如何移除一个子模块?

4473

如何删除Git子模块?为什么不能直接使用git submodule rm module_name命令?


15
那其实不是真的。那个回答没有解决从.git/config中删除子模块条目的问题。被采纳的回答展示了完全移除子模块的最新方法。这个回答也在这里更简洁地解释了:https://dev59.com/QHM_5IYBdhLWcg3wt1k0#36593218 - fvgs
我发现这篇文章在删除子模块方面非常有帮助。它包括有关删除 .gitsubmodules 和 .git/config 文件中条目的信息 链接 - Ri_
22
请直接前往适用于2017年的答案,以节省您的时间:https://dev59.com/QHM_5IYBdhLWcg3wt1k0#36593218。 - Vincenzo Pii
我为子模块问题苦斗了两天。突破口在于我找到了这个链接:https://forums.developer.apple.com/thread/13102。基本上,Xcode和其他应用程序很难扩展包含“~”的URL。一旦我将ssh://username@server.remoteHost.com/~/git/MyRepo.git更改为ssh://username@server.remoteHost.com/home/username/git/MyRepo.git(查找您服务器上的实际路径),所有奇怪的问题都在十分钟内消失了。另请参见https://dev59.com/2o_ea4cB1Zd3GeqPQJJZ#33985629。 - Elise van Looij
38个回答

11

这是我发现的必要或有用的4个步骤(首要重要的步骤):

git rm -f the_submodule
rm -rf .git/modules/the_submodule
git config -f .git/config --remove-section submodule.the_submodule
git commit -m "..."

理论上,在 第一步 中使用 git rm 应该就可以完成。希望有一天能够用一个命令回答 OP 的第二个问题。

但是截至 2017 年 7 月,需要进行 第二步 来删除 .git/modules/ 中的数据,否则将来就不能再添加子模块了。

tinlyx 的答案 所述,在 git 1.8.5+ 版本中,以上两个步骤应该都可以完成,因为所有的 git submodule 命令似乎都有效。

第三步删除文件 .git/config 中的 the_submodule 部分。这样做是为了完整性。 (该条目可能会对旧版本的 git 造成问题,但我没有旧版本可供测试)。

大多数答案建议使用 git submodule deinit。我认为使用 git config -f .git/config --remove-section 更加明确易懂。根据 git-submodule 文档git deinit

取消注册给定的子模块...如果您真的想从存储库中删除一个子模块并提交,请使用 git-rm[1]代替

最后,如果不 git commit,在进行 git submodule summary (在 git 2.7 中)时可能会出现错误。

fatal: Not a git repository: 'the_submodule/.git'
* the_submodule 73f0d1d...0000000:
无论是你完成步骤2还是步骤3都一样。

11

使用 git v2.7.4,简单的三个步骤完全有效。

git submodule deinit -f -- a/submodule    
git rm -f a/submodule
git commit

11

从git中删除submodule的最佳方法:

$ git submodule deinit -f <submodule-name>
$ rm -rf .git/modules/<submodule-name>
$ git config -f .gitmodules --remove-section submodule.<submodule-name>
$ git config -f .git/config --remove-section submodule.<submodule-name>
$ git rm --cached <submodule-name>
$ git commit -m 'rm submodule: <submodule-name>'

问题:这不是缺少了 git add .gitmodules 吗? - SRG
是的,你可以添加这个:git add .gitmodules - Ashish Sondagar

9

我按照这篇指南如何删除子模块?的步骤进行操作。

$ git submodule deinit -f <submodule-name>
$ rm -rf .git/modules/<submodule-name>
$ git config -f .gitmodules --remove-section submodule.<submodule-name>
$ git config -f .git/config --remove-section submodule.<submodule-name>
$ git rm --cached <submodule-name>
$ git commit -m 'rm submodule: <submodule-name>'

但它一直提示:

fatal: no submodule mapping found in .gitmodules for path

所以我的做法是在.gitignore文件中加入路径,就像这样(路径末尾不带星号):
<path>

然后我修改了任何文件并进行了一次简单的推送(simple push)

$ git add .
$ git commit -m "Ignoring sharedlibs folder <path> on .gitignore"
$ git push -u origin master

9
我刚刚发现了一个名为“.submodule”的隐藏文件,里面有一个列表...你可以通过这种方式逐个删除它们。我只有一个,所以我把它删除了。虽然简单,但可能会引起Git的混乱,因为我不知道是否有什么东西与子模块相关联。到目前为止似乎还好,除了libetpan的常规升级问题,但那可能是无关的。
注意到没有人发布手动删除的方法,因此添加了。

这是.gitmodules文件。 - Arialdo Martini

8

从 git 2.17 版本开始,只需要执行以下命令:

git submodule deinit -f {module_name}
git add {module_name}
git commit

无法工作,无论是 git 2.17.1 还是 git 2.20.1。但是使用 git rm 而不是 git add 对两者都有效。注意:如果一切干净,则不需要使用 -f。确保从不使用选项来保护免受意外数据丢失。还要注意,这会保留 .git/modules/{module_name}。最佳实践是将其保留在那里,因为 git 将打印正确的(!)帮助以解决由于此原因而被阻止的问题。 - Tino

7
project dir:     ~/foo_project/
submodule:       ~/foo_project/lib/asubmodule
- - - - - - - - - - - - - - - - - - - - - - - - -
run:
  1.   cd ~/foo_project
  2.   git rm lib/asubmodule && 
          rm .git/modules/lib/asubmodule && 
            git submodule lib/asubmodule deinit --recursive --force

5

如果您刚刚添加了子模块,例如您添加了错误的子模块或将其添加到了错误的位置,请执行git stash,然后删除该文件夹。假设添加子模块是您在最近的仓库中唯一进行的操作。


5
这对我有用。上面的答案在终端中显示,除此之外没有发生任何事情。
'fatal: not removing 'demolibapp' recursively without -r'
  1. demolibapp 是我想要删除的子模块名称
  2. git submodule deinit demolibapp
  3. git rm --cached demolibapp -r
  4. rm -rf .git/modules/demolibapp
  5. git add --all
  6. git commit -m "移除多余的子模块"
  7. git push
  8. rm -rf demolibapp

5
总结一下,这是你应该做的:

设置 path_to_submodule 变量(无尾斜线):

path_to_submodule=path/to/submodule

从.gitmodules文件中删除相关行:
git config -f .gitmodules --remove-section submodule.$path_to_submodule

从.git/config中删除相关部分

git config -f .git/config --remove-section submodule.$path_to_submodule

仅从索引中取消暂存并删除 $path_to_submodule 子模块(以防丢失信息)

git rm --cached $path_to_submodule

跟踪对 .gitmodules 的更改
git add .gitmodules

提交超级项目。
git commit -m "Remove submodule submodule_name"

删除当前未跟踪的子模块文件。
rm -rf $path_to_submodule

rm -rf .git/modules/$path_to_submodule

参见: 备选指南

请问您能否扩展一下如何在没有提交的情况下删除 'git submodule add' 后的子模块?我假设在这种情况下不需要进行提交来删除子模块,对吗? - Carlo Wood
2
我认为你需要交换 git rm --cached $path_to_submodulegit add .gitmodules 的顺序,不是吗?在第一个命令上我遇到了一个错误:fatal: Please stage your changes to .gitmodules or stash them to proceed,因为我有未暂存的更改 .gitmodules。先执行 git add .gitmodules 可以解决这个问题。 - Carlo Wood

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接