Перемещение рабочей копии 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)