Как разрешить конфликт подмодуля git, если подмодуль не инициализирован
У меня две ветки A
и B
. Оба содержат подмодуль (в папке sub
), однако при разных коммитах (которые не перескакивают с одного на другой).
A B
| /
BASE
Я проверил A
, но подмодуль еще не инициализирован. Теперь я объединяю B
и получаю конфликт на подмодуле.
$ git status
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: sub
Выдача git checkout --ours sub
ничего не делает (если подмодуль инициализирован, он работает, также git checkout-index -f --stage=2 -- sub
не работает). git add sub
вызывает ошибку error: pathspec 'sub' did not match any file(s) known to git.
.
$ git diff sub
diff --cc sub
index 533da4e,ab2af77..0000000
--- a/sub
+++ b/sub
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit 533da4ea00703f4ad6d5518e1ce81d20261c40c0
-Subproject commit ab2af775ec467ebb328a7374653f247920f258f3
++Subproject commit 0000000000000000000000000000000000000000
git submodule init -- sub
ничего не делает. Также git submodule update --init --force -- sub
не работает: Skipping unmerged submodule sub
.
Итак, как я могу разрешить этот конфликт подмодуля (без прерывания слияния и повторения после инициализации подмодуля)?
Ответы
Ответ 1
Что делает вашу ситуацию раздражающей, так это то, что git не позволит вам инициализировать несвязанный подмодуль, поэтому обычный совет просто установить подмодуль в состояние, которое вы хотите в подмодуле, затем запустить git add
, не будет Работа. То, что вы можете сделать, - это обновить индекс напрямую, не проходя через рабочее дерево.
Один из способов обновления индекса - git reset
. Если вы знаете фиксацию, в которой подмодуль находится в состоянии, которое вы хотите, вы можете использовать это. Например, любое из следующего может быть тем, что вы хотите:
git reset master -- sub
git reset [email protected]{upstream} -- sub
git reset HEAD -- sub
git reset MERGE_HEAD -- sub
Другой вариант - обновить индекс напрямую, используя команду сантехника git update-index
. Для этого вам нужно знать, что объект типа gitlink (т.е. Запись каталога в родительском репозитории, который указывает на подмодуль) равен 0160000. Нет способа понять это из первых принципов, но вы можете понять это из git ls-files -s
или следующую ссылку (см. "1110 (gitlink)" под 4-битным типом объекта: https://github.com/gitster/git/blob/master/Documentation/technical/index-format.txt
Чтобы использовать этот подход, определите хэш, который вы хотите установить подмодулем, затем выполните, например:
git update-index --cacheinfo 0160000,533da4ea00703f4ad6d5518e1ce81d20261c40c0,sub
Ответ 2
Это работает так же, как и обычное слияние: вы должны предоставить правильное содержимое на этом пути, чтобы git мог его зафиксировать. Содержимое субмодуля сохраняется как его текущий идентификатор фиксации, поэтому вам нужно добавить путь подмодуля к проекту (так же, как вы добавляете какой-либо путь к файлу), когда он имеет правильный контент, что означает, что его HEAD
ссылается на право фиксации. Обычно вы получаете это с обычной проверкой.
В вашем случае вы не можете иметь как правильное содержимое результата слияния по пути подмодуля, так и никакого содержимого. Единственное, что необходимо, это иметь репо на этом пути с правильным идентификатором commit в HEAD
. Содержащее репо действительно не могло бы заботиться о том, откуда взялся репо из подмодуля на этом пути, единственное, что имеет значение на данном этапе, это то, что commit id в HEAD
.