如何从git提交中删除子模块文件
一旦使用 "
git submodule init
" 表达了您对子模块的兴趣,就没有 Porcelain 的方法来表达 "我不再对这个子模块感兴趣"。
"git submodule deinit
" 就是这么做的方法。
删除过程也使用了 git rm
(自 git1.8.5 于 2013 年 10 月发布)。
摘要
3 步移除过程如下:
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的答案中提到,并由Eonil在评论中进行了总结:
这不会改变
.git/modules/
的状态。/
因此,如果您使用此方法删除了一个子模块并重新添加,它将不可能,因为存储库已经被破坏了。
git rm
:参见提交 95c16418:
当前,在子模块上使用 "
git rm
" 将从超级项目中删除子模块的工作树和索引中的 gitlink。
但子模块在.gitmodules
中的部分将保持不变,这是已删除的子模块的剩余部分,可能会使用户感到困惑(与.git/config
中的设置相反,这必须保持为一个提醒,即用户对该子模块表现出了兴趣,因此当检出旧版本时将重新填充)。
让 "
git rm
" 帮助用户,不仅从工作树中删除子模块,还从.gitmodules
文件中删除 "submodule.
" 部分,并将两者都暂存。
git submodule deinit
:源自此补丁:
使用 "
git submodule init
",用户可以告诉 git 他们关心一个或多个子模块,并希望在下一次调用 "git submodule update
" 时进行填充。
但目前,除非用户了解子模块的内部工作原理并自己从.git/config
中删除 "submodule.$name.url
" 设置和工作树,否则他们无法轻松地告诉 git 他们不再关心子模块并希望摆脱该子模块。
提供一个'deinit
'命令以帮助那些用户。这将从.git/config
中删除给定子模块(或所有已初始化的子模块,如果给出了'.
')的整个submodule.
部分。除非强行进行,否则当前的工作树包含修改时将失败。如果命令行上给定的子模块的url设置在.git/config
中找不到,就会抱怨,但并不会失败。 这样就可以处理(de)初始化步骤(.git/config
和.git/modules/xxx
)。自从git1.8.5以来,git rm
还负责以下步骤:将子模块的url记录在.gitmodules
文件中的'add
'步骤:需要为您删除。该子模块特殊条目(如此问题所示):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 submodule deinit不再是一个shell脚本,而是一个C函数调用。请参见Prathamesh Chavan(pratham-pc
)于2018年1月14日提交的2e61273和1342476(合并自由C Hamano--gitster
)于2018年2月13日提交的ead8dbe。
git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit \ ${GIT_QUIET:+--quiet} \ ${prefix:+--prefix "$prefix"} \ ${force:+--force} \ ${deinit_all:+--all} "$@"
在现代的Git中(本文是在2022年编写的,并使用更新的git
安装程序),这变得更加简单:
- 运行
git rm
,并提交。
这将删除
位置的文件树,以及子模块在.gitmodules
文件中的条目。也就是说,您的存储库中子模块的所有痕迹都将被删除。
如文档所述,子模块的.git
目录仍将保留(位于主项目的.git
目录的modules/
目录中),以使检出过去的提交成为可能,而不需要从另一个存储库获取。
如果您仍然希望删除此信息,请手动删除.git/modules/
中子模块的目录,并从文件.git/config
中删除子模块的条目。这些步骤可以使用以下命令自动执行:
rm -rf .git/modules/
,以及git config --remove-section submodule.
。
旧版社区Wiki说明:
通过此页面Git子模块教程:
要删除子模块,您需要执行以下操作:
- 从
.gitmodules
文件中删除相关部分。 - 将
.gitmodules
更改暂存:git add .gitmodules
- 从
.git/config
中删除相关部分。 - 从工作树和索引中删除子模块文件:
git rm --cached path_to_submodule
(没有尾随斜杠)。 - 删除子模块的
.git
目录:rm -rf .git/modules/path_to_submodule
- 提交更改:
git commit -m "Removed submodule
" - 删除现在未跟踪的子模块文件:
rm -rf path_to_submodule
另请参阅: 下面的替代步骤。