如何删除Git子模块?为什么我不能git子模块rm模块名称?
当前回答
在这个网站上尝试了所有不同的答案后,我最终得到了这个解决方案:
#!/bin/sh
path="$1"
if [ ! -f "$path/.git" ]; then
echo "$path is no valid git submodule"
exit 1
fi
git submodule deinit -f $path &&
git rm --cached $path &&
rm -rf .git/modules/$path &&
rm -rf $path &&
git reset HEAD .gitmodules &&
git config -f .gitmodules --remove-section submodule.$path
这将恢复与添加子模块之前完全相同的状态。您可以立即再次添加子模块,这在大多数答案中是不可能的。
git submodule add $giturl test
aboveScript test
这将使您得到一个干净的签出,无需提交任何更改。
这是用以下方法测试的:
$ git --version
git version 1.9.3 (Apple Git-50)
其他回答
总而言之,这是您应该做的:
设置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
简单的步骤
删除配置项:git-config-f.git/config--删除节子模块$submodulename git-config-f.gitmodules—删除部分子模块$子模块名称从索引中删除目录:git rm--cached$submodule路径犯罪删除未使用的文件:rm-rf$submodulepathrm-rf.git/modules/$submodulename
请注意:$submodulepath不包含前导或尾随斜杠。
出身背景
当您执行git子模块add时,它只将其添加到.gitmodules中,但是完成git子模块init后,它将添加到.git/config中。
因此,如果您希望删除模块,但能够快速恢复,那么就这样做:
git rm --cached $submodulepath
git config -f .git/config --remove-section submodule.$submodulepath
首先执行git rebase HEAD和git commit是一个好主意最后,如果你把这个写在脚本中。
还可以看看我可以取消填充Git子模块吗?的答案?。
使用Magit的简单解决方案
如果您在Emacs下使用Magit,则可以执行以下操作:
转到项目根目录,然后
M-x,magit列表子模块
then
M-x,删除magit子模块
系统将询问您要删除哪个子模块。
就是这样!
(我的Magit版本是v3.3.0)
我创建了一个bash脚本来简化删除过程。它还检查回购中是否有未保存的更改,并请求确认。它已经在os x上进行了测试,如果知道它在普通linux发行版上是否也能正常工作,将会很有趣:
https://gist.github.com/fabifrank/cdc7e67fd194333760b060835ac0172f
自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} "$@"
推荐文章
- Visual Studio Code无法检测已安装的Git
- 强制LF eol在git的回购和工作副本
- Git:在裸库中更改活动分支的正确方法?
- 删除git中的分支是否会将其从历史记录中删除?
- 防止在GitHub上推送到master ?
- 根据Git,谁是“我们”,谁是“他们”?
- git如何合并后樱桃采摘工作?
- Git搜索单个文件历史记录中的字符串
- Git命令显示所有(轻量级)标签创建日期
- Gitignore并没有忽视文件夹
- 什么时候用。git/info/exclude代替。gitignore来排除文件?
- 如何告诉git忽略个别行,即gitignore为特定行代码
- “git diff——耐心”是什么意思?
- 我如何在GitHub中为其他人的代码做出贡献?
- 签出旧的提交并使其成为新的提交