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

- 24,552
- 19
- 101
- 135

- 228,013
- 71
- 433
- 510
-
15That's actually not true. That answer does not address removing the submodule entry from `.git/config`. The accepted answer shows the up-to-date way to fully remove a a submodule. It's also explained more succinctly in this answer: http://stackoverflow.com/a/36593218/1562138 – fvgs Apr 13 '16 at 09:02
-
I found this article very helpful in removing submodules. It includes information on removing entries in the .gitsubmodules and .git/config files [link](https://chrisjean.com/git-submodules-adding-using-removing-and-updating/) – Ri_ May 15 '16 at 17:46
-
22Please save yourself some time and directly go the answer that works (in 2017): http://stackoverflow.com/a/36593218/528313 – Vincenzo Pii Jan 16 '17 at 12:57
-
I've wrestled submodule problems for two days. The breakthrough came when I found this: https://forums.developer.apple.com/thread/13102. Basically, Xcode, and perhaps other apps, struggle to expand url's containing '~'. Once I changed ssh://username@server.remoteHost.com/~/git/MyRepo.git to ssh://username@server.remoteHost.com/home/username/git/MyRepo.git (look up the actual path on your server), all the weirdness disappeared with ten minutes. See also https://stackoverflow.com/questions/32833100/adding-a-github-repository-in-xcode-7-using-ssh-authentication-gives-an-authenti/33985629#33985629 – Elise van Looij Feb 09 '18 at 12:48
37 Answers
In modern git (I'm writing this in 2022, with an updated git
installation), this has become quite a bit simpler:
- Run
git rm <path-to-submodule>
, and commit.
This removes the filetree at <path-to-submodule>
, and the submodule's entry in the .gitmodules
file. I.e. all traces of the submodule in your repository proper are removed.
As the docs note however, the .git
dir of the submodule is kept around (in the modules/
directory of the main project's .git
dir), "to make it possible to checkout past commits without requiring fetching from another repository".
If you nonetheless want to remove this info, manually delete the submodule's directory in .git/modules/
, and remove the submodule's entry in the file .git/config
. These steps can be automated using the commands
rm -rf .git/modules/<path-to-submodule>
, andgit config --remove-section submodule.<path-to-submodule>
.
Older community wiki instructions:
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
. - Remove the submodule files from the working tree and index:
git rm --cached path_to_submodule
(no trailing slash). - Remove the submodule's
.git
directory:rm -rf .git/modules/path_to_submodule
- Commit the changes:
git commit -m "Removed submodule <name>"
- Delete the now untracked submodule files:
rm -rf path_to_submodule
See also: alternative steps below.

- 3,086
- 2
- 15
- 8

- 40,711
- 10
- 69
- 66
-
501"And by the way, is there a reason I can't simply git submodule rm whatever?" ? – abernier Jan 20 '11 at 19:04
-
52@abernier A curt answer could be "because no such command exists." My guess is that they're trying to make the removal of submodule files vs submodule configuration explicit to avoid accidental data loss. Perhaps one person would think that `git submodule rm` simply removes submodule registration, and would be surprised if the command also deleted the local repository. Any local changes would be irretrievably lost. And perhaps another person would think that only the files would be removed. – John Douthat Jan 21 '11 at 01:50
-
140Frankly, I don't know why. I hope they add a command, though. These 4 steps are too complicated. – John Douthat Jan 21 '11 at 01:56
-
i kept on getting this error: "fatal: pathspec 'blocks/submodule_folder/' did not match any files". i added the -f, --force command: "git rm --cached -f blocks/submodule_folder" and that got rid of the cache. – hellatan Dec 17 '11 at 23:54
-
7
-
1That didn't work for me. Shouldn't those folders that were previously submodules now appear as ordinary folders within the parent project? Cause they don't for me, and after pushing that change to GitHub it still thinks they're submodules, just that they don't link to the submodule repos anymore... – mxk Jan 13 '12 at 09:26
-
2
-
2also have to clean .git/modules to allow adding a module later with the same path. – Ian Yang Mar 24 '12 at 11:53
-
27Here's a bash script that removes a submodule, just create a git alias for submodule-rm ;) https://gist.github.com/2491147 – Capi Etheriel Apr 25 '12 at 17:27
-
The submodule directory should be deleted, too, correct? So: `rm -rf path_to_submodule` – Josh Brown May 18 '12 at 14:59
-
35
-
1Yes, you probably want to delete the now-untracked submodule files. – John Douthat May 22 '12 at 23:54
-
7You do need to remove the .git/modules reference directory if you want to re-add the directory as a plain submodule (remembering to delete its internal .git folder as well). See Mark's answer below: http://stackoverflow.com/a/9536504/149416 – Anton I. Sipos Jun 29 '12 at 22:15
-
3You need to stage .gitmodules. Run git add .gitmodules before commiting. – luissquall Jul 09 '12 at 16:38
-
4`git submodule rm` should be a command. This setup becomes way more complicated if you have submodules within submodules because the location of your `.git/config` changes. – Justin Force Aug 22 '12 at 21:20
-
how about delete all cache in a folder like `git rm --cached path_to_sub/*` – Dzung Nguyen Aug 25 '12 at 07:45
-
@sidewaysmilk you might just have explained why the command didn't exist. If you make a command, you should cover all those corner cases, and maybe the decided it would be too hard. – Adrian Ratnapala Sep 04 '12 at 20:09
-
1@AdrianRatnapala Maybe. But it's git! These guys are brilliant. And the most complicated procedure should be the first candidate for automation. – Justin Force Sep 18 '12 at 21:27
-
1How does modifying the .git directory by hand work when you push your changes? Does everyone who uses the master project need to make these changes by hand, and how do they know that they need to make these changes? – James Moore Oct 03 '12 at 16:07
-
1@JamesMoore The modified `.gitmodules` file will be pushed to master, so everyone will see the change. However, the relevant section in `.git/config` will not be pushed to others. It merely a local setting with information about the cloned submodule repo. Other people on your project will still need to delete the submodule repo, if necessary. Git cannot faithfully know if the other people have any unpushed changes in that repo, so it would be unsafe for git to automatically delete their copy. – John Douthat Oct 03 '12 at 19:54
-
1The answer is not 100% correct. I found that unless I inserted a "-f" in the "git rm --cached" line, I COULD NOT make this fix work with branches other than "master". Switching to each branch, and using "-f" made it work - I guess it's something to do with the way that editing the config files "breaks" other branches without editing them. Man, submodules are badly designed in git! Never going to use them ever again! – Adam Dec 23 '12 at 18:48
-
There 'should' indeed be a command for removing submodules. how about this: git submodule removeUntrackDelete
? Would that suffice for the aforementioned use cases? :) also, with my limited git knowledge, it is easier for me to mess up these 5 (!) steps than to mess up a single step tbh. – Michahell Mar 07 '13 at 12:56 -
What happens if people have `.git/` with that submodule? Supposing you removed it and push/pull it. There should be a `git submodule rm -f XXX` to avoid data loss. – Wernight May 09 '13 at 14:02
-
-
-
I had to add a -r to the end of the folder remove to take it out of the index: git rm --cached path_to_submodule -r – PeterM May 06 '16 at 16:47
-
this works for me. I want to change the submodule to real files without any `.gitmodules` track. Then you have to delete every submodule git track and the directory clean, and then rebuild your directory.....why it is so complicated to delete the submodule... – penny chan Aug 24 '17 at 04:13
-
deinit still leaves content lying around. I wrote a quick script to behave more like OP's commands. https://github.com/mcandre/gus – mcandre Feb 15 '20 at 17:29
-
rm -rf .git/modules/my_submodule is not a folder. actually .git is not a directory but a file. Has something changed? – openCivilisation Mar 06 '21 at 00:47
-
THIS finally worked. `git rm --cached
` did the trick for me. Thanks! – Jack Scandall Jul 13 '21 at 11:51 -
1@JohnDouthat you say "Any local changes would be irretrievably lost" as a reason why it's not automated. Isn't that risk true for a whole bunch of git commands? Seems like a normal expectation of cli tools that users ought to read up before hitting enter. – jschmitter Jan 25 '22 at 18:29
-
How do I remove ALL submodules? I've removed them one-by-one via `git rm
` but I still have an empty `.gitmodules` file lingering. I want to remove all traces of submodules in my repo. – Emile Cormier Apr 10 '22 at 23:16 -
I ended up removing the empty `.gitmobules` file and it didn't seem to break anything. – Emile Cormier Apr 11 '22 at 00:46
-
I have the same issue as Toskan. removing the config section results in `fatal: no such section: submodule.my.submodule` – Matt Groth May 24 '22 at 03:13
-
If the commands that start with "rm" does not work, start with "git rm ...". – Onat Korucu Jul 12 '22 at 12:18
-
2"In modern git (I'm writing this in 2022, with an updated git installation)" — Could you please say the specific version number you're using. Or even better, the earliest version of git in which it became simpler. – Craig McQueen Jul 28 '22 at 06:38
-
What does "Stage" mean when saying to stage the changes in step 2? I haven't heard that term used in git before. I predominately have been using TortoiseGit context menu for any commits, pushes and pulls. – tzg Nov 01 '22 at 14:44
-
1What does this sentence mean? "To make it possible to checkout past commits without requiring fetching from another repository". It is not really clear to me – Minee Jul 12 '23 at 08:14
-
1@Minee that is if you would like to check out earlier commits while that submodule was still in place. If it's cached, the submodule data will be just checked out. If not, Git would have to fetch it again from its remote repo. – Alexandr Zarubkin Aug 29 '23 at 11:28
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 wholesubmodule.<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} "$@"

- 4,474
- 40
- 55

- 1,262,500
- 529
- 4,410
- 5,250
-
21
-
5@yourfriendzak here is one example of someone successfully using it: http://stackoverflow.com/a/16161950/6309. But keep in mind that, contrary to what I originally believed, 1.8.3 is not yet released! On Unix, you can compile it from the sources. – VonC Apr 28 '13 at 18:45
-
In my experience, `git submodule deinit` does not remove the relevant directory from `.git/config`. It's still there until I manually remove it. – zakdances May 28 '13 at 21:18
-
So if I do a pull after someone else has done this, will my submodule be cleaned up for me, or do I still have to do the usual manual steps anyway? (cf http://stackoverflow.com/questions/14877420/removing-git-submodules-how-to-automate-removal-on-pull ) – Hamish Downer Jun 04 '13 at 15:34
-
2@HamishDowner the special entry should be gone (the directory is no longer a submodule), and the `.gitmodules` should be ok, but I would still double-check anything with the `.git` directory (ie the *local* config, within your local repo: that isn't modified by a `git pull`) – VonC Jun 04 '13 at 15:40
-
@VonC I'm still stuck with the .gitmodules file and inside my .git/modules I have a reference as well. Can we just remove these things, ignore them or something third? – Warpzit Jun 06 '13 at 09:59
-
@Warpzit you do have a git1.8.3, and did a `git submodule deinit`? But if not, yes, you can manually clean the extra metadata. – VonC Jun 06 '13 at 10:11
-
What do other users who share the git repository need to do? just `git pull`? – Jayen Aug 02 '13 at 05:56
-
2@Jayen yes, if you commit the removal of the `.gitmodules` entry and the removal of the special entry in the index, and push that repo, others can pull it and that submodule will be gone. – VonC Aug 02 '13 at 06:04
-
The `deinit` section of `git-submodule(1)` now recommends using `git rm`: "If you really want to remove a submodule from the repository and commit that use git-rm(1) instead." – mgalgs Aug 07 '13 at 20:29
-
1Here's a script that automates those steps: https://gist.github.com/sharplet/6289697. Add it to your `PATH` and `git remove-submodule path/to/submodule`. – Adam Sharp Aug 21 '13 at 02:26
-
@AdamSharp, wouldn't you need to use `git-remove-submodule ...` instead of `git remove-submodule ....`? – kenny Aug 23 '13 at 21:38
-
@kenny no: '`git remove-submodule`' (with a space) will look for an executable '`git-remove-submodule`' (with a dash) anywhere in your `$PATH`. – VonC Aug 23 '13 at 21:40
-
I got an error from the script which I think will happen every time: error: submodule 'magit' (or one of its nested submodules) uses a .git directory (use 'rm -rf' if you really want to remove it including all of its history) Won't submodules always have a .git directory inside of them? – pedz Aug 28 '13 at 21:16
-
@pedz sorry for the late answer. Did you reproduced that error message? Is it in the case of a nested submodule? (a submodule within a submodule) – VonC Sep 03 '13 at 11:04
-
@pedz @VonC definitely sounds like it's caused by the nested submodule. Could you try editing the script to run `git rm -rf "$submodule_name"` (note the `-r` flag)? If that works, I'll update the script accordingly. – Adam Sharp Sep 03 '13 at 22:44
-
@AdamSharp I removed 'magit' which does not have submodules. Isn't any submodule going to have a .git directory within it? – pedz Sep 07 '13 at 22:09
-
@pedz You're right, it doesn't have any submodules. Yes, if a submodule is initialised and checked out, it should have a .git directory. Which version of Git are you using? – Adam Sharp Sep 08 '13 at 11:15
-
@AdamSharp -- sorry for the slow reply. I'm not getting the emails. I don't know which version. Right now I have 1.8.3.2 and 1.7.12.4. I upgraded recently. I had 1.7.4.1 as well. I don't know which version I used when I did the remove. Wait - I do recall that 1.7.4 did not have git submodule deinit. – pedz Sep 16 '13 at 12:49
-
@pedz yes, `git submodule deinit` is only available from 1.8.3+. Note that, as I mention in my edited answer above, `git rm asubmodule` will soon take care of everything. – VonC Sep 16 '13 at 13:00
-
Running the script left me with a broken project. I tried deleting a submodule and then adding it back, with `git submodule add -b master ..`. I got an error, and couldn't add the submodule back anymore: A git directory for 'asub' is found locally with remote(s): origin url_asub.git If you want to reuse this local git directory instead of cloning again from url_asub.git use the '--force' option. If the local git directory is not the correct repo or you are unsure what this means choose another name with the '--name' option. P.S. This is with git version 1.8.4.msysgit.0 – thor Jan 06 '14 at 23:24
-
@TingL You could have converted your existing submodule to make it follow a branch: http://stackoverflow.com/a/18799234/6309. Or use msysgit 1.8.5.2 (https://code.google.com/p/msysgit/downloads/list?can=3&q=portable&colspec=Filename+Summary+Uploaded+ReleaseDate+Size+DownloadCount): a `git rm yourSubmodule` now removes the submodule from the working tree and the `.gitmodules` files. – VonC Jan 07 '14 at 06:49
-
@TingL I have edited the answer to remove the script, and update the answer to git1.8.5, now available for windows as well with the msysgit 1.8.5.2. – VonC Jan 07 '14 at 06:50
-
note: `deinit` and `rm` seem to work with paths, and it worked well for me with a trailing slash on `asubmodule` with both commands. (git v. 1.9.1) – desseim Mar 26 '14 at 20:26
-
@desseim yes, and that will be true for all commands: http://stackoverflow.com/a/22130978/6309 – VonC Mar 26 '14 at 20:29
-
5In current git (v1.9+), plain old `git rm submodule` does exactly what you want as other people have already said. – Pete Peterson Jun 12 '14 at 17:36
-
My experience a good `git rm -rf --cached /path/to/submodule` removes the submodule. Then `git commit`. If I didn't want the folder added as a submodule, I just remove the `.git` in `path/to/folder` and `git add /path/to/folder`. – aubreypwd Sep 25 '14 at 18:59
-
This leaves `.git/modules/
/` 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. – eonil Oct 24 '14 at 18:33 -
@VonC Is it really fine to delete such internal structures? Doesn't it affect to any structural data integrity? I'm no expert on Git, but I am losing trust on Git more and more as I getting know about how it fragile is... – eonil Oct 24 '14 at 18:43
-
1@Eonil no, in this instance, it is ok, in order to keep it coherent with the deletion of the gitlink entry (http://stackoverflow.com/a/16581096/6309). – VonC Oct 24 '14 at 18:44
-
"git submodule deinit [submodule]" just gives me a usage prompt - syntax incorrect? – Nathan Hornby Feb 06 '15 at 14:09
-
@NathanHornby it depends on your version of Git (`git --version`). It is for git 1.8.3+. If your version is too old, you should be able to upgrade it easily enough (for instance: http://stackoverflow.com/a/24847953/6309) – VonC Feb 06 '15 at 15:37
-
@NathanHornby let me me guess: Ubuntu precise 12.0.4 LTS and Git 1.7.9.5? (http://packages.ubuntu.com/precise/vcs/git, and http://stackoverflow.com/q/14409639/6309). – VonC Feb 06 '15 at 16:00
-
you better change the order of the commands or you'll get (on Windows) an error for `Stopping at 'lib/asubmodule'; script returned non-zero status.` solution: `git rm lib/asubmodule && rm .git/modules/lib/asubmodule && git submodule lib/asubmodule deinit --recursive --force` (if your module is under root, you don't need lib/) – Apr 18 '15 at 04:20
-
1@VonC's answers cover ALL the bases, but if you just need to remove a submodule right now, please see: http://stackoverflow.com/a/21211232/8047 – Dan Rosenstark Apr 20 '16 at 14:13
-
@VonC I'm not sure if this Q and the many answers care about history preservation, i.e. vcs time travel, and instead "just want to delete the damn thing". `rm -rf .git/modules/a/submodule` is irreversible unless all commits in the submodule's repo have been pushed to a remote. (If they have been pushed, can I assume checking out a past commit restores it all? I added https://stackoverflow.com/q/61963342/8910547 to represent the alternate scenario. Or perhaps this Q and your answer can be edited to clarify, in which case I might just delete my new Q as redundant. – Inigo May 22 '20 at 20:55
-
rm -rf .git/modules/a/submodule doesn't work for me. it seems .git is not a directory (but it exists) – openCivilisation Mar 06 '21 at 01:02
-
@nurettin true, but in this case, make sure to use without trailing slash, in order to remove the submodule entry, instead of the submodule folder. – VonC May 16 '21 at 13:07
-
I read your answer a few times, but not sure what you're suggesting to do. Are you suggesting that we just do `git submodule deinit` or follow the steps in the summary? Perhaps you meant to use the word _steps_ instead of _summary_. Additionally while I understand you'r suggesting two ways to do step `3`. I don't understand what `3bis` is. Would you mind making an edit? – mfaani Jan 28 '22 at 22:54
-
1@mfaani I did not suggested those steps 8 years ago when I wrote this. The answer has been since edited 22 times. But yes, follow the summary steps, and chose between 3 and 3bis, the latter being if you want to keep the content of the former submodule in your working tree. – VonC Jan 28 '22 at 23:42
-
Caution! It can damage the git, encounter `error: Could not read ...` – Jeff Tian Oct 11 '22 at 06:35
-
@JeffTian Interesting. I never had that error in this case. What OS and Git version are you using? – VonC Oct 11 '22 at 06:36
-
-
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:
# 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

- 21,412
- 9
- 33
- 48
-
73Why this answer has so few upvotes? All those popular answers miss something, this is the only one that really removes all traces of a submodule, in the simplest possible way. And note: the order of commands matters. – mbdevpl Sep 07 '16 at 06:08
-
Where do you get `-rf` from? I get an error when trying to run that one (the second command; Windows machine) – Thomas Jan 19 '17 at 22:16
-
2To respond to my own question: http://stackoverflow.com/questions/97875/rm-rf-equivalent-for-windows – Thomas Jan 19 '17 at 22:19
-
6@mbdevpl came 3 years after the accepted answer, and I guess no one's managed to convince the OP to accept this one – Andy Feb 20 '17 at 01:58
-
Unfortunately this does not allow for keeping of the files in your working tree (in case you might want to then commit them to your parent repo), nor will `rm -rf` work on Windows. – Simon East Jun 30 '17 at 04:51
-
3@Thomas `rm -rf` just means "delete the entire folder" so you can do that from Explorer GUI in Windows. Alternatively, if you're using git in Windows, you will also have git bash available, so you can run all of these commands there and they will work as they are – Andy Madge Dec 08 '17 at 11:24
-
30
-
12
-
7In 2019 this doesn't work. The last line actually tries to remove from the `.git/modules` folder, which you've already removed in the above line. Adding `--` to the first line like the accepted answer seems to make this work. – Fmstrat Jun 28 '19 at 20:01
-
2@Fmstrat `git v2.20.1` still left `.git/modules/submodule` at my side in place, so the `rm` seems to be needed now or then. If newer `git`s want to remove it, fine, **just swap the last two commands**. Also note that `git deinit` and `git rm` are relatively safe, but **`rm -rf .git/modules/submodule` is dangerous as it might remove the wrong directory**. You can rename and move submodules around, and they only carry the correct path to remove in the `.git` file (and `.git/config`). Also removing the module's copy might be wrong in case you jump around in history. Things are complicated .. – Tino Nov 25 '19 at 09:19
-
The second command should remove `.git/modules/name-of-submodule` instead of the path? Though by default, the name Git assigns to the submodule is the path. – TrebledJ Jan 07 '22 at 03:10
-
1This is the best answer and the only correct one. `rm -rf` part is optional, it's only to clean up your local garbage, does not affect the repo state. – Violet Giraffe Feb 06 '23 at 12:52
Just a note. Since git 1.8.5.2, two commands will do:
git rm -r 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
-
5I'm on git version 2.4.9 (Apple Git-60) and all I had to do was rm the_submodule. I pushed that then re-added a folder named the same as the submodule and it worked without issue. – David Silva Smith Dec 03 '15 at 21:23
-
I'm on git version 2.5.4 on OSX and you only need to do the second command if you want to re-add the submodule from another location. If you don't do the second step you'll see this: A git directory for 'submodule' is found locally with remote(s): – Ed Sykes Feb 11 '16 at 17:40
-
21This does not remove the submodule entry from `.git/config`. See http://stackoverflow.com/a/36593218/1562138 for the complete way to remove a submodule. – fvgs Apr 13 '16 at 08:53
-
@fvgs with git 2.7.4 the `git rm` command DOES remove the section from .git/config, as well as removing the .git/modules/... folder(s) – drevicko Feb 22 '17 at 13:04
-
2@drevicko I just tested this with Git 2.11.1 and I observe the same behavior as before. `git init && git submodule add
&& git rm – fvgs Feb 22 '17 at 16:58` leaves behind the `.git/config` entry and the `.git/modules/ ` directory and its contents. Perhaps you didn't initialize the submodule prior to removing it? -
@fvgs ok, I get the same here with git 2.7.4 when I try your experiment - not sure what happened? The submodule was definitely initialised, had been around a while with multiple changes. – drevicko Feb 27 '17 at 11:13
-
2i feel safer running this first .. git submodule deinit -f the_submodule – danday74 Mar 10 '17 at 04:22
-
Can the answer clarify what `the_submodule` is here? The path to the submodule? – sleep Jul 03 '17 at 00:23
-
It's worth noting that if you never had that submodule initialized in the repository you run these commands on (e.g. you created a fresh, non-recursive clone) you don't need to run the second command or remove the section from the git config, as those elements won't exist. – Adam Burley Feb 27 '18 at 17:36
-
1@danday74 your command is actually needed if the submodule is checked out. otherwise you will get an error `Unlink of file '...' failed` – Adam Burley Feb 28 '18 at 21:38
-
This seemed to work in 2020, and is possibly the most simple, except it does not seem to remove the actual code. which would need `git rm -f path/to/submodule` I think https://stackoverflow.com/a/36593218/2808203 is the better solution. – Darrell Ulm Jun 17 '20 at 20:50
-
Simple steps
- Remove config entries:
git config -f .git/config --remove-section submodule.$submodulename
git config -f .gitmodules --remove-section submodule.$submodulename
- Remove directory from index:
git rm --cached $submodulepath
- Commit
- Delete unused files:
rm -rf $submodulepath
rm -rf .git/modules/$submodulename
Please note: $submodulepath
doesn't contain leading or trailing slashes.
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
.
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 HEAD
first and git commit
at the end, if you put this in a script.
Also have a look at an answer to Can I unpopulate a Git submodule?.

