110

How do I replace a git submodule with a different git repo?

Specifically, I have a submodule:

  • located at ./ExternalFrameworks/TestFramework that points to a git repo git@github.com:userA/TestFramework.git
  • I'd like it to now point to git@github.com:userB/TestFramework.git.

The problem is that when I delete the submodule with the method described here, then re-add it using the command

git submodule add git@github.com:userB/TestFramework.git

I get this error:

A git directory for 'ExternalFrameworks/TestFramework' is found locally with remote(s):
  origin    git@github.com:userA/TestFramework.git
If you want to reuse this local git directory instead of cloning again from
  git@github.com:userB/TestFramework.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.
Community
  • 1
  • 1
joseph.hainline
  • 24,829
  • 18
  • 53
  • 70
  • 1
    possible duplicate of [Changing remote repository for a git submodule](http://stackoverflow.com/questions/913701/changing-remote-repository-for-a-git-submodule) – jiyinyiyong Jan 09 '14 at 06:34

6 Answers6

143

If the location (URL) of the submodule has changed, then you can simply:

  1. Modify the .gitmodules file in the repo root to use the new URL.
  2. Delete the submodule folder in the repo rm -rf .git/modules/<submodule>.
  3. Delete the submodule folder in the working directory rm -rf <submodule>.
  4. Run git submodule sync.
  5. Run git submodule update.

More complete info can be found elsewhere:

Tim Henigan
  • 60,452
  • 11
  • 85
  • 78
  • 5
    Also worth noting: when another user (who had already inited the submodule) gets your update, they will also have to do the "git submodule sync" one time before the new submodule will work for them. – joseph.hainline Feb 21 '13 at 03:20
  • 3
    This did not work for me. My submodule still pointed to the old URL after this. Any ideas why? – Arne Nov 22 '13 at 15:55
  • 34
    @Arne Maybe your submodule was never initialized properly. I had to `rm -rf .git/modules/` before it worked for me. – David Braun Dec 07 '13 at 17:48
  • @DavidBraun I have the same problem as @Arne though doing `git submodule sync` after `rm -rf .git/modules/` gives `fatal: Not a git repository: ../.git/modules/`. Any tips? I initially created the submodule via `git submodule add https://` as per the git docs... – acannon828 Sep 29 '14 at 19:44
  • @acannon828 I don't have any tips; I'm too far away from the problem now. Best of luck. – David Braun Sep 30 '14 at 00:28
  • @acannon828 git is trying to find an inexistent path (`.git/modules/.`). Remove the corresponding path and update: `rm -rf && git submodule update` – luissquall Oct 08 '14 at 17:56
  • 2
    Afterwards I had to cd to the module's directory, git checkout the branch I want, then git pull. – Nicolas Raoul Dec 11 '14 at 03:10
  • This is good only if the only thing changed is the URL from which you bring your submodule repository. However the original question was about replacing the git repository of the submodule. For example, I used a github project as my submodule. I found a bug there, but the repo is not active. So I have to fork it, and apply the fix on my own fork - which is now a different repository. Your method won't work for me, – Motti Shneor Jan 17 '16 at 19:26
  • 1
    I get `error: Server does not allow request for unadvertised object 6ed9043bcb3bf7269bba3e60f2bb59b403a7cb13` and `Fetched in submodule path 'app/code/Magenerds/PageDesigner', but it did not contain 6ed9043bcb3bf7269bba3e60f2bb59b403a7cb13. Direct fetching of that commit failed.` – Black Jan 31 '20 at 16:54
  • I had to run `git submodule update --remote` for this to work. – Farzan Mar 11 '22 at 04:17
37

First, delete the current submodule with the method already mentioned here, which I'm including for convenience:

  • Delete the relevant section from the .gitmodules file
  • Delete the relevant section from .git/config
  • Run git rm --cached path_to_submodule (no trailing slash)
  • Commit and delete the now untracked submodule files

Now, add the new submodule with the --name flag. This will give git an alternate name to reference in .git/config for the submodule, to deconflict with the submodule that was there historically, which you still want to work in your prior history.

So type:

git submodule add --name UpdatedTestFramework git@github.com:userB/TestFramework.git

and you'll get the submodule loaded at the path you expect.

Community
  • 1
  • 1
joseph.hainline
  • 24,829
  • 18
  • 53
  • 70
  • 2
    While this way does work, it's not nearly as clean as Tim's method. – joseph.hainline Jan 29 '13 at 05:04
  • 4
    This worked for me but I also had to delete `.git/modules/`. – Nate Jul 21 '14 at 15:19
  • 1
    Appreciate the reference to `--name`. I wasn't aware of the issues surrounding this, and I wasn't able to replace a submodule until I made use of this option (thanks to your answer). – aknuds1 Jan 03 '15 at 20:29
  • This eneded up being the only method that worked for me, however I wanted to keep the same directory name. It did checkout correct path and make the module name the desired name but the working directory name was the new repo name. So If you want the same name you need to also specify that at the end of the url like so: `git submodule add --name old-name-to-keep git@github.com:userB/new-repository.git old-name-to-keep` – rgb Oct 25 '16 at 22:53
10

These commands will do the work on command prompt without altering any files on local repository.

git config --file=.gitmodules submodule.Submod.url https://github.com/username/ABC.git
git config --file=.gitmodules submodule.Submod.branch Dev
git submodule sync
git submodule update --init --recursive --remote
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Pavan Sokke Nagaraj
  • 2,385
  • 1
  • 14
  • 21
5

What fixed this for me was in the root of your git repo (not the submodule), run

rm -rf .git/modules/yourmodule

Then you should be able to add as normal.

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
hobberwickey
  • 6,118
  • 4
  • 28
  • 29
3

The easiest way that I found is this:

git rm -rf [submodule_dir]
git submodule add --name new_[submodule_name] [new_submodule_url] [submodule_dir]

I didn't like the idea to modify my .gitmodules manually. I also wrote a little blogpost about it.

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
DerZyklop
  • 3,672
  • 2
  • 19
  • 27
3

If you want to change the remote URL only for this clone:

git config submodule."$submodule_name".url "$new_url"

This won't affect the .gitmodules file in the parent project, so it won't be propagated to other developers.

This is described as "user specific record changes" here.

Do not run git submodule sync as that will reset to the default URL again.

Community
  • 1
  • 1
joeytwiddle
  • 29,306
  • 13
  • 121
  • 110