Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving a git working copy containing submodules

A recent change in Git changed the way the .git directory is handled when using submodules. Instead of having one .git per submodule, everything is now in the "root level" .git directory (the one corresponding to the working copy including the submodules).

Then, in each submodule, a file is created which points to the new location of the .git directory.

In my project, I have the following .gitmodules file:

[submodule "tests/shared-tests"]
        path = tests/shared-tests
        url = git://github.com/roboptim/roboptim-shared-tests.git
[submodule "cmake"]
        path = cmake
        url = git://github.com/jrl-umi3218/jrl-cmakemodules.git

When I do git clone --recursive, I then obtain:

$ cat cmake/.git
gitdir: /home/moulard/profiles/default-x86_64-linux-ubuntu-12.04.1/src/unstable/roboptim/roboptim-core/.git/modules/cmake

I am currently using Git 1.8.1.5.

My questions are:

  1. Why did this behavior change? I don't see any obvious gain to this new strategy.
  2. How can I then move safely a working copy? (if I move my working copy, I get an error message telling me that the path to the broken gitdir is not a Git repository anymore)

Please note that this is not the same as the previous question Moving the parent directory of a git repository that contains submodules in the sense that I am sure this is not an issue related by the presence of an absolute path in my .gitmodules file.

like image 971
Thomas Moulard Avatar asked Apr 23 '13 04:04

Thomas Moulard


People also ask

Does git clone pull submodules?

It automatically pulls in the submodule data assuming you have already added the submodules to the parent project. Note that --recurse-submodules and --recursive are equivalent aliases.

What does git pull -- recurse submodules do?

If you pass --recurse-submodules to the git clone command, it will automatically initialize and update each submodule in the repository, including nested submodules if any of the submodules in the repository have submodules themselves.


1 Answers

The .git/module organization dates back from git1.7.8 (December 2d, 2011):

When populating a new submodule directory with "git submodule init", the $GIT_DIR metainformation directory for submodules is created inside $GIT_DIR/modules/<name>/ directory of the superproject and referenced via the gitfile mechanism.
This is to make it possible to switch between commits in the superproject that has and does not have the submodule in the tree without re-cloning.

However, recent bug fixes have been included in 1.8.2.1 and 1.8.3 (April 22d, 2013):

"git submodule update", when recursed into sub-submodules, did not acccumulate the prefix paths.

So upgrading to the very latest git release could fix this issue.


Here, one possible solution (with the latest git 1.8.3, April, 22d 2013), is mentioned by the OP Thomas Moulard in the comments:

$ git submodule deinit -f . is working!
Then I can run git submodule init and the paths get fixed

This takes care if the (de)initialization steps (.git/modules)

It doesn't take care of the 'add' step which records the url of a submodule in the .gitmodules file: you still need to remove it manually within that file.

like image 92
VonC Avatar answered Oct 24 '22 21:10

VonC