我如何删除子模块?
我如何删除Git子模块?
顺便说一下,有没有我不能简单的理由
git submodule rm whatever
?
由于git1.8.3(2013年4月22日) :
一旦您expression了对“
submodule init
”子模块的兴趣,就没有瓷器方式说“我不再对这个子模块感兴趣”。
“submodule deinit
”就是这样做的方法。
删除过程也使用git rm
(自2013年10月git1.8.5以来)。
概要
然后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 -fa/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/<path-to-submodule>/
不变。
所以如果你用这个方法删除了一个子模块并重新添加它们,这是不可能的,因为版本库已经被破坏了。
git rm
:见提交95c16418 :
目前,在子模块上使用“
git rm
”会从超级项目中删除子模块的工作树,并从索引中删除该子模块的工作树。
但是.gitmodules
模块的部分保持不变,这是现在移除的子模块的剩余部分,可能会刺激用户(与.git/config
的设置相反,这必须留在用户对该子模块感兴趣的提示所以稍后当一个较旧的提交被签出时会被重新填充)。让“
git rm
”帮助用户,不仅从工作树中删除子模块,而且还从.gitmodules
文件中删除“submodule.<submodule name>
”部分,
git submodule deinit
:它源于这个补丁 :
使用“
git submodule init
”,用户可以告诉git他们关心一个或多个子模块,并希望在下次调用“git submodule update
”时填充它。
但是目前没有简单的方法,他们可以告诉git他们不再关心子模块,并且想要摆脱本地工作树(除非用户知道很多关于子模块内部的知识,并删除“submodule.$name.url
”从.git/config
和工作树一起设置)。通过提供“
deinit
”命令来帮助这些用户。
这将从给定的子模块 (或所有那些在给出“.
”的情况下被初始化的子模块)从.git/config
删除整个submodule.<name>
部分 。
如果当前工作树包含修改,除非强制,否则失败。
当在命令行给出的子模块时,抱怨在.git/config
找不到url设置,但是不会失败。
如果(de)初始化步骤( .git/config
和.git/modules/xxx
)
由于git1.8.5, git rm
也照顾到:
- '
add
'在.gitmodules
文件中logging一个子模块的url:这个步骤需要移除。 - 子模块特殊条目 ( 如此问题所示 ):git rm将其从索引中删除:
git rm --cached path_to_submodule
(无尾随斜线)
这将使用特殊模式“160000”删除索引中存储的目录,将其标记为子模块根目录。
如果您忘记了最后一步,并尝试将子模块添加为常规目录,则会收到如下错误消息:
git add mysubmodule/file.txt Path 'mysubmodule/file.txt' is in submodule 'mysubmodule'
通过页面Git Submodule教程 :
要删除子模块,您需要:
- 从
.gitmodules
文件中删除相关的部分。 - stage
.gitmodules
改变git add .gitmodules
- 从
.git/config
删除相关部分。 - 运行
git rm --cached path_to_submodule
(没有结尾的斜杠)。 - 运行
rm -rf .git/modules/path_to_submodule
- 提交
git commit -m "Removed submodule <name>"
- 删除现在未跟踪的子模块文件
rm -rf path_to_submodule
只是一个说明。 既然git 1.8.5.2,两个命令会做:
git rm the_submodule rm -rf .git/modules/the_submodule
正如@Mark Cheverton的回答正确指出的那样,如果第二行没有被使用,即使你现在已经移除了子模块,剩余的.git / modules / the_submodule文件夹将会阻止相同的子模块在未来被添加回或replace。 另外,正如@VonC所提到的, git rm
将完成子模块的大部分工作。
– 更新(07/05/2017) –
为了澄清,子模块是项目内子模块的相对path。 例如,如果子模块位于子目录subdir
内, subdir/my_submodule
。
正如在注释和其他答案中所指出的那样,这两个命令(尽pipe在function上足以去除一个子模块),在.git/config
[submodule "the_submodule"]
部分留下一个痕迹(截至2017年7月)可以使用第三个命令删除:
git config -f .git/config --remove-section submodule.the_submodule 2> /dev/null
简单的步骤
- 删除configuration项:
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
它添加到.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 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
除了这些build议之外,我还必须使用rm -Rf .git/modules/path/to/submodule
来添加一个具有相同名称的新子模块(在我的情况下,我正在用原来的replace叉子)
您必须删除.gitmodules
和.git/config
中的条目,并从历史logging中删除该模块的目录:
git rm --cached path/to/submodule
如果你写在git的邮件列表上,可能有人会为你做一个shell脚本。
要删除使用以下内容添加的子模块:
git submodule add blah@blah.com:repos/blah.git lib/blah
跑:
git rm lib/blah
而已。
对于旧版本的git(约1.8.5),请使用:
git submodule deinit lib/blah git rm lib/blah git config -f .gitmodules --remove-section submodule.lib/blah
您可以使用别名来自动化其他人提供的解决scheme:
[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"
把它放在你的gitconfiguration中,然后你可以这样做: git rms path/to/submodule
总之,这是你应该做的:
-
设置
path_to_submodule
var(无尾随斜线):path_to_submodule=path/to/submodule
-
从.gitmodules文件中删除相关行:
git config -f .gitmodules --remove-section submodule.$path_to_submodule
-
从.git / config中删除相关部分
git config -f .git/config --remove-section submodule.$path_to_submodule
-
仅从索引中卸载并删除$ path_to_submodule(以防止丢失信息)
git rm --cached $path_to_submodule
-
跟踪对.gitmodules所做的更改
git add .gitmodules
-
提交超级项目
git commit -m "Remove submodule submodule_name"
-
删除现在未跟踪的子模块文件
rm -rf $path_to_submodule
rm -rf .git/modules/$path_to_submodule
如果由于添加,提交和推送已经是Git存储库(包含.git
)的文件夹而意外添加了子模块,则不会有.gitmodules
文件进行编辑,或者.git/config
任何文件。 在这种情况下,所有你需要的是:
git rm --cached subfolder git add subfolder git commit -m "Enter message here" git push
FWIW ,我也删除.git
文件夹之前做的git add
。
在对本网站所有不同的答案进行试验之后,我最终得到了这个解决scheme:
#!/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
这使您无需执行任何更改即可完成签出。
这已经过testing:
$ git --version git version 1.9.3 (Apple Git-50)
我目前在做什么2012年12月(结合了大部分的答案):
oldPath="vendor/example" git config -f .git/config --remove-section "submodule.${oldPath}" git config -f .gitmodules --remove-section "submodule.${oldPath}" git rm --cached "${oldPath}" rm -rf "${oldPath}" ## remove src (optional) rm -rf ".git/modules/${oldPath}" ## cleanup gitdir (optional housekeeping) git add .gitmodules git commit -m "Removed ${oldPath}"
这是我做的:
1.)从.gitmodules文件中删除相关的部分。 你可以使用下面的命令:
git config -f .gitmodules --remove-section "submodule.submodule_name"
2.)阶段的.gitmodules
更改
git add .gitmodules
3.)从.git/config
删除相关部分。 你可以使用下面的命令:
git submodule deinit -f "submodule_name"
4.)删除gitlink(无尾随斜线):
git rm --cached path_to_submodule
5.)清理.git/modules
:
rm -rf .git/modules/path_to_submodule
)承诺:
git commit -m "Removed submodule <name>"
7.)删除现在未跟踪的子模块文件
rm -rf path_to_submodule
我不得不把John Douthat的步骤更进一步,并进入子模块的目录,然后删除Git仓库:
cd submodule rm -fr .git
然后,我可以将这些文件作为父Git存储库的一部分提交,而不需要对子模块进行旧的引用。
我最近发现了一个包含许多有用的git相关命令的git项目: https : //github.com/visionmedia/git-extras
安装并键入:
git-delete-submodule submodule
然后事情就完成了。 子模块目录将从您的回购库中删除,并且仍然存在于您的文件系统中。 然后,您可以提交更改,如: git commit -am "Remove the submodule"
。
我发现deinit
对我很好:
git submodule deinit <submodule-name> git rm <submodule-name>
从git文档 :
DEINIT
取消注册给定的子模块,即从.git / config和他们的工作树一起删除整个
submodule.$name
部分。
project dir: ~/foo_project/ submodule: ~/foo_project/lib/asubmodule - - - - - - - - - - - - - - - - - - - - - - - - - run: 1. cd ~/foo_project 2. git rm lib/asubmodule && rm .git/modules/lib/asubmodule && git submodule lib/asubmodule deinit --recursive --force
我刚刚find.submodule(忘记了确切名称)的隐藏文件,它有一个列表…你可以单独擦除它们。 我只有一个,所以我删除了它。 简单,但它可能会混乱Git,因为我不知道是否有任何东西附加到子模块。 似乎目前为止,除了libetpan通常的升级问题,但是(希望)是不相关的。
注意到没有人张贴手动擦除,所以补充说
如果刚刚添加子模块,例如,您只是添加了错误的子模块,或者将其添加到了错误的位置,只需执行git stash
然后删除该文件夹即可。 这是假设添加子模块是您在最近的回购中做的唯一的事情。
以下是我发现必要或有用的四个步骤(重要的第一步):
git rm -f the_submodule rm -rf .git/modules/the_submodule git config -f .git/config --remove-section submodule.the_submodule git commit -m "..."
理论上 , 步骤1中的 git rm
应该照顾它。 希望OP问题的第二部分有一天能得到积极的回应(这可以用一个命令来完成)。
但是到2017年7月, 步骤2是需要删除.git/modules/
中的数据的,否则您不能在将来添加子模块。
因为所有的git submodule
命令似乎都起作用了,所以你可以用git 1.8.5+来解决上面的两个步骤。
第3步删除文件.git/config
中的the_submodule
部分。 这应该是完整的。 (这个入口可能会导致旧的git版本出现问题,但我没有一个testing)。
为此,大多数答案build议使用git submodule deinit
。 我发现使用git config -f .git/config --remove-section
更加明确,不那么容易混淆。 根据git-submodule文档 , git deinit
:
取消注册给定的子模块…如果您确实想从存储库中删除子模块并提交使用git-rm [1] 来代替 。
最后但并非最不重要的,如果你没有git commit
,你会/可能会在做git submodule summary
(从git 2.7开始)时出错:
fatal: Not a git repository: 'the_submodule/.git' * the_submodule 73f0d1d...0000000:
这是不pipe你是否执行步骤2或3。