19

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

  1. All your projects locate in /tmp.
  2. You've got a proj_master and proj_mod.
  3. You clone porj_master as proj_ALL then clone prom_mod as a submodule in it.
  4. You rename proj_ALL to 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 1.7.9.5

  1. Initialize proj_master.

    $ cd /tmp
    $ mkdir proj_master; cd proj_master
    $ git init .
    $ touch README
    $ git add .; git commit -m "hello proj_master"
    
  2. Initialize proj_mod.

    $ cd /tmp
    $ mkdir proj_mod; cd proj_mod
    $ git init .
    $ touch README
    $ git add .; git commit -m "hello proj_mod"
    
  3. Clone proj_master as proj_ALL and clone proj_mod as 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.
    
  4. Rename proj_ALL to 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.

Community
  • 1
  • 1
Jianwen W.
  • 3,919
  • 4
  • 18
  • 17

4 Answers4

12

You have a couple of options, they end up being the same thing:

clone again

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

Compare original/.git/config to moved/.git/config and address any significant differences (missing branches need creating - missing remotes just need adding to the config file).

fix paths

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 worktree setting:

[core]
    ...
    worktree = /original/path/submodule

To

[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.

Community
  • 1
  • 1
AD7six
  • 63,116
  • 12
  • 91
  • 123
  • Thanks, AD7six. Your trick fixes my problem. I'm just curious about why git uses such a nasty approach ("absolute path") in its recent release. – Jianwen W. May 20 '12 at 06:20
  • Others are complaining about these issues too. Check ["Annoying absolute path for "core.worktree" to submodule"](http://comments.gmane.org/gmane.comp.version-control.git/193492). Good news is that, in git-1.7.10, *relative path* will be back and *absolute path* will go away. – Jianwen W. May 20 '12 at 06:32
  • I had noticed that one of my machines used relative paths, but hadn't checked the versions - I added that info to the answer after a quick bit of confirmatory research. – AD7six May 20 '12 at 20:28
5

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.

Calin
  • 51
  • 1
  • 1
4

You also need to check each sub-module's gitdir.

It should be in sub-module's folder .git file.

pb2q
  • 58,613
  • 19
  • 146
  • 147
Titan Lien
  • 51
  • 4
1

You need to actually modify two files

.git/modules/<path-to-submodule>/config
<path-to-submodule>/.git
mhstnsc
  • 848
  • 1
  • 10
  • 24