Перемещение рабочей копии git, содержащей подмодули

Недавнее изменение в Git изменило способ обработки каталога .git при использовании подмодулей. Вместо того, чтобы иметь один .git на каждый подмодуль, все теперь находится в директории "root level" .git (той, которая соответствует рабочей копии, включая подмодули).

Затем в каждом подмодуле создается файл, который указывает на новое местоположение каталога .git.

В мой проект, у меня есть следующий .gitmodules файл:

[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

Когда я делаю git clone --recursive, я получаю:

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

В настоящее время я использую Git 1.8.1.5.

Мои вопросы:

  • Почему изменилось это поведение? Я не вижу очевидной выгоды для этой новой стратегии.
  • Как я могу безопасно перемещать рабочую копию? (если я переведу свою рабочую копию, я получаю сообщение об ошибке, сообщающее мне, что путь к сломанному gitdir больше не является хранилищем Git)

Обратите внимание, что это не то же самое, что предыдущий вопрос Перемещение родительского каталога репозитория Git, содержащего подмодули, в том смысле, что я уверен, что это это не проблема, связанная с наличием абсолютного пути в моем файле .gitmodules.

Ответ 1

Организация .git/module восходит к git1.7.8 (2 декабря 2011 г.):

При заполнении нового каталога подмодулей с "git submodule init" каталог метаинформации $GIT_DIR для подмодулей создается внутри каталога $GIT_DIR/modules/<name>/ суперпроекта и ссылается через механизм gitfile.
Это позволяет переключаться между коммитами в суперпроекте, который имеет и не имеет подмодуля в дереве без повторного клонирования.

Однако последние исправления ошибок были включены в 1.8.2.1 и 1.8.3 (22 апреля 2013 г.):

"git обновление подмодуля", когда он был рекурсирован в под-подмодули, не acccumulate пути префикса.

Поэтому обновление до самого последнего выпуска git может решить эту проблему.


Здесь одно возможное решение (с последним git 1.8.3, апрель, 22d 2013) упоминается OP Thomas Moulard в комментарии:

$ git submodule deinit -f . работает!
Затем я могу запустить git submodule init, и пути будут исправлены.

Это позаботится, если шаги инициализации (de) (.git/modules)

Он не заботится о шаге "add", который записывает url подмодуля в файле .gitmodules: вам все равно нужно удалить его вручную в этом файле.

Ответ 2

Я успешно исправил свою рабочую копию после перемещения ее в другом месте, выполнив следующее:

  • Обновление пути gitdir: в superproject/path/to/submodule/.git файле
  • Обновление пути worktree= в superproject/.git/modules/path/to/submodule/config файле

Я не знаю, почему git использует абсолютные пути там!

(проверено на git 2.0.1.563)