How do I move an existing Git submodule within a Git repository?
Note: As mentioned in the comments this answer refers to the steps needed with older versions of git. Git now has native support for moving submodules:
Since git 1.8.5,
git mv old/submod new/submodworks as expected and does all the plumbing for you. You might want to use git 1.9.3 or newer, because it includes fixes for submodule moving.
The process is similar to how you'd remove a submodule (see How do I remove a submodule?):
.gitmodulesand change the path of the submodule appropriately, and put it in the index with
git add .gitmodules.
- If needed, create the parent directory of the new location of the submodule (
mkdir -p new/parent).
- Move all content from the old to the new directory (
mv -vi old/parent/submodule new/parent/submodule).
- Make sure Git tracks this directory (
git add new/parent).
- Remove the old directory with
git rm --cached old/parent/submodule.
- Move the directory
.git/modules/old/parent/submodulewith all its content to
- Edit the
.git/modules/new/parent/configfile, make sure that worktree item points to the new locations, so in this example it should be
worktree = ../../../../../new/parent/module. Typically there should be two more
..than directories in the direct path in that place.
Edit the file
new/parent/module/.git, make sure that the path in it points to the correct new location inside the main project
.gitfolder, so in this example
git statusoutput looks like this for me afterwards:
# On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: .gitmodules # renamed: old/parent/submodule -> new/parent/submodule #
Finally, commit the changes.
The most modern answer, taken from Valloric's comment above:
- Upgrade to Git 1.9.3 (or 2.18 if the submodule contains nested submodules)
git mv old/submod new/submod
- Afterwards the .gitmodules and the submodule directory are already staged for a commit (you can verify this with
- Commit the changes with
git commitand you're good to go!
In my case, I wanted to move a submodule from one directory into a subdirectory, e.g. "AFNetworking" -> "ext/AFNetworking". These are the steps I followed:
- Edit .gitmodules changing submodule name and path to be "ext/AFNetworking"
- Move submodule's git directory from ".git/modules/AFNetworking" to ".git/modules/ext/AFNetworking"
- Move library from "AFNetworking" to "ext/AFNetworking"
- Edit ".git/modules/ext/AFNetworking/config" and fix the
[core] worktreeline. Mine changed from
- Edit "ext/AFNetworking/.git" and fix
gitdir. Mine changed from
git add .gitmodules
git rm --cached AFNetworking
git submodule add -f <url> ext/AFNetworking
Finally, I saw in the git status:
matt$ git status # On branch ios-master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: .gitmodules # renamed: AFNetworking -> ext/AFNetworking
Et voila. The above example doesn't change the directory depth, which makes a big difference to the complexity of the task, and doesn't change the name of the submodule (which may not really be necessary, but I did it to be consistent with what would happen if I added a new module at that path.)