How do I remove a submodule?

How do I remove a Git submodule?

By the way, is there a reason I can't simply do

git submodule rm whatever

?


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.

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

Summary

The 3-steps removal process would then be:

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 Eonil in the comments:

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 rm : 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.<submodule name> " section from the .gitmodules file and stage both.


git submodule deinit : It stems from this patch:

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

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

Since git1.8.5, the git rm takes also care of the:

  • ' add ' step which records the url of a submodule in the .gitmodules 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:
    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.
  • 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.

    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)

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

    Via the page Git Submodule Tutorial:

    To remove a submodule you need to:

  • Delete the relevant section from the .gitmodules file.
  • Stage the .gitmodules changes git add .gitmodules
  • Delete the relevant section from .git/config .
  • Run git rm --cached path_to_submodule (no trailing slash).
  • Run rm -rf .git/modules/path_to_submodule
  • Commit git commit -m "Removed submodule <name>"
  • Delete the now untracked submodule files
    rm -rf path_to_submodule
  • See also : alternative steps below.


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

    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 rm will do most of the job on a submodule.

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

    Just to clarify, the_submodule is the relative path of the submodule inside the project. For example, it's subdir/my_submodule if the submodule is inside a subdirectory 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:

    git config -f .git/config --remove-section submodule.the_submodule 2> /dev/null
    
    链接地址: http://www.djcxy.com/p/324.html

    上一篇: 如何验证JavaScript中的电子邮件地址?

    下一篇: 我如何移除子模块?