Не удается разрешить конфликт слияния с папкой подмодуля git

У меня есть две ветки Git, развиваю и перепроектирую, которые мне нужно объединить. У меня есть подмодуль под названием библиотека, где его обновления отслеживаются разработчиками. Когда я бегуgit merge"в нем говорится, что библиотека была изменена обоими, хотя я не касался подмодуля библиотеки. Когда я нажимаю на библиотеку в VS Code, чтобы увидеть конфликтующие изменения, я вижу это:

diff --cc library
index 749618f9,589a7ae5..00000000
--- a/library
+++ b/library

Я попытался удалить папку библиотеки и запустить "git submodule updateв то время как в ветви редизайна, прежде чем слиться безуспешно. Я добавил ignore = all в файл.gitmodules в редизайне, но он не работал. Как мне избавиться от конфликта слияния с этим подмодулем?

2 ответа

Решение

Я решил проблему. Я нашел ответ из этого ответа на аналогичный вопрос Stackru: /questions/46789184/chto-eto-znachit-kogda-git-govorit-chto-fajl-nuzhdaetsya-v-obnovlenii/46789211#46789211. Когда я побежал 'git add' в библиотеку и совершил это, проблема ушла. Другой разработчик из моей команды изменил хеш, связанный с подмодулем библиотеки.

Проблема в том, что library был изменен в обеих ветках относительно фиксации слияния. Хитрость здесь в том, чтобы понять, что значит "модифицировать" подмодуль.

Помните, что суть любого подмодуля в том, что ваш суперпроектссылается на какой-то другой Git-репозиторий. Этот другой Git-репозиторий - тот, который используется как подмодуль - не имеет представления, что он используется как подмодуль. Это просто обычный старый Git-репозиторий. 1 Это совершает. Истинное имя любого коммита - это его хэш-идентификатор. Суперпроект, которыйиспользует этот подмодуль, запускает команды Git в подмодуле, чтобы сообщить ему git checkoutнекоторый конкретный коммитпо хеш-идентификатору, в результате чего подмодуль Git находится в режиме отсоединенного HEAD.

Тем временем вернемся к суперпроекту: этот репозиторий является обычным Git-репозиторием. Это совершает. Истинное имя каждого коммита - это некоторый хэш-идентификатор, хотя обычно выgit checkoutкакое-то название ветви. Имя ветви будет преобразовано в некоторый конкретный идентификатор хэша, и ваш суперпроект Git будет проверять этот коммит через это имя ветви - например,develop- и теперь быть на конкретном коммите, например, a123456..., Так скажем, вы на коммите a123456,

Где-тов коммите a123456естьфайлоподобный объект, который на самом деле не является файлом, но вместо этого представляет собой gitlink. Этот объект gitlink в коммите содержит необработанный хэш-идентификатор некоторого коммита, который существует в субмодуле. В вашем случае эта gitlink является записью для имени library и это держит, например, 589a7ae5, Это коммит подмодуля: ваш суперпроект Git будет, если вы запустите git submodule updateвведите подмодуль Git и введите команду git checkout 589a7ae5,

Итак: каждый коммит в суперпроекте имеет "файл" с именем library это действительно ссылка, которая хранит некоторый хэш-идентификатор. Теперь вы запустили:

git checkout develop
git merge redesign

(а может и наоборот). git merge Команда обнаружила коммиты, обозначенные именами веток develop а также redesignвместе с третьим коммитом, который является базой слияния этих двух других коммитов.

Все три из этих коммитов имеют (или не имеют: один из ваших 00000000) запись gitlink с именем library, Три хеш-идентификатора в этих ссылках разные. Git сейчас пытается объединить две разницы:

  • Одна разница говорит, чтоначиная с gitlink X в базе слияния, замените эту gitlink хеш-идентификатором Y.
  • Другой diff говорит, чтоначиная с X в базе слияния, замените это на Z.

Эти две директивы - заменить на Y и заменить на Z - конфликтуют друг с другом. Git не знает, какой из них правильный (если на самом деле любой из них является правильным).

Ваша задача, чтобы разрешить этот конкретный конфликт слияния, состоит в том, чтобы выбратьправильный хеш-идентификатор для субмодуля. Как только вы узнаете правильный хеш-код -как вы узнаете, что это зависит от вас 2- вы просто временно переходите в подмодуль Git-репозиторий и запускаетеgit checkout hash, затем вернитесь к суперпроекту и запуститеgit add library, Ваш суперпроект Git теперь записывает новый идентификатор хеша в gitlink, который войдет в коммит слияния, и конфликт слияния разрешен.

Когда вы разрешили все конфликты слияния, включая обычные файловые, если они есть, и готовы к слиянию, выполните git merge --continueили жеgit commit закончить слияние. Коммит слияния будет иметь в качестве своей ссылки дляlibrary, ID хеша, который вы добавили.

(Если правильно прекратить использование субмодуля полностью, вы можетеgit rm libraryвместо того, чтобы сначала проверить правильный хеш подмодуля, затемgit addимя.)


1 При этом пропускаются некоторые технические детали, с помощью которых можно обнаружить, что этот репозиторий субмодулей находится в каком-то суперпроекте. Важно то, что большая часть Git блаженно не знает об этих деталях: подмодуль думает, что он как бы независим. Более того, типичный репозиторий Git-репозитория является клоном какого-либо другого репозитория Git, и этот другой репозиторий Git полностью не знает о клоне, поэтому даже если клон - используемый вами подмодуль - знал, что это был субмодуль, его origin все равно не будет в курсе.

2 Типичный пример метода для поиска правильного идентификатора хеша начинается с:

cd library

сопровождаемый различными git log и / или git show и / или git checkout команды, или, может быть, gitk --all или что вы хотите использовать для просмотра Git-репозитория. В конце концов, вы видите какой-то хеш-код, который выглядит хорошо и git checkout на нем, чтобы обновить рабочее дерево в этом хранилище, затем cd Вернитесь из подмодуля, соберите и протестируйте проект. Этот процесс естественным образом оставляет подмодуль на правильном коммите, так что вам не нужно повторноgit checkout правильный хэш-идентификатор.

Использование vscode с подмодулями: где пользовательский интерфейс хорошо справляется с большинством задач.

Однако из-за конфликта слияния подмодулей я не смог найти способ его исправить.

Все, что требовалось, - это запустить это в cli:

git add submodule-name
Другие вопросы по тегам