Reputation: 20865
Is there some easy way to rename a git submodule directory (other than going through the entire motion of deleting it and re-adding it with a new destination name).
And while we are at it, why is it that I simply cannot do the following in the parent directory: git mv old-submodule-name new-submodule-name
Upvotes: 243
Views: 121804
Reputation: 41116
Many great answers, I recently ran into this issue (had a bit of struggle) and I want to share a complete (yet minimal) list of steps that I took.
Working on a concrete example:
Repository PyShallow ([GitHub]: CristiFati/pyshallow - PyShallow):
Depends on PyCFUtils ([GitHub]: CristiFati/pycfutils - PyCFUtils) and has it as a (Git) submodule:
I recently renamed it (on GitHub) from CFPyUtils
One thing that threw me me a bit off course is that the old URL (with the old name) still works - GitHub is smart enough to redirect to the new one (which makes sense)
I might be considered too pedantic, but I wanted all references to CFPyUtils removed (even if some of them are just internal (no visibility to the user) and they work)
Steps (if one wants to replace old by new - each term refers to both: path and (part of) URL):
Rename submodule folder in the Git repository (git mv old new
)
.gitmodules: Edit and replace all old occurrences by new
.git/config: Edit and replace all old occurrences by new
Rename (manually) submodule reference folder (mv .git/modules/old .git/modules/new
)
new/.git (!!! it's a file !!!): Update the new reference folder
Synchronize submodule (git submodule sync
)
Modify any (non Git related) file that references the old submodule path
Everything works fine afterwards on the test clone, and also on a fresh one.
The actual steps:
(py_pc064_03.10_test0) [cfati@cfati-5510-0:/mnt/e/Work/Dev/Repos/GitHub/CristiFati/pyshallow/src]> ~/sopr.sh ### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ### [064bit prompt]> # ---------- Start from scratch ---------- [064bit prompt]> ls [064bit prompt]> [064bit prompt]> git clone [email protected]:CristiFati/pyshallow.git . Cloning into '.'... remote: Enumerating objects: 123, done. remote: Counting objects: 100% (123/123), done. remote: Compressing objects: 100% (83/83), done. remote: Total 123 (delta 57), reused 92 (delta 30), pack-reused 0 Receiving objects: 100% (123/123), 18.97 KiB | 626.00 KiB/s, done. Resolving deltas: 100% (57/57), done. [064bit prompt]> [064bit prompt]> ls Contents LICENSE README.md _extra cfpyutils gen_evt mue_idle.py nix_run.sh win_run.bat [064bit prompt]> [064bit prompt]> ls cfpyutils/ [064bit prompt]> [064bit prompt]> git submodule update --init Submodule 'cfpyutils' ([email protected]:CristiFati/cfpyutils.git) registered for path 'cfpyutils' Cloning into '/mnt/e/Work/Dev/Repos/GitHub/CristiFati/pyshallow/src/cfpyutils'... Submodule path 'cfpyutils': checked out '46ba9528d3aaed29eeaee5f09ac50c0f28e5836d' [064bit prompt]> [064bit prompt]> # ---------- Step #1. ---------- [064bit prompt]> git mv cfpyutils pycfutils [064bit prompt]> [064bit prompt]> ls Contents LICENSE README.md _extra gen_evt mue_idle.py nix_run.sh pycfutils win_run.bat [064bit prompt]> [064bit prompt]> git status On branch master Your branch is up to date with 'origin/master'. Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: .gitmodules renamed: cfpyutils -> pycfutils [064bit prompt]> [064bit prompt]> git diff --cached .gitmodules diff --git a/.gitmodules b/.gitmodules index a4caf8a..8c841d4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,5 +1,5 @@ [submodule "cfpyutils"] - path = cfpyutils + path = pycfutils url = [email protected]:CristiFati/cfpyutils.git #url = https://github.com/CristiFati/cfpyutils.git branch = master [064bit prompt]> [064bit prompt]> # ---------- Step #2. ---------- [064bit prompt]> vi .gitmodules [064bit prompt]> [064bit prompt]> # ---------- Step #3. ---------- [064bit prompt]> vi .git/config [064bit prompt]> [064bit prompt]> # ---------- Step #4. ---------- [064bit prompt]> mv .git/modules/cfpyutils .git/modules/pycfutils [064bit prompt]> [064bit prompt]> git status fatal: not a git repository: pycfutils/../.git/modules/cfpyutils [064bit prompt]> [064bit prompt]> # ---------- Step #5. ---------- [064bit prompt]> vi pycfutils/.git [064bit prompt]> [064bit prompt]> # ---------- Step #6. ---------- [064bit prompt]> git submodule sync Synchronizing submodule url for 'pycfutils' [064bit prompt]> [064bit prompt]> # ---------- Step #7. ---------- [064bit prompt]> vi mue_idle.py [064bit prompt]> [064bit prompt]> # ---------- All done (review changes, commit and push) ---------- [064bit prompt]> [064bit prompt]> git diff diff --git a/.gitmodules b/.gitmodules index 8c841d4..c9be742 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,5 +1,5 @@ -[submodule "cfpyutils"] +[submodule "pycfutils"] path = pycfutils - url = [email protected]:CristiFati/cfpyutils.git - #url = https://github.com/CristiFati/cfpyutils.git - branch = master + url = [email protected]:CristiFati/pycfutils.git + #url = https://github.com/CristiFati/pycfutils.git + branch = main diff --git a/mue_idle.py b/mue_idle.py index 60813f9..dc48dc8 100755 --- a/mue_idle.py +++ b/mue_idle.py @@ -12,8 +12,8 @@ if cur_dir not in sys.path: sys.path.append(cur_dir) \"\"\" import gen_evt as ge -from cfpyutils.common import ts_str -from cfpyutils.keyboard import read_key +from pycfutils.common import ts_str +from pycfutils.keyboard import read_key __version_info__ = (0, 2, 2) [064bit prompt]> [064bit prompt]> git status On branch master Your branch is up to date with 'origin/master'. Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: .gitmodules renamed: cfpyutils -> pycfutils Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: .gitmodules modified: mue_idle.py [064bit prompt]> git add .gitmodules mue_idle.py [064bit prompt]> [064bit prompt]> git commit -m "fix: update submodule (path && url)" [master 15d21e9] fix: update submodule (path && url) 3 files changed, 8 insertions(+), 8 deletions(-) rename cfpyutils => pycfutils (100%) [064bit prompt]> git push Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 8 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 544 bytes | 24.00 KiB/s, done. Total 4 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/2), completed with 2 local objects. To github.com:CristiFati/pyshallow.git 7fcf9f3..52b148e master -> master
Upvotes: 0
Reputation: 5852
The correct solution is:
mv oldpath ~/another-location
git rm oldpath
git submodule add submodule-repository-URL newpath
Upvotes: 19
Reputation: 32848
I found following workflow working:
mv oldpath newpath
git rm oldpath
git add newpath
git submodule sync
Note: this approach does not update the index and .gitmodules
properly in 2018 versions of GIT.
Note: You may be able to just do git mv oldpath newpath
now, as pointed out in VonC's answer. (Ensure you are using the latest version of git)
Upvotes: 124
Reputation: 92377
MacOs: When I wanna use VonC solution to change submodule folder Common
to lowercase:
git mv Common common
I get
fatal: renaming 'Common' failed: Invalid argument
Solution - use some temporary folder name and move twice:
git mv Common commontemp
git mv commontemp common
That's all :)
Upvotes: 5
Reputation: 1324218
Git1.8.5 (October 2013) should simplify the process. Simply do a:
git mv A B
"
git mv A B
", when moving a submoduleA
has been taught to relocate its working tree and to adjust the paths in the.gitmodules
file.
See more in commit 0656781fadca1:
Currently using "
git mv
" on a submodule moves the submodule's work tree in that of the superproject. But the submodule's path setting in.gitmodules
is left untouched, which is now inconsistent with the work tree and makes git commands that rely on the properpath -> name mapping
(likestatus
anddiff
) behave strangely.Let "
git mv
" help here by not only moving the submodule's work tree but also updating the "submodule.<submodule name>.path
" setting from the.gitmodules
file and stage both.
This doesn't happen when no.gitmodules
file is found and only issues a warning when it doesn't have a section for this submodule. This is because the user might just use plain gitlinks without the.gitmodules
file or has already updated the path setting by hand before issuing the "git mv" command (in which case the warning reminds him thatmv
would have done that for him).
Only when.gitmodules
is found and contains merge conflicts themv
command will fail and tell the user to resolve the conflict before trying again.
git 2.9 (June 2016) will improve git mv
for submodule:
See commit a127331 (19 Apr 2016) by Stefan Beller (stefanbeller
).
(Merged by Junio C Hamano -- gitster
-- in commit 9cb50a3, 29 Apr 2016)
mv
: allow moving nested submodules"
git mv old new
" did not adjust the path for a submodule that lives as a subdirectory insideold/
directory correctly.submodules however need to update their link to the git directory as well as updates to the
.gitmodules
file.
Upvotes: 341
Reputation: 166399
It's not possible to rename it, so you've to remove it first (deinit
) and add it again.
So after removing it:
git submodule deinit <path>
git rm --cached <path>
you may also double check and remove the references to it in:
.gitmodules
.git/config
.git/modules/<name>
(best to make a backup), as each folder has config
file where it keeps the reference to its worktree
then stage your changes by committing any changes to your repo by:
git commit -am 'Removing submodule.'
and double check if you don't have any outstanding issues by:
git submodule update
git submodule sync
git submodule status
so now you can add the git submodule again:
git submodule add --name <custom_name> [email protected]:foo/bar.git <my/path>
Upvotes: 16
Reputation: 807
I just tried a few of the suggested above. I'm running:
$ git --version
git version 1.8.4
I found it was best to de-init the submodule, remove the directory and create a new submodule.
git submodule deinit <submodule name>
git rm <submodule folder name>
git submodule add <address to remote git repo> <new folder name>
At least that is what worked for me best. YMMV!
Upvotes: 12
Reputation: 150615
Edit the .gitmodules file to rename the submodule and then rename the submodule directory.
I think you might need to do a git submodule sync
afterwards, but I'm not in a position to check right now.
Upvotes: 4