如何删除子模块?

R. Martinho Fernandes 3366 git git-submodules

如何删除Git子模块?

顺便说一句,有什么理由我不能干脆做到 git submodule rm whatever吗?

John Douthat.. 3369

通过页面Git Submodule教程:

要删除子模块,您需要:

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

另见:下面的替代步骤.

  • "顺便说一下,有什么理由我不能简单地给子模块做任何事情吗?" ? (398认同)
  • 坦率地说,我不知道为什么.但我希望他们能增加一个命令.这4个步骤太复杂了. (116认同)
  • @abernier一个简单的答案可能是"因为没有这样的命令存在." 我的猜测是他们试图明确删除子模块文件与子模块配置,以避免意外数据丢失.也许有人会认为`git submodule rm`只是删除子模块注册,如果命令也删除了本地存储库,会感到惊讶.任何局部变化都将无可挽回地丧失.也许另一个人会认为只会删除文件. (47认同)
  • 还需要rm -rf .git\modules\submodule名称? (32认同)
  • 这是一个删除子模块的bash脚本,只需为submodule-rm创建一个git别名;)https://gist.github.com/2491147 (24认同)
  • @dtan确保没有斜杠 (7认同)
  • 如果要将目录重新添加为普通子模块(还记得删除其内部.git文件夹),则需要删除.git/modules参考目录.请参阅下面Mark的答案:http://stackoverflow.com/a/9536504/149416 (7认同)
  • `git submodule rm`应该是一个命令.如果在子模块中有子模块,这种设置会变得更加复杂,因为`.git/config`的位置会发生变化. (4认同)
  • 你需要暂存.gitmodules.在提交之前运行git add .gitmodules. (3认同)
  • 好吧,我不得不再次`git rm --cached -f submodule_name`,现在它可以了. (2认同)
  • 还必须清理.git/modules以允许稍后使用相同的路径添加模块. (2认同)

VonC.. 2067

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 -rf:Daniel Schroeder回答中提到了这一点,并在评论中Eonil总结:

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


git rm:请参阅commit 95c16418:

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

让" git rm"帮助用户不仅从工作树中删除子模块,而且还submodule.<submodule name>.gitmodules文件中删除" "部分并将两者都分段.


git submodule deinit:它来自这个补丁:

使用" git submodule init",用户可以告诉git他们关心一个或多个子模块,并希望在下次调用" git submodule update" 时填充它.
但目前没有简单的方法他们可以告诉git他们不再关心子模块并且想要摆脱本地工作树(除非用户知道很多关于子模块内部并且submodule.$name.url.git/config工作中删除" "设置树自己).

通过提供' deinit'命令帮助这些用户.
将删除给定子模块的整个submodule.<name>部分.git/config(或者对于所有已经初始化的部分,如果.给出' ').
如果当前工作树包含修改除非被强制,则失败.
抱怨在命令行上给出的子模块时,无法找到url设置.git/config,但仍然不会失败.

如果(de)初始化步骤(.git/config.git/modules/xxx),这需要注意

从git1.8.5开始,git rm需要关注:

  • ' add'记录.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()提交2e61273,提交1342476(2018年1月14日).(由Junio C Hamano合并- -提交ead8dbe,2018年2月13日)pratham-pc
gitster

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

  • 你能给出一个用于`submodule deinit`的例子吗? (16认同)
  • @yourfriendzak这里是成功使用它的一个例子:http://stackoverflow.com/a/16161950/6309.但请记住,与我原先认为的相反,1.8.3还没有发布!在Unix上,您可以从源代码编译它. (4认同)
  • 在当前的git(v1.9 +)中,普通的旧`git rm子模块'完全按照你想要的那样做,正如其他人已经说过的那样. (2认同)

tinlyx.. 442

只是一张纸条.从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/my_submodule如果子模块位于子目录中subdir.

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

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

  • 这不会从`.git/config`中删除子模块条目.有关删除子模块的完整方法,请参见http://stackoverflow.com/a/36593218/1562138. (17认同)
  • 我正在使用git版本2.4.9(Apple Git-60),而我所要做的只是rm the_submodule.我推了一下,然后重新添加了一个名为与子模块相同的文件夹,它没有问题. (3认同)
  • 这是100%绝对辉煌和工作.哇. (3认同)
  • 我觉得更安全地运行第一个.. git submodule deinit -f the_submodule (2认同)

fvgs.. 417

这个问题的大多数答案都是过时的,不完整的或不必要的复杂.

使用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

  • 为什么这个答案有这么少的赞成?所有那些受欢迎的答案都会遗漏一些东西,这是唯一能够以最简单的方式真正消除子模块所有痕迹的答案.请注意:命令的顺序很重要. (30认同)
  • *.gitmodules*文件似乎仍然不受影响运行这些命令 (8认同)
  • 这是2018年的不复杂答案吗? (7认同)
  • @mbdevpl在接受答案后3年,我想没有人设法说服OP接受这个 (5认同)

errordevelop.. 200

简单的步骤

  1. 删除配置条目:
    git config -f .git/config --remove-section submodule.$submodulename
    git config -f .gitmodules --remove-section submodule.$submodulename
  2. 从索引中删除目录:
    git rm --cached $submodulepath
  3. 承诺
  4. 删除未使用的文件
    rm -rf $submodulepath
    rm -rf .git/modules/$submodulename

请注意: $submodulepath不包含前导或尾部斜杠.

背景

当你这样做时git submodule add,它只会添加它.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 submodule | grep'^ +'| cut -d'' - f2` (2认同)

