git 如何删除子模块?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1260748/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:52:09  来源:igfitidea点击:

How do I remove a submodule?

gitgit-submodules

提问by R. Martinho Fernandes

How do I remove a Git submodule?

如何删除 Git 子模块?

By the way, is there a reason I can't simply do git submodule rm whatever?

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

采纳答案by VonC

Since git1.8.3 (April 22d, 2013):

git1.8.3(2013 年 4 月 22 日)开始

There was no Porcelain way to say "I no longer am interested in this submodule", once you express your interest in a submodule with "submodule init".
"submodule deinit" is the way to do so.

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

The deletion process also uses git rm(since git1.8.5 October 2013).

删除过程也使用git rm(自 git1.8.5 2013 年 10 月起)。

Summary

概括

The 3-steps removal process would then be:

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

Explanation

解释

rm -rf: This is mentioned in Daniel Schroeder's answer, and summarized by Eonilin the comments:

rm -rf:这是Daniel Schroeder回答中提到的,Eonil评论中总结了这一点

This leaves .git/modules/<path-to-submodule>/unchanged.
So if you once delete a submodule with this method and re-add them again, it will not be possible because repository already been corrupted.

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



git rm: See commit 95c16418:

git rm:见提交 95c16418

Currently using "git rm" on a submodule removes the submodule's work tree from that of the superproject and the gitlink from the index.
But the submodule's section in .gitmodulesis left untouched, which is a leftover of the now removed submodule and might irritate users (as opposed to the setting in .git/config, this must stay as a reminder that the user showed interest in this submodule so it will be repopulated later when an older commit is checked out).

Let "git rm" help the user by not only removing the submodule from the work tree but by also removing the "submodule.<submodule name>" section from the .gitmodulesfile and stage both.

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

让 " git rm" 不仅从工作树中删除子模块,而且通过submodule.<submodule name>.gitmodules文件和暂存中删除 " " 部分来帮助用户。



git submodule deinit: It stems from this patch:

git submodule deinit:它源于这个补丁

With "git submodule init" the user is able to tell git they care about one or more submodules and wants to have it populated on the next call to "git submodule update".
But currently there is no easy way they can tell git they do not care about a submodule anymore and wants to get rid of the local work tree (unless the user knows a lot about submodule internals and removes the "submodule.$name.url" setting from .git/configtogether with the work tree himself).

Help those users by providing a 'deinit' command.
This removes the whole submodule.<name>section from .git/configeither for the given submodule(s)(or for all those which have been initialized if '.' is given).
Fail if the current work tree contains modifications unless forced.
Complain when for a submodule given on the command line the url setting can't be found in .git/config, but nonetheless don't fail.

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

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

This takes care if the (de)initialization steps (.git/configand .git/modules/xxx)

如果(去)初始化步骤(.git/config.git/modules/xxx

Since git1.8.5, the git rmtakes alsocare of the:

由于git1.8.5的git rm需要关心的:

  • 'add' step which records the url of a submodule in the .gitmodulesfile: it is need to removed for you.
  • the submodule special entry(as illustrated by this question): the git rm removes it from the index:
    git rm --cached path_to_submodule(no trailing slash)
    That will remove that directory stored in the index with a special mode "160000", marking it as a submodule root directory.
  • ' add' 在.gitmodules文件中记录子模块的 url 的步骤:需要为您删除它。
  • 子模块特殊条目(如本问题所示): git rm 将其从索引中删除:(
    git rm --cached path_to_submodule没有尾部斜杠)
    这将删除存储在索引中的具有特殊模式“160000”的目录,将其标记为子模块根目录.

If you forget that last step, and try to add what was a submodule as a regular directory, you would get error message like:

如果您忘记了最后一步,并尝试将子模块添加为常规目录,则会收到如下错误消息:

git add mysubmodule/file.txt 
Path 'mysubmodule/file.txt' is in submodule 'mysubmodule'


Note: since Git 2.17 (Q2 2018), git submodule deinit is no longer a shell script.
It is a call to a C function.

注意:从 Git 2.17(2018 年第二季度)开始,git submodule deinit 不再是 shell 脚本。
它是对 C 函数的调用。

See commit 2e61273, commit 1342476(14 Jan 2018) by Prathamesh Chavan (pratham-pc).
(Merged by Junio C Hamano -- gitster--in commit ead8dbe, 13 Feb 2018)

请参阅Prathamesh Chavan ( ) 的commit 2e61273commit 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} "$@"

回答by John Douthat

Via the page Git Submodule Tutorial:

通过页面Git 子模块教程

To remove a submodule you need to:

要删除子模块,您需要:

  1. Delete the relevant section from the .gitmodulesfile.
  2. Stage the .gitmoduleschanges:
    git add .gitmodules
  3. Delete the relevant section from .git/config.
  4. Remove the submodule files from the working tree and index:
    git rm --cached path_to_submodule(no trailing slash).
  5. Remove the submodule's .gitdirectory:
    rm -rf .git/modules/path_to_submodule
  6. Commit the changes:
    git commit -m "Removed submodule <name>"
  7. Delete the now untracked submodule files:
    rm -rf path_to_submodule
  1. .gitmodules文件中删除相关部分。
  2. 阶段性.gitmodules更改:
    git add .gitmodules
  3. 从 中删除相关部分.git/config
  4. 从工作树和索引中删除子模块文件:(
    git rm --cached path_to_submodule没有尾部斜杠)。
  5. 删除子模块的.git目录:
    rm -rf .git/modules/path_to_submodule
  6. 提交更改:
    git commit -m "Removed submodule <name>"
  7. 删除现在未跟踪的子模块文件:
    rm -rf path_to_submodule

