如何删除Git子模块?为什么我不能git子模块rm模块名称?


当前回答

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

git rm --cached path/to/submodule

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

其他回答

我不得不进一步执行John Douth的步骤,并将其cd到子模块的目录中,然后删除Git存储库:

cd submodule
rm -fr .git

然后,我可以将文件作为父Git存储库的一部分提交,而无需对子模块的旧引用。

如果你想删除子模块而不从本地文件系统中删除文件夹,我可以这样做:

MOD=example
git rm --cached -f apps/$MOD
git config -f .gitmodules --remove-section submodule.$MOD

总而言之,这是您应该做的:

设置path_to_submodule变量(无尾随斜杠):path_to_submodule=路径/到/子模块从.gitmodules文件中删除相关行:git-config-f.gitmodules—删除节子模块$路径_子模块从.git/config中删除相关部分git-config-f.git/config—删除节子模块$路径_子模块仅从索引中取消存储并删除$path_to_submodule(以防止丢失信息)git rm--缓存的$path_to_submodule跟踪对.gitmodules所做的更改git-add.gitmodules提交超级项目gitcommit-m“删除子模块子模块名”删除现在未跟踪的子模块文件rm-rf$path_to_submodulerm-rf.git/modules/$path_to_submodule

我发现deinit对我很好:

git submodule deinit <submodule-name>    
git rm <submodule-name>

从git文档:

解交织注销给定子模块,即删除整个子模块$名称git/config中的部分及其工作树。

自git1.8.3(2013年4月22日)起:

一旦你用“gitsubmoduleInit”表达了对某个子模块的兴趣,就没有瓷的方式来表示“我不再对这个子模块感兴趣了”。“git submodule deinit”是这样做的方法。

删除过程还使用gitrm(自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/<子模块路径>/保持不变。所以,若您使用此方法删除了一个子模块并再次添加它们,那个么就不可能了,因为存储库已经损坏。


git rm:请参阅提交95c16418:

当前在子模块上使用“gitrm”会将子模块的工作树从超级项目的工作树中删除,并将gitlink从索引中删除。但是.gitmodules中的子模块部分保持不变,这是现在删除的子模块的剩余部分,可能会激怒用户(与.git/config中的设置相反,这必须保持提醒用户对该子模块感兴趣,以便稍后在签出旧的提交时重新填充)。

让“gitrm”不仅从工作树中删除子模块,还可以从.gitmodules文件中删除“submodule.<submodulename>”部分,并将两者都暂存,从而帮助用户。


git子模块deinit:它源于这个补丁:

使用“gitsubmodule init”,用户可以告诉git他们关心一个或多个子模块,并希望在下次调用“gitsubmodule update”时填充它。但目前,他们无法简单地告诉git他们不再关心子模块,并希望摆脱本地工作树(除非用户非常了解子模块的内部结构,并将“submodule.$name.url”设置与工作树一起从.git/config中删除)。

通过提供“deinit”命令帮助这些用户。这将删除整个子模块<对于给定的子模块(或所有已初始化的子模块,如果给定“.”)。如果当前工作树包含修改,则失败,除非强制。如果在命令行上给定的子模块的url设置在.git/config中找不到,但仍然不会失败,请进行投诉。

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

从git1.8.5开始,gitrm还负责:

在.gitmodules文件中记录子模块url的“add”步骤:需要为您删除它。子模块特殊条目(如这个问题所示):gitrm将其从索引中删除:git rm—缓存的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函数的调用。

见Prathamesh Chavan(pratham pc)的承诺2e61273、承诺1342476(2018年1月14日)。(于2018年2月13日由Junio C Hamano--gitster--在commit ead8dbe中合并)

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