如何删除Git子模块?为什么我不能git子模块rm模块名称?
当前回答
自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} "$@"
其他回答
简单的步骤
删除配置项: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子模块吗?的答案?。
在现代git中(我在2022年编写了这篇文章,并更新了git安装),这变得非常简单:
运行git-rm<path to submodule>并提交。
这将删除<path to submodule>处的文件树,以及.gitmodules文件中的子模块条目。即,删除存储库中子模块的所有痕迹。
然而,正如文档所指出的,子模块的.git目录(在主项目.git目录的模块/目录中)被保留了下来,“这样就可以在不需要从另一个存储库获取的情况下签出过去的提交”。如果您仍然想删除此信息,请手动删除.git/modules/中的子模块目录,并删除.git/config文件中的子模板条目
rm-rf.git/modules/<子模块路径>,以及git-config—删除节子模块<子模块路径>。
较旧的社区wiki说明:
通过Git子模块教程页面:
要删除子模块,您需要:
从.gitmodules文件中删除相关部分。暂存.gitmodules更改:git-add.gitmoduls从.git/config中删除相关部分。从工作树中删除子模块文件,并索引:git rm--cached path_to_submodule(无斜杠)。删除子模块的.git目录:rm-rf.git/modules/path_to_submodule提交更改:gitcommit-m“已删除子模块<name>”删除现在未跟踪的子模块文件:rm-rf path_to_submodule
另请参见:以下替代步骤。
git子模块deinit<子模块路径>从.gitmodules中删除节git rm<子模块路径>删除需要从项目中删除的模块文件。将删除的文件添加到git并调用gitadd.gitmodules提交并推送
如果您需要使用bash脚本在一行命令中执行此操作,如下所示:
$cd/path/to/your/rebo&&/bin/bash$HOME/remove_submodule.sh/path/to-the/submodule
在$HOME目录中创建bash脚本文件,名为remove_submodule.sh:
#!/bin/bash
git config -f .gitmodules --remove-section submodule.$1
git config -f .git/config --remove-section submodule.$1
git rm --cached $1
git add .gitmodules
git commit -m "Remove submodule in $1"
rm -rf $1
rm -rf .git/modules/$1
git push origin $(git rev-parse --abbrev-ref HEAD) --force --quiet
我遵循了同一指南的指示如何删除子模块?
$ git submodule deinit -f <submodule-name>
$ rm -rf .git/modules/<submodule-name>
$ git config -f .gitmodules --remove-section submodule.<submodule-name>
$ git config -f .git/config --remove-section submodule.<submodule-name>
$ git rm --cached <submodule-name>
$ git commit -m 'rm submodule: <submodule-name>'
但它一直在说:
fatal: no submodule mapping found in .gitmodules for path
因此,我所做的是像这样在.gitignore中包含路径(路径末尾没有星号):
<path>
然后我修改了任何文件并进行了简单的推送:
$ git add .
$ git commit -m "Ignoring sharedlibs folder <path> on .gitignore"
$ git push -u origin master
推荐文章
- 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中为其他人的代码做出贡献?
- 签出旧的提交并使其成为新的提交