See also: alternative steps below.

另请参阅下面的替代步骤

回答by tinlyx

Just a note. Since git 1.8.5.2, two commands will do:

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

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

As @Mark Cheverton's answer correctly pointed out, if the second line isn't used, even if you removed the submodule for now, the remnant .git/modules/the_submodule folder will prevent the same submodule from being added back or replaced in the future. Also, as @VonC mentioned, git rmwill do most of the job on a submodule.

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

--Update (07/05/2017)--

--更新 (07/05/2017)--

Just to clarify, the_submoduleis the relative path of the submodule inside the project. For example, it's subdir/my_submoduleif the submodule is inside a subdirectory subdir.

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

As pointed out correctly in the comments and other answers, the two commands (although functionally sufficient to remove a submodule), do leave a trace in the [submodule "the_submodule"]section of .git/config(as of July 2017), which can be removed using a third command:

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

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

回答by fvgs

The majority of answers to this question are outdated, incomplete, or unnecessarily complex.

这个问题的大多数答案已经过时、不完整或不必要地复杂。

A submodule cloned using git 1.7.8 or newer will leave at most four traces of itself in your local repo. The process for removing those four traces is given by the three commands below:

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

回答by errordeveloper

Simple steps

简单的步骤

  1. Remove config entries:
    git config -f .git/config --remove-section submodule.$submodulename
    git config -f .gitmodules --remove-section submodule.$submodulename
  2. Remove directory from index:
    git rm --cached $submodulepath
  3. Commit
  4. Delete unused files:
    rm -rf $submodulepath
    rm -rf .git/modules/$submodulename
  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

Please note:$submodulepathdoesn't contain leading or trailing slashes.

请注意:$submodulepath不包含前导或尾随斜杠。

Background

背景

When you do git submodule add, it only adds it to .gitmodules, but once you did git submodule init, it added to .git/config.

当您这样做时git submodule add,它只会将其添加到.gitmodules,但是一旦您这样做了git submodule init,它就会添加到.git/config.

So if you wish to remove the modules, but be able to restore it quickly, then do just this:

因此,如果您希望删除模块,但能够快速恢复它,请执行以下操作:

git rm --cached $submodulepath
git config -f .git/config --remove-section submodule.$submodulepath

It is a good idea to do git rebase HEADfirst and git commitat the end, if you put this in a script.

这是一个好主意,做git rebase HEAD第一,git commit在最后,如果你把这个脚本。

Also have a look at an answer to Can I unpopulate a Git submodule?.

还可以查看Can I unpopulate a Git submodule?的答案.

回答by Mark Cheverton

In addition to the recommendations, I also had to rm -Rf .git/modules/path/to/submoduleto be able to add a new submodule with the same name (in my case I was replacing a fork with the original)

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

回答by Doug

To remove a submodule added using:

要删除使用以下方法添加的子模块:

git submodule add [email protected]:repos/blah.git lib/blah

Run:

跑:

git rm lib/blah

That's it.

就是这样。

For old versions of git (circa ~1.8.5) use:

对于旧版本的 git(大约 1.8.5)使用:

git submodule deinit lib/blah
git rm lib/blah
git config -f .gitmodules --remove-section submodule.lib/blah

回答by Carmine Paolino

You must remove the entry in .gitmodulesand .git/config, and remove the directory of the module from the history:

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

git rm --cached path/to/submodule

If you'll write on git's mailing list probably someone will do a shell script for you.

如果您在 git 的邮件列表上写信,可能有人会为您编写一个 shell 脚本。

回答by luissquall

To summarize, this is what you should do :

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

  1. Set path_to_submodulevar (no trailing slash):

    path_to_submodule=path/to/submodule

  2. Delete the relevant line from the .gitmodules file:

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

  3. Delete the relevant section from .git/config

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

  4. Unstage and remove $path_to_submodule only from the index (to prevent losing information)

    git rm --cached $path_to_submodule

  5. Track changes made to .gitmodules

    git add .gitmodules

  6. Commit the superproject

    git commit -m "Remove submodule submodule_name"

  7. Delete the now untracked submodule files

    rm -rf $path_to_submodule

    rm -rf .git/modules/$path_to_submodule

  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. 取消暂存并仅从索引中删除 $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

回答by Charles

You can use an alias to automate the solutions provided by others:

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

[alias]
  rms = "!f(){ git rm --cached \"\";rm -r \"\";git config -f .gitmodules --remove-section \"submodule.\";git config -f .git/config --remove-section \"submodule.\";git add .gitmodules; }; f"

Put that in your git config, and then you can do: git rms path/to/submodule

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