Подтвердить что ты не робот

После перемещения подмодуля git в другой каталог сбой с ошибкой 'git status -porcelain' не удалось в подмодуле

Первоначально у меня была следующая (упрощенная) структура репо:

MyRepo
   external1/MySub (git submodule)
   .gitsubmodules

Где

$ cat .gitsubmodules

  [submodule "external1/MySub"]
  path = external1/MySub
  url = [email protected]:/remoterepo/externals/MySub.git

Затем мне захотелось переместить MySubmodule в другой каталог в том же репозитории git, например, external2, поэтому структура выглядит следующим образом:

MyRepo
   external2/MySub (git submodule)
   .gitsubmodules

Что я сделал, и думал, достаточно, я просто переместил (через OS mv) каталог external1/MySub на внешний2/MySub и отредактировал файл .gitsubmodules:

$ cat .gitsubmodules

  [submodule "external2/MySub"]
  path = external2/MySub
  url = [email protected]:/remoterepo/externals/MySub.git

После этого изменения я получаю следующую ошибку:

$ git status

  fatal: Could not chdir to '../../../../../repo/external/MySub': No such file or directory
  fatal: 'git status --porcelain' failed in submodule repo/external2/MySub

Что мне не хватает? Любые другие изменения необходимо сделать для такого перехода на работу?

(Я использую git версию 1.8.3rc3 в Windows 8.1)

4b9b3361

Ответ 1

Я просто переместил каталог external1/MySub на внешний2/MySub

Переместить как в mv (команда unix), или git mv (git)?

Вам нужно переместить специальную запись индекса, представляющего подмодуль для родительского репо.

Обычно (чтение git mv), этого должно было быть достаточно:

git mv external1/MySub external2/MySub

Перемещение подмодуля с использованием gitfile (что означает, что они были клонированы с версией Git версии 1.7.8 или новее), обновит настройки gitfile и core.worktree, чтобы заставить подмодуль работать в новом месте.
Он также попытается обновить параметр submodule.<name>.path в файле gitmodules и выполнить этот файл (если не используется).

Это лучше всего работает с последним 1.8.5 Git (например, msysgit для Windows или последний пакет для Unix)


Suseika добавляет в комментариях

Если вы получаете сообщение

fatal: renaming '%submodule%' failed: No such file or directory

это, вероятно, потому, что вы добавляете уровень каталога, например. движущийся подмодуль "math" до "libs/math".
git mv не создает отсутствующих [промежуточных] каталогов, вы должны mkdir их самостоятельно.


git 2.9 (июнь 2016 г.) улучшит git mv для подмодуля:

См. совершить a127331 (19 апреля 2016 г.) Стефан Беллер (stefanbeller).
(слияние Junio ​​C Hamano - gitster - в commit 9cb50a3, 29 апреля 2016 г.

mv: разрешить перемещение вложенных подмодулей

"git mv old new" не отредактировал путь для подмодуля, который правильно работает в подкаталоге внутри каталога old/.

Подкатегории

однако, должны обновить свою ссылку в каталоге Git, как а также обновления файла .gitmodules.


git 2.12 (Q1 2017) предлагает перемещать вложенные подмодули в родительское репо:

Существует новый помощник подмодуля " git submodule absorbgitdirs", чтобы упростить перемещение встроенного каталога .git/ для подмодулей в суперпроект к .git/modules/ (и укажем последний с первым который превращен в файл "gitdir:" ).

См. commit 7c4be45 (27 декабря 2016 г.), commit f6f8586, commit 47e83eb, commit 1a248cf (12 декабря 2016 г.) и commit 6f94351, commit 89c8626, commit 90c0011, commit 6f94351, commit 89c8626, commit 90c0011 (08 декабря 2016 г.) Стефан Беллер (stefanbeller).
(слияние Junio ​​C Hamano - gitster - в commit da2b74e, 10 января 2017 г.

подмодуль: добавить absorb-git-dir функцию

Когда подмодуль имеет свой git dir внутри рабочего ребра, подмодуль поддержка проверки, которую мы планируем добавить в более поздний патч, не удастся.

Добавить функциональность для переноса каталога Git, который будет поглощен в каталог суперпроектов Git.

Недавно добавленный код в этом патче структурирован таким образом, что другие области Git также может использовать его. Код в подмодуле - помощник - это просто обертка и парсер параметров для function absorb_git_dir_into_superproject, который заботится о внедрении подмодулей Git в суперпроектах Git dir. Эта функция использует более абстрактную функцию для этого случая использования relocate_gitdir, который может быть использован, например, код рабочей книги в конечном итоге для перемещения по каталогу Git.


Примечание: все еще существует (git 2.14.x/2.15, Q4 2017) ошибка, связанная с перемещением подмодулей: см. "Git: рекурсивно перемещаются подмодули (вложенные подмодули )".


git 2.15.x/2.16 (Q1 2018) сделает движущийся подмодуль более надежным, так как "git fetch --recurse-submodules" теперь знает, что подмодули могут быть перемещался в суперпроекте в дополнение к обновлению, и находит те, которые должны быть получены соответственно.

См. commit 4b4aced, совершить c68f837 ( 16 октября 2017 г.) и зафиксировать 01ce122 (06 октября 2017 г.) Heiko Voigt (hvoigt).
(слияние Junio ​​C Hamano - gitster - в commit b4d658b, 06 ноября 2017 г.

реализовать выборку перемещенных подмодулей

Мы сохраняем измененные пути подмодулей для вычисления потребности в подмодулях выборка. Это не работает для перемещенных подмодулей, поскольку их пути не оставаться неизменным в случае перемещенных подмодулей.
В случае новых подмодулей у нас нет пути в текущей проверке, так как они только появились в этой выборке.

Более общий сбор имен подмодулей для изменений вместо их пути включают вышеупомянутые случаи. Если у нас нет конфигурации для gitlink мы полагаемся на построение имени по умолчанию из путь, если репозиторий Git можно найти по его пути. Мы пропускаем не сконфигурированные gitlinks, имя по умолчанию которых совпадает с настроенным один.

Ответ 2

Я изменил еще несколько вещей вручную и фактически работал с git 1.8.3rc3 (ненужным с git 1.8.5):

  • Исправить gitdir путь в .git subodule файл repo/external2/MySub/.git:

    -gitdir: ../../../.git/modules/external1/MySub
    +gitdir: ../../../.git/modules/external2/MySub
    
  • Переименуйте каталог подмодулей в каталог repo/.git/modules/

    $ mv repo/.git/modules/external1 repo/.git/modules/external2
    
  • Исправить worktree путь в repo/.git/modules/external2/MySub/config

    -worktree = ../../../../../external1/MySub
    +worktree = ../../../../../external2/MySub