如何删除Git子模块?为什么不能直接使用git submodule rm module_name
命令?
如何删除Git子模块?为什么不能直接使用git submodule rm module_name
命令?
在现代的 git 中(本文是在2022年编写,使用更新的 git
版本),这变得更加简单:
git rm <path-to-submodule>
并提交。这将删除 <path-to-submodule>
下的文件树以及子模块在 .gitmodules
文件中的条目。也就是说,你的代码库中所有与子模块相关的痕迹都会被删除。
然而,正如文档中所述,子模块的 .git
目录仍然会被保留(在主项目的 .git
目录下的 modules/
目录中),以便可以在不需要从其他代码库中获取历史提交记录时回滚到过去的版本。
如果你仍想移除这些信息,则需手动删除 .git/modules/
目录下的子模块目录,并在文件 .git/config
中删除子模块的条目。这些步骤可以通过以下命令自动化完成:
rm -rf .git/modules/<path-to-submodule>
git config --remove-section submodule.<path-to-submodule>
旧版社区维基教程:
通过页面 Git 子模块教程 中的说明:
要删除子模块,需要执行以下步骤:
.gitmodules
文件中删除相应的条目。git add .gitmodules
.git/config
文件中删除相关部分。git rm --cached 子模块路径(不要加尾部斜杠)
。.git
目录:rm -rf .git/modules/子模块路径
git commit -m“移除子模块 <name>”
rm -rf 子模块路径
另请参阅: 下面的替代步骤。
git submodule rm
只是删除子模块注册,并会惊讶于该命令还会删除本地存储库。任何本地更改都将无法恢复。另一个人可能认为只有文件被删除。 - John Douthat之前,没有一种简单的方法来表达“我不再对这个子模块感兴趣”,一旦你通过 "
git submodule init
" 表示了你的兴趣。
"git submodule deinit
" 就是这样的方式。
删除过程还使用了 git rm
(自 git1.8.5 于2013年10月起)。
因此,三步删除过程如下:
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
:这在Daniel Schroeder的answer中提到,并由Eonil在the comments中总结:
这不会更改
.git/modules/<path-to-submodule>/
。因此,如果您使用此方法删除子模块并再次添加它们,则将无法进行操作,因为存储库已经被损坏。
git rm
:请参阅commit 95c16418:
目前在子模块上使用 "
git rm
" 命令会将子模块的工作树从超级项目中移除,并从索引中移除 gitlink。
但是,.gitmodules
文件中子模块的部分不会被修改,这是已删除子模块的残留物,可能会让用户感到困惑(与.git/config
中的设置相反,这必须保留作为提醒,表明用户对此子模块有兴趣,因此当检出旧提交时,它将重新填充)。
让 "
git rm
" 帮助用户,不仅从工作树中删除子模块,还从.gitmodules
文件中删除 "submodule.<submodule name>
" 部分,并将其暂存。
git submodule deinit
: 它源于 此补丁:
帮助那些用户提供一个“使用 "
git submodule init
",用户可以告诉 Git 他们关心一个或多个子模块,并希望在下一次调用 "git submodule update
" 时填充它。
但是目前没有简单的方法可以告诉 Git 不再关心子模块,并希望摆脱本地工作树(除非用户对子模块内部有很多了解,并从.git/config
中删除 "submodule.$name.url
" 设置以及工作树)。
deinit
”命令。这将从.git/config
中删除整个submodule.<name>
部分,无论是针对给定的子模块(如果给出“.
”则为所有已初始化的子模块),还是对于所有已初始化的子模块。除非强制执行,否则在当前工作树包含修改时会失败。当命令行上给定的子模块的url设置在.git/config
中找不到时,会发出警告,但仍不会失败。
这将处理(取消)初始化步骤(.git/config
和.git/modules/xxx
)
自git1.8.5以来,git rm
也会处理:
add
' 步骤会在 .gitmodules
文件中记录子模块的url: 需要将其删除。git rm --cached path_to_submodule
(没有斜杠)如果你忘记了最后一步,试图将一个子模块添加为常规目录,你将会得到以下错误信息:
git add mysubmodule/file.txt
Path 'mysubmodule/file.txt' is in submodule 'mysubmodule'
pratham-pc
)。(由Junio C Hamano -- gitster
--于commit ead8dbe中合并,2018年2月13日)
git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit \
${GIT_QUIET:+--quiet} \
${prefix:+--prefix "$prefix"} \
${force:+--force} \
${deinit_all:+--all} "$@"
submodule deinit
的例子吗? - zakdances.gitmodules
应该没问题,但我仍然建议双重检查 .git
目录中的任何内容(即本地存储库中的 本地 配置:这不会被 git pull
修改)。 - VonC.gitmodules
条目和索引中特殊条目的操作,并推送该仓库,其他人就可以拉取它并且子模块将被删除。 - VonC这个问题的大多数答案已经过时、不完整或者过于复杂。
使用 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
.git/modules
文件夹中删除。像被接受的答案那样在第一行加上“--”似乎可以解决这个问题。 - Fmstrat仅作说明。自git 1.8.5.2以来,只需两个命令即可:
git rm -r the_submodule
rm -rf .git/modules/the_submodule
正如@Mark Cheverton的回答所指出的那样,如果不使用第二行,即使现在删除了子模块,剩余的.git/modules/the_submodule文件夹也会阻止将来添加或替换相同的子模块。此外,正如@VonC所提到的,git rm
命令将处理子模块上的大部分工作。
--更新(07/05/2017)--
只是为了澄清,the_submodule
是项目内子模块的相对路径。例如,如果子模块位于子目录subdir
中,则为subdir/my_submodule
。
正如评论和其他答案所指出的那样,这两个命令(虽然在功能上足以删除子模块),但确实会在.git/config
文件的[submodule "the_submodule"]
部分留下痕迹(截至2017年7月),可以使用第三个命令删除:
git config -f .git/config --remove-section submodule.the_submodule 2> /dev/null
.git/config
中移除子模块条目。请访问https://dev59.com/QHM_5IYBdhLWcg3wt1k0#36593218获取完整的移除子模块方式。 - fvgsgit init && git submodule add <repository> && git rm <name>
会留下.git/config
条目和.git/modules/<name>
目录及其内容。也许您在删除之前没有初始化子模块? - fvgs取消链接文件 '...' 失败
。 - Adam Burley简单步骤
git config -f .git/config --remove-section submodule.$submodulename
git config -f .gitmodules --remove-section submodule.$submodulename
git rm --cached $submodulepath
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 子模块的关联。
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
。 - errordevelopergit submodule | grep '^+' | cut -d' ' -f2
。 - errordeveloper要删除使用以下命令添加的子模块:
REPOSITORY=blah@blah.com:repos/blah.git
MOD_DIR=lib/blah
git submodule add $REPOSITORY $MOD_DIR
运行:
git rm $MOD_DIR
就是这样。
对于旧版本的git(大约在1.8.5左右,实际上甚至在2.26.2中),请使用:
git submodule deinit $MOD_DIR
git rm $MOD_DIR
git config -f .gitmodules --remove-section submodule.$MOD_DIR
git rm
命令仍会在 .git/modules/
目录下留下一些东西。(2.5.4) - Rudolf Adamkovičgit rm
,它不会生效。在我的 Mac 上进行了快速测试,使用 2.5.4 版本更新了 .gitmodules 文件,如此文档所述:https://git-scm.com/docs/git-rm#_submodules ... 但是,如果您发现某种平台/版本组合没有发生这种情况,您应该提交一个错误报告。 - Douggit rm
命令会在.git/modules/
目录和 .git/config
文件中留下一些内容(在 Ubuntu 系统,git 版本是 2.7.4)。另一个回答是100%正确的:https://dev59.com/QHM_5IYBdhLWcg3wt1k0#36593218 - mbdevpl除了这些建议,我还需要执行rm -Rf .git/modules/path/to/submodule
命令,以便能够添加一个同名的新子模块(在我的情况下,我正在用原始版本替换一个分支)。
.gitmodules
和.git/config
中删除条目,并从历史记录中删除该模块的目录。git rm --cached path/to/submodule
如果你在Git的邮件列表上发帖,可能会有人为你编写一个Shell脚本。我发现deinit
对我很有效:
git submodule deinit <submodule-name>
git rm <submodule-name>
来自Git文档:
deinit
取消注册给定的子模块,即从.git/config文件中删除整个
submodule.$name
部分以及它们的工作树。
git
最安全的答案,因为另一个答案会过早地删除 .git/modules/submodule
目录,这似乎会导致较新的 git
时不时失败。此外(请参见我的评论),删除 .git/modules/submodule
可能是错误的路径,因此这是一步危险的操作,最好只在 git
抱怨时(或者您确信这是您想要的、正确的路径并且真正需要时)才执行。 - Tinogit commit
命令来提交工作目录中暂存的更改: modified .gitmodules
和 deleted <submodule-path>
。 - Yuri Pozniak您可以使用别名来自动化其他人提供的解决方案:
[alias]
rms = "!f(){ git rm --cached \"$1\";rm -r \"$1\";git config -f .gitmodules --remove-section \"submodule.$1\";git config -f .git/config --remove-section \"submodule.$1\";git add .gitmodules; }; f"
将其添加到你的git配置中,然后你可以执行:git rms path/to/submodule
git clone https://github.com/hilbix/empty.git; cd empty; git submodule add https://github.com/hilbix/empty.git one; git mv one two; git rms two
。
其次:您必须从正确的路径执行此操作。git
别名应该在工作树中的任何位置都可以工作(或者优雅地失败)。
第三:git config -f .git/config
在子模块中会失败,因为.git
通常是一个文件。 - Tino
.git/config
中删除子模块条目的问题。被采纳的回答展示了完全移除子模块的最新方法。这个回答也在这里更简洁地解释了:https://dev59.com/QHM_5IYBdhLWcg3wt1k0#36593218 - fvgs