协慌网

登录 贡献 社区

如何删除子模块?

如何删除 Git 子模块?

顺便说一下,有什么理由我不能简单地做git submodule rm whatever

答案

通过页面Git Submodule 教程

要删除子模块,您需要:

  1. .gitmodules文件中删除相关部分。
  2. 阶段.gitmodules更改git add .gitmodules
  3. .git/config删除相关部分。
  4. 运行git rm --cached path_to_submodule (没有尾部斜杠)。
  5. 运行rm -rf .git/modules/path_to_submodule
  6. 提交git commit -m "Removed submodule <name>"
  7. 删除现在未跟踪的子模块文件
    rm -rf path_to_submodule

另见下面的替代步骤

git1.8.3(2013 年 4 月 22 日)

一旦你表达了对带有 “ submodule init ” 的子模块的兴趣,就没有瓷器方式说 “我不再对这个子模块感兴趣” 了。
submodule deinit ” 是这样做的方法。

删除过程也使用git rm (自 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 -rfDaniel Schroeder回答中提到了这一点, Eonil评论中 对此进行总结:

这使得.git/modules/<path-to-submodule>/不变。
因此,如果您曾使用此方法删除子模块并再次重新添加它们,则无法实现,因为存储库已损坏。


git rm :参见commit 95c16418

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

让 “ git rm ” 不仅可以从工作树中删除子模块,还可以从.gitmodules文件中删除 “ submodule.<submodule name> ” 部分并对.gitmodules分段,从而.gitmodules用户。


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文件.gitmodules模块的 url:需要为你删除它。
  • 子模块特殊条目如此问题所示 ):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 子模块 deinit 不再是 shell 脚本。
它是对 C 函数的调用。

参见Prathamesh Chavan( pratham-pc )的 提交 2e61273提交 1342476 (2018 年 1 月 14 日
(由Junio C gitster合并- gitster - in commit ead8dbe ,2018 年 2 月 13 日)

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

只是一个说明。从 git 1.8.5.2 开始,两个命令将执行:

git rm the_submodule
rm -rf .git/modules/the_submodule

正如 @Mark Cheverton 的回答正确指出的那样,如果没有使用第二行,即使你现在删除了子模块,剩余的. git / modules / the_submodule 文件夹也会阻止将来添加或替换相同的子模块。另外,正如 @VonC 所提到的, git rm将完成子模块的大部分工作。

- 更新(07/05/2017) -

只是为了澄清, the_submodule是项目内子模块的相对路径。例如,如果子模块位于子目录subdir subdir/my_submodule

正如在评论和其他答案中正确指出的那样,两个命令(尽管在功能上足以删除子模块)确实在.git/config[submodule "the_submodule"]部分留下了痕迹(截至 2017 年 7 月),可以使用第三个命令删除:

git config -f .git/config --remove-section submodule.the_submodule 2> /dev/null