How do I remove a submodule?

git, git-submodules

Solution

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 "`git submodule init`". "`git 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} "$@"

Problem

How do I remove a Git submodule? Why can't I do `git submodule rm module_name`?

Original source

Related problems