题 如何删除子模块?


如何删除Git子模块?

顺便说一句,有什么理由我不能简单地做

git submodule rm whatever


3024
2017-08-11 14:31


起源


简单的答案 stackoverflow.com/a/21211232/94687 现在是正确的,应该这样标记。现在,它很简单 git rm modulename 和 rm -rf .git/modules/modulename - imz -- Ivan Zakharyaschev
这实际上不是真的。该答案不涉及从中删除子模块条目 .git/config。接受的答案显示了完全删除子模块的最新方法。在这个答案中也更简洁地解释了它: stackoverflow.com/a/36593218/1562138 - fvgs
我发现这篇文章对删除子模块很有帮助。它包含有关删除.gitsubmodules和.git / config文件中的条目的信息 链接 - Ri_
请节省一些时间,直接找到有效的答案(2017年): stackoverflow.com/a/36593218/528313 - Vincenzo Pii
我已经解决了两天的子模块问题。当我发现这个时,取得了突破: 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(查看实际路径在你的服务器上),所有的怪异都消失了十分钟。也可以看看 stackoverflow.com/questions/32833100/... - Elise van Looij


答案:


以来 git1.8.3(2013年4月22日)

一旦你表达了对子模块的兴趣,就没有瓷器方式说“我不再对这个子模块感兴趣”submodule init”。
  “submodule deinit“是这样做的方式。

删除过程也使用 git rm (自2013年10月git1.8.5)。

概要

然后,三步删除过程将是:

0. mv a/submodule a/submodule_tmp

1. git submodule deinit -f -- a/submodule    
2. rm -rf .git/modules/a/submodule
3. git rm -f a/submodule
# Note: a/submodule (no trailing slash)

# or, if you want to leave it in your working tree and have done step 0
3.   git rm --cached a/submodule
3bis mv a/submodule_tmp a/submodule

说明

rm -rf:这是在提到的 丹尼尔施罗德回答,并总结 Eonil 在 评论

这离开了 .git/modules/<path-to-submodule>/ 不变。
  因此,如果您曾使用此方法删除子模块并再次重新添加它们,则无法实现,因为存储库已损坏。


git rm:见 提交95c16418

目前使用“git rm“在子模块上,从超级项目和索引的gitlink中删除子模块的工作树。
  但子模块的部分在 .gitmodules 保持不变,这是现在删除的子模块的剩余部分,可能会激怒用户(而不是设置为 .git/config,这必须保留用户对此子模块表现出兴趣的提示,以便稍后在签出旧提交时重新填充)。

让“git rm“通过不仅从工作树中删除子模块,还通过删除”帮助用户“submodule.<submodule name>“部分来自 .gitmodules 档案和舞台两者。


git submodule deinit:它起源于 这个补丁

随着“git submodule init“用户能够告诉git他们关心一个或多个子模块,并希望在下次调用时填充它”git submodule update”。
  但目前没有简单的方法他们可以告诉git他们不再关心子模块并想要摆脱本地工作树(除非用户对子模块内部有很多了解并删除了“submodule.$name.url“来自 .git/config 与工作树本人一起)。

通过提供'帮助这些用户'deinit'命令。
  这个 删除整个 submodule.<name> 部分来自 .git/config 要么是给定的   子模块(S) (或者对于所有已经初始化的人,如果'.' 给出)。
  如果当前工作树包含修改除非被强制,则失败。
  抱怨在命令行上给出的子模块时,无法找到url设置 .git/config但是,尽管如此,不要失败。