Mark Chevert.. 82

除了建议之外,我还必须rm -Rf .git/modules/path/to/submodule能够添加一个具有相同名称的新子模块(在我的情况下,我用原始替换了一个fork)


Doug.. 56

要删除使用以下内容添加的子模块:

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

  • `git rm`仍然在`.git/modules /`中留下了东西.(2.5.4) (6认同)

Carmine Paol.. 49

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

git rm --cached path/to/submodule

如果你在git的邮件列表上写,可能有人会为你做一个shell脚本.


luissquall.. 41

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

  1. 设置path_to_submodulevar(没有尾部斜杠):

    path_to_submodule=path/to/submodule

  2. 从.gitmodules文件中删除相关行:

    git config -f .gitmodules --remove-section submodule.$path_to_submodule

  3. 从.git/config中删除相关部分

    git config -f .git/config --remove-section submodule.$path_to_submodule

  4. Unstage并仅从索引中删除$ path_to_submodule(以防止丢失信息)

    git rm --cached $path_to_submodule

  5. 跟踪对.gitmodules所做的更改

    git add .gitmodules

  6. 提交超级项目

    git commit -m "Remove submodule submodule_name"

  7. 删除现在未跟踪的子模块文件

    rm -rf $path_to_submodule

    rm -rf .git/modules/$path_to_submodule


Charles.. 41

您可以使用别名来自动化其他人提供的解决方案:

[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"

把它放在你的git配置中,然后你就可以: git rms path/to/submodule


Oli Studholm.. 39

如果由于您添加,提交并推送了一个已经是Git存储库(包含)的文件夹而意外添加了子模块.git,则您将无法.gitmodules编辑或编辑任何文件.git/config.在这种情况下,您只需要:

git rm --cached subfolder
git add subfolder
git commit -m "Enter message here"
git push

FWIW,我还在删除.git之前删除了文件夹git add.


Damjan Pavli.. 30

我发现deinit作品对我有好处:

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

来自git docs:

DEINIT

取消注册给定的子模块,即submodule.$name 从.git/config中删除整个部分及其工作树.


udondan.. 20

在对此网站上的所有不同答案进行试验后,我最终得到了这个解决方案:

#!/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)


Lance Rushin.. 17

我目前正在做什么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}"


Ishan Liyana.. 14

这是我做的:

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

6.)承诺:

git commit -m "Removed submodule <name>"

7.)删除现在未跟踪的子模块文件

rm -rf path_to_submodule


Chien-Wei Hu.. 13

我最近发现了一个git项目,其中包含许多有用的git相关命令:https://github.com/visionmedia/git-extras

安装并输入:

git-delete-submodule submodule

事情就这样完成了.子模块目录将从您的仓库中删除,并且仍然存在于您的文件系统中.然后,您可以提交更改,如:git commit -am "Remove the submodule".


Kyle Clegg.. 10

我不得不将John Douthat的步骤更进一步并cd进入子模块的目录,然后删除Git存储库:

cd submodule
rm -fr .git

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


小智.. 8

以下是我发现必要或有用的4个步骤(首先是重要的步骤):

git rm -f the_submodule
rm -rf .git/modules/the_submodule
git config -f .git/config --remove-section submodule.the_submodule
git commit -m "..."

理论上,git rm步骤1中应该照顾它.希望OP问题的第二部分可以在某一天得到积极回答(这可以在一个命令中完成).

但是截至2017年7月,步骤2是必要的,以删除数据,.git/modules/否则,您不能在以后添加子模块.

正如tinlyx的回答所指出的那样,你可以通过git 1.8.5+的上述两个步骤逃脱,因为所有git submodule命令似乎都有效.

第3步删除the_submodule文件中的部分.git/config.这应该是为了完整性.(该条目可能会导致较旧的git版本出现问题,但我没有测试版本).

为此,大多数答案建议使用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:

无论您是执行步骤2还是3,都可以执行此操作.


Stephen J.. 7

我刚刚找到了.submodule(忘了确切的名字)隐藏文件,它有一个列表......你可以单独删除它们.我只有一个,所以我删除了它.很简单,但它可能会搞砸Git,因为我不知道是否有任何附加到子模块的内容.到目前为止似乎还不错,除了libetpan通常的升级问题,但是(希望)不相关.

注意到没有人发布手动擦除,所以补充说


小智.. 7

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


Albert Tobac.. 6

在git 2.17及更高版本中,它只是:

git submodule deinit -f {module_name}
git add {module_name}
git commit


归档时间:

查看次数:

826052 次

最近记录:

7 月,3 周 前