- 16,941
- 11
- 79
- 125

- 6,716
- 6
- 41
- 54
-
1I had a lot of submodules (and a bigger mess) so I had to pass them through a for loop. Since most of them where under a specific directory and ls output contained trailing slashes. I did something like `for dir in directory/*; do git rm --cached $dir; done`. – Pablo Olmos de Aguilera C. Oct 09 '11 at 20:50
-
To get this the list which can be used in script for recursive deletion - `git config -f .git/config -l | cut -d'=' -f1 | grep "submodule.$MODPATH" | sed 's/^submodule\.//' | sed 's/\.url$//'` - - looks like you have to really do this in case if there is something messed up, otherwise just `git submodule | grep -v '^+' | cut -d' ' -f3` – errordeveloper Oct 12 '11 at 00:43
-
2to get the list of modules where no local changes had been made - `git submodule | grep '^+' | cut -d' ' -f2` – errordeveloper Oct 12 '11 at 01:01
-
note, I had to include `submodulename` in double quotes `"submodulename"` .. referring the `.git/config` file – muon Jul 20 '17 at 15:22
-
1Simple. Efficient. In 2.25.0, after the step 1, you need to stage .gitmodules changes before step 2. – Michel Donais Feb 05 '20 at 14:56
To remove a submodule added using:
REPOSITORY=blah@blah.com:repos/blah.git
MOD_DIR=lib/blah
git submodule add $REPOSITORY $MOD_DIR
Run:
git rm $MOD_DIR
That's it.
For old versions of git (circa ~1.8.5, actually even in 2.26.2) use:
git submodule deinit $MOD_DIR
git rm $MOD_DIR
git config -f .gitmodules --remove-section submodule.$MOD_DIR
-
2+1 indeed. This is the only correct answer from git 1.8.3 onwards. Should be accepted as the correct one. – Xananax Jul 02 '14 at 18:26
-
15
-
1@RudolfAdamkovic it works for me? Notice it only removes the submodule entry if the exact path matches; if you've moved a submodule and then use `git rm` it doesn't; A quick test with 2.5.4 on my mac updates the .gitmodules file, as described in the documentation here: https://git-scm.com/docs/git-rm#_submodules ... but if you have found some kind of combination of platform / version where this doesn't happen, you should probably lodge a bug about it. – Doug Jan 02 '16 at 15:48
-
5This answer is not entirely correct. `git rm` leaves stuff in `.git/modules/` dir and `.git/config` file (ubuntu, git 2.7.4). Other answer works 100%: http://stackoverflow.com/a/36593218/4973698 – mbdevpl Sep 07 '16 at 06:03
-
1Will deinit remove the submodule but leave the files? I want it to remove all of the remnants in git but leave the actual folder in place. – justin.m.chase Nov 03 '21 at 19:08
-
@justin.m.chase It looks like git rm --cached $MOD_DIR will leave the files in place but you'll have to manually remove the .gitmodules entry. – Fredrick Aug 19 '22 at 14:28
-
Doesn't work. Accidentally typed the wrong URL and I can't get rid of it any more. `git submodule delete --force` desperately needed. – Martin Oct 02 '22 at 18:48
In addition to the recommendations, I also had to rm -Rf .git/modules/path/to/submodule
to be able to add a new submodule with the same name (in my case I was replacing a fork with the original)