如果(de)初始化步骤(.git/config 和 .git/modules/xxx

从git1.8.5开始 git rm 需要  照顾:

  • add'步骤,记录子模块中的子模块 .gitmodules 文件:需要为您删除。
  • 子模块 特别入场 (如图所示 这个问题):git rm将其从索引中删除:
    git rm --cached path_to_submodule(没有尾随斜线)
    这将使用特殊模式“160000”删除存储在索引中的目录,将其标记为子模块根目录。

如果您忘记了最后一步,并尝试将子模块添加为常规目录,您将收到如下错误消息:

git add mysubmodule/file.txt 
Path 'mysubmodule/file.txt' is in submodule 'mysubmodule'

注意:自Git 2.17(2018年第二季度)以来,git子模块deinit不再是shell脚本。
它是对C函数的调用。

看到 提交2e61273提交1342476 (2018年1月14日)by Prathamesh Chavan(pratham-pc
(合并 Junio C Hamano - gitster  -  在 提交ead8dbe,2018年2月13日) 

git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit \
  ${GIT_QUIET:+--quiet} \
  ${prefix:+--prefix "$prefix"} \
  ${force:+--force} \
  ${deinit_all:+--all} "$@"

1799
2018-04-23 05:57



你能给出一个使用例子吗? submodule deinit? - zakdances
@yourfriendzak这里有一个成功使用它的例子: stackoverflow.com/a/16161950/6309。但请记住,与我原先认为的相反,1.8.3还没有发布!在Unix上,您可以从源代码编译它。 - VonC
@HamishDowner特殊条目应该消失(目录不再是子模块),而且 .gitmodules 应该没问题,但我仍然会仔细检查一下 .git 目录(即 本地 config,在您的本地仓库中:未被a修改 git pull) - VonC
@Jayen是的,如果你承诺删除了 .gitmodules 进入和删除索引中的特殊条目,并推送该回购,其他人可以拉它,该子模块将消失。 - VonC
这是一个自动执行这些步骤的脚本: gist.github.com/sharplet/6289697。把它添加到你的 PATH 和 git remove-submodule path/to/submodule。 - Adam Sharp


通过页面 Git子模块教程

要删除子模块,您需要:

  1. 从中删除相关部分 .gitmodules 文件。
  2. 上演 .gitmodules 变化 git add .gitmodules
  3. 删除相关部分 .git/config
  4. git rm --cached path_to_submodule (没有尾随斜线)。
  5. rm -rf .git/modules/path_to_submodule
  6. 承诺 git commit -m "Removed submodule <name>"
  7. 删除现在未跟踪的子模块文件
    rm -rf path_to_submodule

也可以看看下面的替代步骤


3145
2018-01-18 23:30



“顺便说一下,有什么理由我不能简单地给子模块做任何事情吗?” ? - abernier
@abernier一个简单的回答可能是“因为没有这样的命令存在。”我的猜测是他们试图明确删除子模块文件与子模块配置,以避免意外数据丢失。也许有人会这么认为 git submodule rm 只需删除子模块注册,如果该命令也删除了本地存储库,则会感到惊讶。任何局部变化都将无可挽回地丧失。也许另一个人会认为只会删除文件。 - John Douthat
坦率地说,我不知道为什么。但我希望他们能增加一个命令。这4个步骤太复杂了。 - John Douthat
这是一个删除子模块的bash脚本,只需为submodule-rm创建一个git别名;) gist.github.com/2491147 - Capi Etheriel
还需要rm -rf .git \ modules \ submodule名称? - rogerdpack


只是一个说明。从git 1.8.5.2开始,两个命令将执行:

git rm the_submodule
rm -rf .git/modules/the_submodule

正如@Mark Cheverton的回答正确指出的那样,如果没有使用第二行,即使你现在删除了子模块,剩余的.git / modules / the_submodule文件夹也会阻止将来添加或替换相同的子模块。另外,正如@VonC所提到的, git rm 将完成子模块的大部分工作。

- 更新(07/05/2017) -

只是澄清一下, the_submodule 是项目内子模块的相对路径。例如,它是 subdir/my_submodule 如果子模块在子目录中 subdir

正如评论中所指出的那样 其他答案,这两个命令(虽然在功能上足以删除一个子模块),确实留下了痕迹 [submodule "the_submodule"] 部分 .git/config (截至2017年7月),可以使用第三个命令删除:

git config -f .git/config --remove-section submodule.the_submodule 2> /dev/null

332
2018-04-13 08:51



我在git版本2.4.9(Apple Git-60)上,我所要做的就是rm the_submodule。我推了一下,然后重新添加了一个名为与子模块相同的文件夹,它没有问题。 - David Silva Smith
这不会从中删除子模块条目 .git/config。看到 stackoverflow.com/a/36593218/1562138 用于删除子模块的完整方法。 - fvgs
这是100%绝对辉煌和工作。哇。 - Dan Rosenstark
@drevicko我刚用Git 2.11.1测试了这个,我观察到和以前一样的行为。 git init && git submodule add <repository> && git rm <name> 留下了 .git/config 进入和 .git/modules/<name> 目录及其内容。也许你在删除之前没有初始化子模块? - fvgs
我觉得第一次运行更安全.. git submodule deinit -f the_submodule - danday74


这个问题的大部分答案都是过时的,不完整的或不必要的复杂。

使用git 1.7.8或更新版本克隆的子模块将在您的本地仓库中留下最多四个自身痕迹。删除这四条跟踪的过程由以下三个命令给出:

# Remove the submodule entry from .git/config
git submodule deinit -f path/to/submodule

# Remove the submodule directory from the superproject's .git/modules directory
rm -rf .git/modules/path/to/submodule

# Remove the entry in .gitmodules and remove the submodule directory located at path/to/submodule
git rm -f path/to/submodule

246
2018-03-02 16:07



为什么这个答案有这么少的赞成?所有那些受欢迎的答案都会遗漏一些东西,这是唯一能够以最简单的方式真正消除子模块所有痕迹的答案。请注意:命令的顺序很重要。 - mbdevpl
回答我自己的问题: stackoverflow.com/questions/97875/rm-rf-equivalent-for-windows - Thomas
@mbdevpl在接受答案后3年就出现了,我想没有人能说服OP接受这个 - Andy
@Thomas rm -rf 只是意味着“删除整个文件夹”,以便您可以从Windows中的Explorer GUI执行此操作。或者,如果您在Windows中使用git,那么您也可以使用git bash,因此您可以在那里运行所有这些命令,它们将按原样运行 - Andy Madge
这是2018年的不复杂答案吗? - Warren P


简单的步骤

  1. 删除配置条目:
    git config -f .git/config --remove-section submodule.$submodulename
      git config -f .gitmodules --remove-section submodule.$submodulename
  2. 从索引中删除目录:
    git rm --cached $submodulepath
  3. 承诺
  4. 删除未使用的文件
    rm -rf $submodulepath
    rm -rf .git/modules/$submodulename

请注意:  $submodulepath 不包含前导或尾部斜杠。

背景

当你这样做 git submodule add,它只是添加它 .gitmodules但是 一旦你这样做了 git submodule init,它补充说 .git/config

因此,如果您希望删除模块,但能够快速恢复它, 然后这样做:

git rm --cached $submodulepath
git config -f .git/config --remove-section submodule.$submodulepath

这是一个好主意 git rebase HEAD 第一和 git commit 最后,如果你把它放在一个脚本中。

另外看看 一个答案 我可以在Git子模块中取消填充吗?


185
2017-08-11 14:43



我有很多子模块(和更大的混乱)所以我不得不通过for循环传递它们。由于它们大多数在特定目录下并且ls输出包含尾部斜杠。我做了类似的事情 for dir in directory/*; do git rm --cached $dir; done。 - Pablo Olmos de Aguilera C.
为了得到这个可以在脚本中用于递归删除的列表 - git config -f .git/config -l | cut -d'=' -f1 | grep "submodule.$MODPATH" | sed 's/^submodule\.//' | sed 's/\.url$//'  - 看起来你必须真的这样做以防万一有什么搞砸了,否则就是这样 git submodule | grep -v '^+' | cut -d' ' -f3 - errordeveloper
获取未进行本地更改的模块列表 - git submodule | grep '^+' | cut -d' ' -f2 - errordeveloper
请注意,我必须包括 submodulename 用双引号 "submodulename" ..参考 .git/config 文件 - muon
#2正是我想要的,谢谢! +1 - AyexeM


除了建议,我也不得不这样做 rm -Rf .git/modules/path/to/submodule 能够添加一个具有相同名称的新子模块(在我的情况下,我用原来的替换叉子)


80
2017-10-12 10:17



我也遇到了麻烦。如果您尝试将子模块重新安装到同一路径,它会将分支信息缓存在您提到的位置,这会使事情变得混乱。 - jangosteve
谢谢,我也需要这个。 @Anton,我同意,并且我编辑了topvoted答案来添加此信息。 - William Denniss
我使用--name选项来进行替换工作......请参阅 stackoverflow.com/questions/14404704/... - joseph.hainline


您必须删除该条目 .gitmodules 和 .git/config,并从历史记录中删除模块的目录:

git rm --cached path/to/submodule

如果你在git的邮件列表上写,可能有人会为你做一个shell脚本。


46
2017-11-01 21:43



不需要任何shell脚本,其他答案有删除子模块的所有痕迹的命令: stackoverflow.com/a/36593218/4973698 - mbdevpl


要删除使用以下内容添加的子模块:

git submodule add blah@blah.com:repos/blah.git lib/blah

跑:

git rm lib/blah

而已。

对于旧版本的git(大约~1.8.5),请使用:

git submodule deinit lib/blah
git rm lib/blah
git config -f .gitmodules --remove-section submodule.lib/blah

45
2017-07-09 17:55



确实+1。这是git 1.8.3以后唯一正确的答案。应该被接受为正确的。 - Xananax
+1在较新版本的git中删除正确且干净的方法。 - Xiv
git rm 仍然留下的东西 .git/modules/。 (2.5.4) - Rudolf Adamkovič
@RudolfAdamkovic它对我有用吗?请注意,如果确切的路径匹配,它只会删除子模块条目;如果您移动了子模块然后使用 git rm 它没有;我的mac上的2.5.4快速测试更新了.gitmodules文件,如下面的文档中所述: git-scm.com/docs/git-rm#_submodules ...但是如果你发现某种平台/版本的组合没有发生这种情况,你应该提出一个关于它的错误。 - Doug
这个答案并不完全正确。 git rm 留下的东西 .git/modules/ 迪尔和 .git/config 文件(ubuntu,git 2.7.4)。其他答案100%有效: stackoverflow.com/a/36593218/4973698 - mbdevpl