关于git:如何删除子模块?

How do I remove a submodule?

如何删除Git子模块?

顺便问一下,我不能这么做有什么原因吗EDOCX1?0?


通过页面Git子模块教程:

要删除子模块,需要:

  • .gitmodules文件中删除相关部分。
  • 阶段.gitmodules改变git add .gitmodules
  • .git/config中删除相关章节。
  • 运行git rm --cached path_to_submodule(无尾斜线)。
  • 运行rm -rf .git/modules/path_to_submodule
  • 承诺第十一条〔八〕款
  • 删除现在未跟踪的子模块文件
  • 另请参见:下面的其他步骤。


    Since Git1.8.3(April 22D,2013):

    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.

    删除过程也使用git rm(自从GIT1.8.5 October 2013)。

    摘要

    The 3-steps removal process will be:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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

    清除

    This is mentioned in Daniel Schroeder's answer,and summarized by eonil in the comments:

    BLCK1/

    See Commit 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 .gitmodules is 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." section from the .gitmodules file and stage both.

    从这个标记中可以看出

    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/config together with the work tree himself).

    Help those users by providing a 'deinit' command.
    This removes the whole submodule. section from .git/config either 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.

    本文关照初始化步骤(EDOCX1&4)和EDOCX1&5)

    自从GIT1.8.5以来,第git rm号法律还规定:

    • File:it is need to removed for you.
    • The submodule special entry(as illustrated by this question):The GIT RM removes it from the index:(无trailing slash)That will remove that directory stored in the index with a special mode"160000",marking it as a submodule root directory.

    如果你忘记了最后一步,并尝试添加一个副产品,作为一个常规目录,你会得到错误的信息,如:

    ZZU1

    注:Since Git 2.17(Q2 2018),Git subbodule deinit is no longer a shell script.这叫一个C函数。

    See commit 2E61273,commit 1342476(14 Jan 2018)by Prathamesh Chavan(EDOCX1&10).哈马诺Junio C.EDOCX1&11--in commit EAD8DBE,13 Feb 2018

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


    记下来Since Gite 1.8.5.2,two commands will do:

    1
    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 U submodule folder will prevent the same submodule from being added back or replaced in the future.同时,作为@vonc mentioned,git rmWill do most of the job on a submodule.

    最新情况(07/05/2017)--

    (just to clarify,the_submodule)is the relative path of the submodule inside the project.例如,如果潜水管道内有一个subdir子目录。

    2.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 EDOCX1&17)section of EDOCX1&4(as of July 2017),which can be removed using a third command:

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


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

    使用git 1.7.8或更高版本克隆的子模块在本地repo中最多会留下四个自身的痕迹。删除这四个记录道的过程由以下三个命令给出:

    1
    2
    3
    4
    5
    6
    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


    简单步骤

  • 删除配置项:git config -f .git/config --remove-section submodule.$submodulenamegit config -f .gitmodules --remove-section submodule.$submodulename
  • 从索引中删除目录:
    git rm --cached $submodulepath
  • 提交
  • 删除未使用的文件:rm -rf $submodulepathrm -rf .git/modules/$submodulename
  • 请注意:$submodulepath不包含前导或尾随斜杠。

    背景

    当你做git submodule add时,它只会加在.gitmodules上,但是一旦你做了git submodule init,它就加入了.git/config

    因此,如果您希望删除模块,但能够快速恢复,那么就这么做:

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

    最好先做git rebase HEADgit commit。最后,如果你把它放到一个脚本中。

    还有一个答案,我可以不流行一个git子模块吗?.


    除了这些建议之外,我还必须添加一个同名的新子模块(在我的例子中,我是用原来的叉子替换叉子)。


    To remove a submodule added using:

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

    运行:

    1
    git rm lib/blah

    是的

    For old versions of GIT(Circa ~ 1.8.5)use:

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


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

    1
    git rm --cached path/to/submodule

    如果你要写在Git的邮件列表上,可能会有人给你写一个shell脚本。


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

    1
    2
    [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


    总而言之,您应该这样做:

  • 设置path_to_submodulevar(无尾斜杠):

    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_子模块的存储和删除(以防止信息丢失)

    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中的任何内容。在这种情况下,您只需要:

    1
    2
    3
    4
    git rm --cached subfolder
    git add subfolder
    git commit -m"Enter message here"
    git push

    在执行git add之前,我还删除了.git文件夹。


    我发现deinit对我有好处:

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

    来自GIT文档:

    deinit

    Unregister the given submodules, i.e. remove the whole submodule.$name
    section from .git/config together with their work tree.


    在对所有不同的答案进行实验之后,我终于找到了这个解决办法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/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

    这与你添加潜水艇之前的状态相同。你可以再一次添加潜水艇,这在这里是不可能的。

    1
    2
    git submodule add $giturl test
    aboveScript test

    这给了你一个干净的检查,没有任何改变。

    This was tested with:

    1
    2
    $ git --version
    git version 1.9.3 (Apple Git-50)


    我目前正在做的是2012年12月(结合了这些答案的大部分):

    1
    2
    3
    4
    5
    6
    7
    8
    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文件中删除相关节。可以使用以下命令:

    1
    git config -f .gitmodules --remove-section"submodule.submodule_name"

    2.)阶段.gitmodules变化

    1
    git add .gitmodules

    3.)删除.git/config中的相关章节。可以使用以下命令:

    1
    git submodule deinit -f"submodule_name"

    4.)移除Gitlink(无尾随斜杠):

    1
    git rm --cached path_to_submodule

    5.)清理.git/modules

    1
    rm -rf .git/modules/path_to_submodule

    6)提交:

    1
    git commit -m"Removed submodule <name>"

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

    1
    rm -rf path_to_submodule


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

    Install it and type:

    1
    git-delete-submodule submodule

    然后事情就发生了。潜艇目录将从您的备份中删除,并且仍然存在于您的档案系统中。你可以像这样改变


    我必须进一步执行John Douthe的步骤,并将cd放入子模块的目录中,然后删除git存储库:

    1
    2
    cd submodule
    rm -fr .git

    然后,我可以将这些文件作为父Git存储库的一部分提交,而不必使用对子模块的旧引用。


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

    1
    2
    3
    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"..."

    理论上,步骤1中的git rm应该处理好它。希望有一天,OP问题的第二部分可以得到肯定的回答(这可以在一个命令中完成)。

    但截至2017年7月,第2步是删除.git/modules/中的数据所必需的,否则,您不能在将来添加子模块。

    正如Tinlyx的回答所指出的那样,对于git 1.8.5+,您可能可以通过上述两个步骤,因为所有git submodule命令似乎都可以工作。

    步骤3删除文件.git/configthe_submodule的部分。这应该是为了完整性。(该条目可能会对旧的Git版本造成问题,但我没有要测试的版本)。

    对此,大多数答案建议使用git submodule deinit。我发现使用git config -f .git/config --remove-section更明确,也不那么容易混淆。根据Git子模块文件,git deinit

    Unregister the given submodules ... If you really want to remove a
    submodule from the repository and commit that use git-rm[1]
    instead.

    最后但并非最不重要的是,如果您不执行git commit,您在执行git submodule summary时(从git 2.7开始)会/可能会出错:

    1
    2
    fatal: Not a git repository: 'the_submodule/.git'
    * the_submodule 73f0d1d...0000000:

    不管您是执行第2步还是第3步。


    1
    2
    3
    4
    5
    6
    7
    8
    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


    我找到了潜艇(Forgot's exactly name)隐藏的文件,它有一个清单。你可以用这种方式逐个除掉他们。我只有一个,所以我删除了它。很简单,但可能会有点不对劲,因为我不知道有没有任何东西与潜艇有关。看起来很好,从利伯特潘的普通升级问题来看,但这是(希望)不相关的。

    通知没有人在手动擦除,因此添加


    如果您刚刚添加了子模块,例如,您只是添加了错误的子模块或将其添加到了错误的位置,只需执行git stash,然后删除文件夹。这是假设添加子模块是您在最近的回购中所做的唯一事情。


    对于Git 2.17及更高版本,它只是:

    1
    2
    3
    git submodule deinit -f {module_name}
    git add {module_name}
    git commit

    在最新的Git中,只需要4个操作就可以删除Git子模块。

    • 删除EDOCX1[0]中的对应条目
    • 阶段变更git add .gitmodules
    • 删除子模块目录git rm --cached
    • 承诺1〔18〕。