Не удается разрешить конфликт слияния с папкой подмодуля 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