- 3,810
- 7
- 32
- 51

- 1,202
- 10
- 8
-
1I was having troubles with this as well. If you try to reinstall a submodule to the same path, it keeps the branch info cached in the location you mentioned which messes things up. – jangosteve Mar 05 '12 at 22:27
-
Thanks, I needed this too. @Anton, I agree, and I've edited the topvoted answer to add this info. – William Denniss Sep 23 '12 at 15:17
-
I used the --name option to make the replace work... see http://stackoverflow.com/questions/14404704/how-do-i-replace-a-git-submodule-with-another-repo – joseph.hainline Jan 18 '13 at 18:06
You must remove the entry in .gitmodules
and .git/config
, and remove the directory of the module from the history:
git rm --cached path/to/submodule
If you'll write on git's mailing list probably someone will do a shell script for you.

- 2,749
- 20
- 21
-
There is no need for any shell script, other answer has commands for removing all traces of a submodule: http://stackoverflow.com/a/36593218/4973698 – mbdevpl Sep 07 '16 at 06:06
I found deinit
works good for me:
git submodule deinit <submodule-name>
git rm <submodule-name>
From git docs:
deinit
Unregister the given submodules, i.e. remove the whole
submodule.$name
section from .git/config together with their work tree.

- 1
- 1

- 31,277
- 10
- 71
- 76
-
-
1it did not remove .git/modules/.. . You should remove them, see the answer by @fvgs – Vilém Kurz Oct 01 '18 at 13:40
-
-
1AFAICS this seems to be the **most safest answer for newer `git`s** which know of `deinit`, as [the other answer](https://stackoverflow.com/a/36593218/490291) removes the `.git/modules/submodule` directory too early, which seems to make newer `git`s to fail now or then. Also (see my comment there) removing `.git/modules/submodule` might be the wrong path, so this is a dangerous step, best taken later only when `git` complains (or if you are 299% sure this what you want, is the correct path and really needed). – Tino Nov 25 '19 at 09:42
-
I also needed `git commit` to commit staged changes in working dir: `modified .gitmodules` and `deleted
`. – Yuri Pozniak Feb 19 '20 at 01:01 -
As of git 2.31.0, if you later add another submodule at same path, git will happily not update .git/modules/submodule/config with the new submodule's repository path (nor warn) so a future git push/pull will not work. That's when you need to remove .git/modules/submodule before doing the add again. – Case Larsen Sep 30 '21 at 19:54
You can use an alias to automate the solutions provided by others:
[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"
Put that in your git config, and then you can do: git rms path/to/submodule

- 6,199
- 6
- 50
- 66
-
-1 as this is plain too wrong. FIRST: This assumes that the submodule's name and path are identical **which is most often not the case**. I.E. `git clone https://github.com/hilbix/empty.git; cd empty; git submodule add https://github.com/hilbix/empty.git one; git mv one two; git rms two`. SECOND: You must execute this from the correct path. `git` aliases should work anywhere in the worktree (or fail gracefully). THIRD: `git config -f .git/config` fails within submodules, as `.git` usually is a file there. – Tino Nov 25 '19 at 09:31
To summarize, this is what you should do :
Set
path_to_submodule
var (no trailing slash):path_to_submodule=path/to/submodule
Delete the relevant line from the .gitmodules file:
git config -f .gitmodules --remove-section submodule.$path_to_submodule
Delete the relevant section from .git/config
git config -f .git/config --remove-section submodule.$path_to_submodule
Unstage and remove $path_to_submodule only from the index (to prevent losing information)
git rm --cached $path_to_submodule
Track changes made to .gitmodules
git add .gitmodules
Commit the superproject
git commit -m "Remove submodule submodule_name"
Delete the now untracked submodule files
rm -rf $path_to_submodule
rm -rf .git/modules/$path_to_submodule

- 3,810
- 7
- 32
- 51

- 1,740
- 19
- 14
-
so everyone else who pulls down my change will have to run rm -rf $path_to_submodule rm -rf .git/modules/$path_to_submodule to remove the submodule cache ? – j2emanue Apr 24 '15 at 15:09
-
I recommend to update, `git submodule update`. And if the submodules paths weren't updated correctly (git throws an error), remove them: `rm -rf .git/modules/
&& rm -rf – luissquall Apr 29 '15 at 00:22&& git submodule update`
If the submodule was accidentally added because you added, committed and pushed a folder that was already a Git repository (contained .git
), you won’t have a .gitmodules
file to edit, or anything in .git/config
. In this case all you need is :
git rm --cached subfolder
git add subfolder
git commit -m "Enter message here"
git push
FWIW, I also removed the .git
folder before doing the git add
.

- 3,810
- 7
- 32
- 51

- 2,600
- 22
- 16
git submodule deinit <path to submodule>
- Remove the section from
.gitmodules
git rm <path to submodule>
- Delete the module files which you need to remove from your project.
- Add the deleted files to git and call
git add .gitmodules
- Commit and Push

- 18,150
- 39
- 158
- 271
-
24For me it was enough to call `git submodule deinit
` and `git rm – Dmytro Ovdiienko May 05 '20 at 20:42`. Last command automatically deletes the entry inside the `.gitmodules`. Git 2.17 -
After experimenting with all the different answers on this site, I ended up with this solution:
#!/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
This restores the exact same state as before you added the submodule. You can right away add the submodule again, which was not possible with most of the answers here.
git submodule add $giturl test
aboveScript test
This leaves you with a clean checkout with no changes to commit.
This was tested with:
$ git --version
git version 1.9.3 (Apple Git-50)

- 57,263
- 20
- 190
- 175
-
Why do you use `git rm --cached $path` then `rm -rf $path` instead of `git rm -r $path`? – bfontaine Nov 29 '14 at 15:00
-
2-1 Does not work if you try to remove a submodule within a submodule (submodule can form trees!). Also **this is dangerously buggy** due to missing quoting! Example `git submodule add https://github.com/hilbix/empty.git 'dangerous .. submodule'` -> when you try to remove 'dangerous .. submodule' with your script, this will `rm -rf ..` which is most likely not what you want .. – Tino Nov 25 '19 at 09:49
What I'm currently doing Dec 2012 (combines most of these answers):
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}"

- 7,540
- 4
- 29
- 34
I recently find out a git project which include many useful git related command: https://github.com/visionmedia/git-extras
Install it and type :
git-delete-submodule submodule
Then things are done. The submodule directory will be removed from your repo and still exist in your filesystem. You can then commit the change like: git commit -am "Remove the submodule"
.

- 3,810
- 7
- 32
- 51

- 1,773
- 1
- 17
- 27
-
You can call this as `git delete-submodule`, as `git-extras` needs to be in the path to work. Also note that **I recommend to not use `git-extras`**, as many parts of it are **extremely buggy and dangerous**. I.E. `git-delete-submodule` possibly removes the wrong path below `.git/modules/*`, as it assumes that the module and the path are identical (which is quite often not the case), and it does not work correctly if you try to remove a submodule within a submodule. `git-extras` might be 99% helpful, but please do not complain if things utterly go wrong using it. **YOU HAVE BEEN WARNED!** – Tino Nov 25 '19 at 10:03
-
For saving time use this commands `apt install git-extras && git delete-submodule submodule`. @Chien-Wei Huang has extra `-` in post – Machinexa Sep 02 '21 at 17:20
Here is what I did :
1.) Delete the relevant section from the .gitmodules file. You can use below command:
git config -f .gitmodules --remove-section "submodule.submodule_name"
2.) Stage the .gitmodules
changes
git add .gitmodules
3.) Delete the relevant section from .git/config
. You can use below command:
git submodule deinit -f "submodule_name"
4.) Remove the gitlink (no trailing slash):
git rm --cached path_to_submodule
5.) Cleanup the .git/modules
:
rm -rf .git/modules/path_to_submodule
6.) Commit:
git commit -m "Removed submodule <name>"
7.) Delete the now untracked submodule files
rm -rf path_to_submodule

