How to rename a git repo (project) which contains submodules in its subdirectories
I never expect renaming a git repo, which, more specifically, is the top-level folder holds the project, would be so hard. Yes, the project containing some submodules, but it is the top-level folder that needs renaming, not the submodule folder. Git, it seems, records some odd absolute paths in its submodule mechanisms.
Let’s assume that
- All your projects locate in
- You’ve got a
- You clone
prom_modas a submodule in it.
- You rename
proj_onebillion. Then black magic happens.
The following steps will reproduce the problem I mentioned. The version of git I use is:
$ git --version git version 126.96.36.199
$ cd /tmp $ mkdir proj_master; cd proj_master $ git init . $ touch README $ git add .; git commit -m "hello proj_master"
$ cd /tmp $ mkdir proj_mod; cd proj_mod $ git init . $ touch README $ git add .; git commit -m "hello proj_mod"
proj_modas a submodule.
$ cd /tmp $ git clone proj_master proj_ALL $ cd proj_ALL $ git submodule add /tmp/proj_mod ./mod $ git add .; git commit -m "hello proj_ALL" $ git status % Everything is OK.
proj_onebillion. Encounter a fatal error.
$ cd /tmp $ mv proj_ALL proj_onebillion $ cd proj_onebillion $ git status fatal: Not a git repository: /tmp/proj_ALL/.git/modules/mod
One thing to notice is the
.git file in the submodule directory.
$ cat /tmp/proj_ALL/mod/.git gitdir: /tmp/proj_ALL/.git/modules/mod
Yeah, an absolute path. For the first time, I realize that git is aware of something outside the scope of the top-level repo folder.
That’s it. I repeat that one more time that I rename the top-level project folder, not the submodule folder. I check schmuck’s question, which tried to rename the submodule folder, therefore seems not so helpful to my problem.
If I miss something that should have been read before, I apologize. To all guys, any advice is welcomed.
4 Solutions collect form web for “How to rename a git repo (project) which contains submodules in its subdirectories”
You have a couple of options, they end up being the same thing:
Instead of renaming the folder – just clone again
$ cd /project/original $ cd .. $ mkdir moved $ git init $ git pull ../original master $ git submodule init $ git submodule update
moved/.git/config and address any significant differences (missing branches need creating – missing remotes just need adding to the config file).
You can rename your project folder, it just needs a little tweaking.
- Fix your submodule .git file references.
I.e. these files:
$ cd /project/moved $ find -name .git -type f
All you need to do is edit them to point at the right directory
- Fix your submodule .git config files
I.e. these files:
$ cd /project/moved $ find .git/modules/ -name config
Here, update the
[core] ... worktree = /original/path/submodule
[core] ... worktree = /moved/path/submodule
And that’s it.
A note about versions
1.7.8 introduced the use of a .git file for submodules and used absolute paths, this was fixed in 1.7.10 – therefore the problem only applies to git repos created with git version 1.7.8, and 1.7.9.
When moving a project that has git submodules from one folder to another, on the same machine, there are some hardcoded links that have to be updated.
First, all submodules have a .git file where they store the absolute path to their git configuration folder ( these are inside the main’s project .git folder, grouped into the modules folder). To fix all of these, run the following command from the root of the main project:
find . -name .git -print0 -type f | xargs -0 sed -i 's|<OLD PATH>|<NEW PATH>|g'
Second, the configuration files for the git submodules have a line where the working directory is saved, also absolute. To update all of the references at once, run the following command from the root of the main project:
find . -name config -print0 -type f | xargs -0 sed -i 's|<OLD PATH>|<NEW PATH>|g'
The assumptions made are that your OS is some form of *nix, and that you have the package sed installed.
You also need to check each sub-module’s
It should be in sub-module’s folder
You need to actually modify two files