- 3,810
- 7
- 32
- 51

- 2,237
- 1
- 26
- 25
-
1Thanks for this. For me, I had to rearrange the first three steps' order to 3), 1), 2). Doing 1) first gave `fatal: no submodule mapping found in .gitmodules for path 'submodule_name'` at step 3. Both steps were necessary though. (git v2.8.2) – U007D Aug 25 '16 at 00:16
All the answers look outdated. I am using git version 2.28.0
. One line answer is,
git rm path-to-submodule
However, even though the submodule is removed from source control, .git/modules/path-to-submodule still contains the submodule repository and .git/config contains its URL, so you still have to remove those manually:
git config --remove-section submodule.path-to-submodule
rm -rf .git/modules/path-to-submodule
Sometimes, you have to use the -f
flag:
$ git rm -f img2vec
For example, because you might get an error like this:
$ git rm img2vec/
error: the following file has changes staged in the index:
img2vec
(use --cached to keep the file, or -f to force removal)

- 34,860
- 64
- 239
- 408

- 2,129
- 1
- 17
- 41
-
Outdated? [My answer](https://stackoverflow.com/a/16162000/6309) does mention the `git rm` option and the associated config change. – VonC Oct 29 '21 at 09:05
-
Since this the top & most recent answer, you should update it with the following steps as well: 1. Remove the `.gitmodules` file. 2. Remove relevant data from the index as well by invoking the `git rm --cached -r
` – Jarmos Nov 10 '21 at 10:19
For the benefit of the reader, this here tries to sum it up and give a step-by-step guide on how to do it if things do not work as expected. Following is the tested and safe way for git
version 2.17
and above to get rid of a submodule:
submodule="path/to/sub" # no trailing slash!
git submodule deinit -- "$submodule"
git rm -- "$submodule"
- If this does not work for you, see below.
- No options. Nothing dangerous. And do not even consider doing more!
- Tested with Debian Buster
2.20.1
and Ubuntu 18.042.17.1
. "$submodule"
is just to emphasize where to put the name, and that you have to be careful with spaces and the like- If on Windows ignore the first line and replace
"$submodule"
with the Windows way of a properly specified path to the submodule. (I am not Windows)
Warning!
Never touch the insides of the
.git
directory yourself! Editing inside.git
enters the dark side. Stay away at all cost!And yes, you can blame
git
for this, as many handy things were missing ingit
in the past. Like a proper way to remove submodules again.I think there is a very dangerous part in the documentation of
git submodule
. It recommends to remove$GIT_DIR/modules/<name>/
yourself. In my understanding this is not only plain wrong, it is extremely dangerous and provokes major headaches in future! See below.
Note that
git module deinit
is the direct inverse to
git module init
but
git submodule deinit -- module
git rm -- module
also is quite the inverse to
git submodule add -- URL module
git submodule update --init --recursive -- module
because some commands basically need to do more than just a single thing:
git submodule deinit -- module
- (1) updates
.git/config
- (1) updates
git rm
- (2) removes the files of the module
- (3) thereby recursively removes the submodules of the submodule
- (4) updates
.gitmodules
git submodule add
- pulls in the data to
.git/modules/NAME/
- (1) does
git submodule init
, so updates.git/config
- (2) does
git submodule update
, so, nonrecursively checks out the module - (4) updates
.gitmodules
- pulls in the data to
git submodule update --init --recursive -- module
- pulls in further data if needed
- (3) checks out the submodules of the submodule recursively
This cannot be fully symmetric, as keeping it strictly symmetric does not make much sense. There simply is no need for more than two commands. Also "pulling in the data" is implicit, because you need it, but removing the cached information is not done, because this is not needed at all and might wipe precious data.
This truly is puzzling to newcomers, but basically is a good thing: git
just does the obviously thing and does that right, and does not even try to do more. git
is a tool, which must do a reliable job, instead of being just another "Eierlegende Wollmilchsau" ("Eierlegende Wollmilchsau" translates for me to "some evil version of a Swiss army knife").
So I understand complaints of people, saying "Why doesn't do git
the obvious thing for me". This is because "obvious" here depends from the point of view. Reliability in each and every situation is far more important. Hence what's obvious for you often is not the right thing in all possible technical situations. Please remember that: AFAICS git
follows the technical path, not the social one. (Hence the clever name: git)
If this fails
The commands above may fail due to following:
- Your
git
is too old. Then use a newergit
. (See below how to.) - You have uncommitted data and might lose data. Then better commit them first.
- Your submodule is not clean in a
git clean
sense. Then first clean your submodule using that command. (See below.) - You have done something in the past which is unsupported by
git
. Then you are on the dark side and things get ugly and complicated. (Perhaps using another machine fixes it.) - Perhaps there are more ways to fail I am not aware of (I am just some
git
power-user.)
Possible fixes follow.
Use a newer git
If your machine is too old there is no submodule deinit
in your git
. If you do not want (or can) update your git
, then just use another machine with a newer git
! git
is meant to be fully distributed, so you can use another git
to get the job done:
workhorse:~/path/to/worktree$ git status --porcelain
must not output anything! If it does, cleanup things first!workhorse:~/path/to/worktree$ ssh account@othermachine
othermachine:~$ git clone --recursive me@workhorse path/to/worktree/.git TMPWORK && cd TMPWORK
- Now do the submodule stuff
othermachine:~/TMPWORK$ git commit . -m . && exit
workhorse:~/path/to/worktree$ git fetch account@othermachine:TMPWORK/.git
workhorse:~/path/to/worktree$ git merge --ff-only FETCH_HEAD
. If this does not work, usegit reset --soft FETCH_HEAD
- Now cleanup things, until
git status
is clean again. You are able to do so, because you have had it clean before, thanks to the first step.
This othermachine
can be some VM, or some Ubuntu WSL under Windows, whatever. Even a chroot
(but I assume that you are non-root, because if you are root
it should be more easy to update to the newer git
).
Note that if you cannot ssh
in, there are trainloads of ways to transport git
repositories. You can copy your worktree on some USB stick (including the .git
directory), and clone from the stick. Clone the copy, just to get things in a clean fashion again. This might be a PITA, in case your submodules are not accessible from othermachine directly. But there is a solution for this, too:
git config --add url.NEWURLPREFIX.insteadOf ORIGINALURLPREFIX
You can use this multiply, and this is saved into $HOME/.gitconfig
. Something like
git config --add 'url./mnt/usb/repo/.insteadof' https://github.com/
rewrites URLs like
https://github.com/XXX/YYY.git
into
/mnt/usb/repo/XXX/YYY.git
It's easy if you start to become accustomed to powerful git
features like this.
Cleanup things first
Cleaning manually up is good, because this way you perhaps detect some things you forgot about.
- If git complains about unsaved stuff, commit and push it somewhere safe.
- If git complains about some leftovers,
git status
andgit clean -ixfd
is your friend - Try to abstain from options to
rm
anddeinit
as long as you can. Options (like-f
) forgit
are good if you are a Pro. But as you came here, you probably are not so experienced in thesubmodule
area. So better be safe than sorry.
Example:
$ git status --porcelain
M two
$ git submodule deinit two
error: the following file has local modifications:
two
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'two' contains local modifications; use '-f' to discard them
$ cd two
$ git submodule deinit --all
error: the following file has local modifications:
md5chk
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'md5chk' contains local modifications; use '-f' to discard them
$ cd md5chk
$ git submodule deinit --all
error: the following file has local modifications:
tino
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'tino' contains local modifications; use '-f' to discard them
$ cd tino
$ git status --porcelain
?? NEW
$ git clean -i -f -d
Would remove the following item:
NEW
*** Commands ***
1: clean 2: filter by pattern 3: select by numbers 4: ask each
5: quit 6: help
What now> 1
Removing NEW
$ cd ../../..
$ git status --porcelain
$ git submodule deinit two
Cleared directory 'two'
Submodule 'someunusedname' (https://github.com/hilbix/src.git) unregistered for path 'two'
You see, there is no -f
needed on submodule deinit
. If things are clean, in a git clean
sense. Also note that git clean -x
is not needed. This means git submodule deinit
unconditionally removes untracked files which are ignored. This is usually what you want, but do not forget about it. Sometimes ignored files might be precious, like cached data which takes hours to days to be calculated again.
Why never remove $GIT_DIR/modules/<name>/
?
Probably people want to remove the cached repository, because they are afraid to run into a problem later. This is true, but running into that "problem" is the correct way to solve it! Because the fix is easy, and done right you will be able to live happily ever after. This avoids more cumbersome trouble than when you remove the data yourself.
Example:
mkdir tmptest &&
cd tmptest &&
git init &&
git submodule add https://github.com/hilbix/empty.git two &&
git commit -m . &&
git submodule deinit two &&
git rm two &&
git commit -m . &&
git submodule add https://github.com/hilbix/src.git two
The last line outputs following error:
A git directory for 'two' is found locally with remote(s):
origin https://github.com/hilbix/empty.git
If you want to reuse this local git directory instead of cloning again from
https://github.com/hilbix/src.git
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.
Why this error? Because .git/modules/two/
previously was populated from https://github.com/hilbix/empty.git and now shall be re-populated from something else, namely https://github.com/hilbix/src.git. You won't see this if you re-populate it from https://github.com/hilbix/empty.git
What to do now? Well, just do exactly as told! Use --name someunusedname
git submodule add --name someunusedname https://github.com/hilbix/src.git two
.gitmodules
then looks like
[submodule "someunusedname"]
path = two
url = https://github.com/hilbix/src.git
ls -1p .git/modules/
gives
someunusedname/
two/
This way in future you can switch branches/commit forward and backward and will never get into any trouble again, due to two/
having two different (and possibly incompatible) upstream repositories. And the best is: You keep both cached locally, too.
- This is not only true for you. It also is true for all others using your repository.
- And you do not lose history. In case you forgot to push the very latest version of the old submodule, you can enter the local copy and do so later on. Note that it is quite common that somebody forgets to push some submodules (because this is a PITA for newcomers, until they became accustomed to
git
).
However if you removed the cached directory, both different checkouts will stumble upon each other, because you will not use the --name
options, right? So each time you do the checkout you perhaps have to remove the .git/modules/<module>/
directory again and again. This is extremely cumbersome and makes it hard to use something like git bisect
.
So there is a very technical reason to keep this module directory as a placeholder. People who recommend to remove something below .git/modules/
either do not know better or forget to tell you that this makes powerful features like git bisect
nearly impossible to use if this crosses such a submodule incompatibility.
A further reason is shown above. Look at the ls
. What do you see there?
Well, the 2nd variant of module two/
is not under .git/modules/two/
, it is under .git/modules/someunusedname/
! So things like git rm $module; rm -f .git/module/$module
are totally wrong! You must either consult module/.git
or .gitmodules
to find the right thing to remove!
So not only most other answers fall into this dangerous trap, even very popular git
extensions had this bug (it's now fixed there)! So better keep your hands of the .git/
directory if you do not exactly, what you are doing!
And from the philosophical view, wiping history is always wrong! Except for quantum mechanics, as usual, but this is something completely different.
FYI you probably guessed it: hilbix is my GitHub account.

- 9,583
- 5
- 55
- 60
-
This encyclopedia of a post should be broken up into clearer sections with bigger/clearer sub headings to indicate the actual answer, and the different "troubleshooting"/etc sections. – Andrew Jan 19 '20 at 19:17
-
-
Great answer with gotchas I am certain to have learned about the hard way. Highly recommend everyone at least speed reads it. – goldfishalpha Feb 07 '23 at 11:01
I had to take John Douthat's steps one step further and cd
into the submodule's directory, and then remove the Git repository:
cd submodule
rm -fr .git
Then I could commit the files as a part of the parent Git repository without the old reference to a submodule.

- 30,738
- 21
- 105
- 131

- 38,547
- 26
- 130
- 141
-
I had to do this too in order to get past a "fatal: Not a git repository:" error when trying to do the `git rm --cache` step. – RickDT Apr 01 '13 at 15:48
Here are the 4 steps that I found necessary or useful (important ones first):
git rm -f the_submodule
rm -rf .git/modules/the_submodule
git config -f .git/config --remove-section submodule.the_submodule
git commit -m "..."
In theory, git rm
in step 1 should take care of it. Hopefully, the second part of OP question can be answered positively one day (that this can be done in one command).
But as of July 2017, step 2 is necessary to remove data in .git/modules/
for otherwise, you can't e.g. add the submodule back in the future.
You can probably get away with the above two steps for git 1.8.5+ as tinlyx's answer noted, as all git submodule
commands seem to work.
Step 3 removes the section for the_submodule
in the file .git/config
. This should be done for completeness. (The entry may cause problems for older git versions, but I don't have one to test).
For this, most answers suggest using git submodule deinit
. I find it more explicit and less confusing to use git config -f .git/config --remove-section
. According to the git-submodule documentation, 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.
Last but not least, if you don't git commit
, you will/may get an error when doing git submodule summary
(as of git 2.7):
fatal: Not a git repository: 'the_submodule/.git'
* the_submodule 73f0d1d...0000000:
This is regardless of whether you do steps 2 or 3.

- 1,388
- 13
- 14
With git v2.7.4 simple 3 steps worked just fine.
git submodule deinit -f -- a/submodule
git rm -f a/submodule
git commit

- 667
- 7
- 11
The best way to remove a submodule from git:
$ git submodule deinit -f <submodule-name>
$ rm -rf .git/modules/<submodule-name>
$ git config -f .gitmodules --remove-section submodule.<submodule-name>
$ git config -f .git/config --remove-section submodule.<submodule-name>
$ git rm --cached <submodule-name>
$ git commit -m 'rm submodule: <submodule-name>'

- 917
- 1
- 9
- 16
I just found the .submodule (forgot exact name) hidden file, it has a list... you can erase them individually that way. I just had one, so I deleted it. Simple, but it might mess up Git, since I don't know if anything's attached to the submodule. Seems ok so far, aside from libetpan's usual upgrade issue, but that's (hopefully) unrelated.
Noticed nobody posted manual erasing, so added
With git 2.17 and above it's just:
git submodule deinit -f {module_name}
git add {module_name}
git commit

- 2,219
- 5
- 22
- 30
-
Did not work, neither for `git 2.17.1` nor `git 2.20.1`. However using `git rm` instead of `git add` worked for both. Notes: **`-f` is not needed** if things are clean. Be sure to **never use options** with `git` if you want to protect against unintended data loss. Also note that this leaves `.git/modules/{module_name}` in place. **It is best practice to keep it there** because `git` prints the correct(!) help how to proceed if something is blocked due to this. – Tino Nov 25 '19 at 10:37
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
I followed the instructions from this very same guide How do I remove a submodule?
$ git submodule deinit -f <submodule-name>
$ rm -rf .git/modules/<submodule-name>
$ git config -f .gitmodules --remove-section submodule.<submodule-name>
$ git config -f .git/config --remove-section submodule.<submodule-name>
$ git rm --cached <submodule-name>
$ git commit -m 'rm submodule: <submodule-name>'
But it kept saying:
fatal: no submodule mapping found in .gitmodules for path
So what I did is including the path in .gitignore like this (With no asterisk in the end of the path):
<path>
Then I modified any file and did a simple push:
$ git add .
$ git commit -m "Ignoring sharedlibs folder <path> on .gitignore"
$ git push -u origin master

- 101
- 2
- 5
If you have just added the submodule, and for example, you simply added the wrong submodule or you added it to the wrong place, simply do git stash
then delete the folder. This is assuming that adding the submodule is the only thing you did in the recent repo.

- 7,299
- 14
- 58
- 96
To summarize, this is what you should do :
Set path_to_submodule var (no trailing slash):
path_to_submodule=path/to/submodule
Delete the relevant line from the .gitmodules file:
git config -f .gitmodules --remove-section submodule.$path_to_submodule
Delete the relevant section from .git/config
git config -f .git/config --remove-section submodule.$path_to_submodule
Unstage and remove $path_to_submodule only from the index (to prevent losing information)
git rm --cached $path_to_submodule
Track changes made to .gitmodules
git add .gitmodules
Commit the superproject
git commit -m "Remove submodule submodule_name"
Delete the now untracked submodule files
rm -rf $path_to_submodule
rm -rf .git/modules/$path_to_submodule
See also : Alternative guide lines

- 345
- 6
- 19
-
Can you please extend this with how to remove a submodule following a 'git submodule add' but without having ever committed it? I assume that in that case no commit is needed to remove the submodule, right? – Carlo Wood Jan 03 '20 at 11:43
-
2I think you need to swap the `git rm --cached $path_to_submodule` and `git add .gitmodules` no? I did get an error on the first command: `fatal: Please stage your changes to .gitmodules or stash them to proceed` because I had unstaged changes to `.gitmodules`. Doing the `git add .gitmodules` first solves that. – Carlo Wood Jan 03 '20 at 11:49
This worked for me. The above answers were showing this in the terminal and nothing else was happening
'fatal: not removing 'demolibapp' recursively without -r'
- demolibapp is my submodule name that I want to remove
- git submodule deinit demolibapp
- git rm --cached demolibapp -r
- rm -rf .git/modules/demolibapp
- git add --all
- git commit -m "removing extra submodules"
- git push
- rm -rf demolibapp

- 726
- 1
- 7
- 17
If you want to remove the submodule without deleting the folder from your local file system here is what worked for me:
MOD=example
git rm --cached -f apps/$MOD
git config -f .gitmodules --remove-section submodule.$MOD

- 13,061
- 8
- 52
- 100
I've created a bash script to ease the removal process. It also checks whether there are changes in the repo left unsaved and asks for confirmation.
It has been tested on os x
would be interesting to know if it works as is on common linux distros as well:
https://gist.github.com/fabifrank/cdc7e67fd194333760b060835ac0172f

- 3,506
- 3
- 18
- 28
A simple solution using Magit
If you use Magit under Emacs you can proceed as follows:
Go to your project root, then
M-x
, magit-list-submodules
then
M-x
, magit-submodule-remove
You will be asked which submodule you want to remove.
That's it!
(My Magit version is v3.3.0)

- 10,518
- 5
- 31
- 70
In case you need to do it in one line command with bash script as below:
$ cd /path/to/your/repo && /bin/bash $HOME/remove_submodule.sh /path/to/the/submodule
Create bash script file in the $HOME
dir named i.e. remove_submodule.sh
:
#!/bin/bash
git config -f .gitmodules --remove-section submodule.$1
git config -f .git/config --remove-section submodule.$1
git rm --cached $1
git add .gitmodules
git commit -m "Remove submodule in $1"
rm -rf $1
rm -rf .git/modules/$1
git push origin $(git rev-parse --abbrev-ref HEAD) --force --quiet

- 9,880
- 3
- 65
- 77
- A submodule can be deleted by running
git rm <submodule path> && git commit
. This can be undone usinggit revert
.- The deletion removes the superproject's tracking data, which are both the gitlink entry and the section in the
.gitmodules
file. - The submodule's working directory is removed from the file system, but the Git directory is kept around as it to make it possible to checkout past commits without requiring fetching from another repository.
- The deletion removes the superproject's tracking data, which are both the gitlink entry and the section in the
- To completely remove a submodule, additionally manually delete
$GIT_DIR/modules/<name>/
.
Source: git help submodules

- 5,885
- 2
- 19
- 28
-
Good explanation for the fact that git doesn't remove the internal data, so we can see that this is a feature, not a bug. – Wolf Jul 20 '23 at 14:21
In latest git just 4 operation is needed to remove the git submodule.
- Remove corresponding entry in
.gitmodules
- Stage changes
git add .gitmodules
- Remove the submodule directory
git rm --cached <path_to_submodule>
- Commit it
git commit -m "Removed submodule xxx"

- 12,790
- 16
- 88
- 100
Removing git submodule
To remove a git
submodule below 4 steps are needed.
- Remove the corresponding entry in
.gitmodules
file. Entry might be like mentioned below
[submodule "path_to_submodule"]
path = path_to_submodule
url = url_path_to_submodule
- Stage changes
git add .gitmodules
- Remove the submodule directory
git rm --cached <path_to_submodule>
. - Commit it
git commit -m "Removed submodule xxx"
and push.
Additional 2 more steps mentioned below are needed to clean submodule completely in local cloned copy.
- Remove the corresponding entry in
.git/config
file. Entry might be like mentioned below
[submodule "path_to_submodule"]
url = url_path_to_submodule
- Do
rm -rf .git/modules/path_to_submodule
These 5th and 6th steps does not creates any changes which needs commit.

- 12,790
- 16
- 88
- 100
-
1It would be much easier if you would use `git submodule deinit` https://git-scm.com/docs/git-submodule#Documentation/git-submodule.txt-deinit-f--force--all--ltpathgt82308203 – Black Jan 31 '20 at 10:11