Какая версия файла git будет окончательно использована: LOCAL, BASE или REMOTE?
Когда в течение git merge
появляется конфликт, я открываю слияние, называемое Meld. Он открывает три файла LOCAL, BASE и REMOTE. Поскольку я читал LOCAL - это моя локальная ветвь, BASE - общий предок, а REMOTE - это ветвь, которую нужно объединить.
Теперь на мой вопрос: какая версия файла будет наконец использована? Разве это REMOTE? Если да, могу ли я отредактировать его так, как я хочу, независимо от того, что в ветке BASE, например?
Ответы
Ответ 1
Он посередине: BASE
.
Фактически, BASE
не является общим предком, а полузавершенным слиянием, где конфликты помечены >>>>
и <<<<
.
Вы можете увидеть имена файлов в верхней части окна редактирования meld.
Смотрите скриншот здесь
![meld base]()
Вы можете отредактировать файл BASE
, как хотите, с помощью команд meld или без них.
Вы также можете избавиться от meld и просто отредактировать файл с помощью своего любимого текстового редактора.
- Код между метками
<<<< HEAD
и =====
является одним из ваших локальных файлов перед слиянием.
- Код между
====
и >>>> <branch name>
является одним из удаленных файлов.
Ответ 2
У Meld есть скрытая функция трехстороннего слияния, активированная передачей в 4-м параметре:
meld $LOCAL $BASE $REMOTE $MERGED
Правая и левая панели открываются в режиме только для чтения, поэтому вы случайно не можете объединиться неправильно. В средней панели отображается результат слияния. Для конфликтов он показывает базовую версию, чтобы вы могли видеть все важные биты: исходный текст посередине и конфликтующие изменения с обеих сторон. Наконец, когда вы нажимаете кнопку "Сохранить", файл $MERGED записывается - точно так, как ожидалось, через git.
Файл ~/.gitconfig, который я использую, содержит следующие настройки:
[merge]
tool = mymeld
conflictstyle = diff3
[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE $MERGED
открывается с 3 вкладками, 1-я и 2-я вкладки, содержащие простые различия, которые я пытаюсь объединить, а 3-я вкладка, открытая по умолчанию, показывает трехстороннее представление слияния.
Теперь причина, по которой эта функция скрыта, заключается в том, что она еще недостаточно отполирована. Это очень полезно, как сейчас, но Кай Уилладсен, автор соломы, указал на несколько морщин, которые нуждаются в глажке. Например, нет графического интерфейса для запуска трехстороннего режима слияния, синтаксис командной строки является немного тайным и т.д. Если вы говорите на python и имеете некоторое время на ваших руках - вы знаете, что делать.
Изменить:
В новых версиях Meld синакс немного изменился. Это было в комментариях, но оно относится к ответу.
Теперь команда meld использует параметр --output, поэтому последняя строка из приведенного выше фрагмента должна быть:
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED
Ответ 3
Имеется 4 файла:
-
$LOCAL
Файл в ветке, где вы сливаетесь; нетронутый процессом слияния, когда он показан вам
-
$REMOTE
Файл в ветке, откуда вы сливаетесь; нетронутый процессом слияния, когда он показан вам
-
$BASE
Общий предок $LOCAL и $REMOTE, т.е. точка, в которой две ветки начали отвлекать рассматриваемый файл; нетронутый процессом слияния, когда он показан вам
-
$MERGED
Частично объединенный файл с конфликтами; это единственный файл, затронутый процессом слияния и, фактически, никогда не показан вам в meld
Файл $MERGED
- это тот, который содержит метки <<<<<<
, >>>>>>
, =====
(и, возможно, ||||||
) (которые ограничивают конфликты). Это файл, который вы редактируете вручную для устранения конфликтов.
Редактирование конфликтов вручную и редактирование визуальных конфликтов выполняются в разных файлах и представлены различной информацией.
При использовании mergetool (предположим meld
) файлы, которые там видны, следующие: $LOCAL
, $BASE
, $REMOTE
. Обратите внимание, что вы не видите файл $MERGED
, хотя он передается как скрытый параметр в meld
для записи результата редактирования там.
Другими словами, в meld
вы редактируете файл в середине, файл $BASE
, и вы выбираете все изменения слева или справа вручную. Это чистый файл, который не затрагивается процессом слияния. Единственный сбой в том, что при сохранении вы не сохраняете файл $BASE
, а в четвертом скрытом параметре meld
, который является файлом $MERGED
(который вы даже не видите). Файл $BASE
не содержит конфликтов или частичных успешных слияний, потому что это не файл $MERGED
.
В визуальном редактировании при представлении вам файла $BASE
(вместо файла $MERGED
) git
в основном отбрасывает все его попытки выполнить слияние (эти попытки видны, если хотите, в $MERGED) и позволяет полностью выполнить слияние с нуля.
Суть в том, что в конфликтах с ручным и визуальным слиянием вы не смотрите на одни и те же файлы, но конечный результат записывается в тот же файл (это файл $MERGED
).
Ручная коррекция конфликтов выполняется на $MERGED
, потому что git
не имеет смысла представлять вам три файла, поэтому он выдает информацию из трех файлов ($LOCAL
, $BASE
, $REMOTE
) в этом $MERGED
файле.
Но визуальные инструменты имеют средства, чтобы показать вам три файла: они показывают файлы $LOCAL
, $BASE
, $REMOTE
. Вы выбираете изменения из файлов $LOCAL
и $REMOTE
, и вы переносите их в файл $BASE
, полностью перестраиваете и даже перезаписываете неудачную попытку слияния, которая является файлом $MERGED
.
Ответ 4
Решение Cosmin работает, но файл $BASE обновляется, а не $MERGED. Это обновит файл $MERGED:
Meld: v1.8.4
[merge]
conflictstyle = diff3
tool = mymeld
[mergetool "mymeld"]
cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE --diff $BASE $LOCAL --diff $BASE $REMOTE
Ответ 5
С Meld 1.7 решение Томека Бери больше не работает.
Настройки по умолчанию меня не удовлетворили:
![Default settings]()
Вместо Meld >= 1.7 Я предлагаю одно из двух других решений.
Первое решение:
meld $LOCAL $BASE $REMOTE --auto-merge
![first solution]()
Второе решение:
meld $LOCAL $MERGED $REMOTE
![second solution]()
.gitconfig
Скопируйте и вставьте это в свой .gitconfig
файл, чтобы получить решения, описанные выше:
[merge]
tool = meld16
[mergetool "meld17"]
# use this for Meld >=1.7
# see http://stackoverflow.com/a/22911793/859591
# second solution:
cmd = meld $LOCAL $MERGED $REMOTE
# first solution:
#cmd = meld $LOCAL $BASE $REMOTE --auto-merge
[mergetool "meld16"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED
[include]
# requires git v1.7.10+
path = .gitconfig.local
Скопируйте и вставьте это в файл .gitconfig.local
, чтобы установить meld17 или meld16 только для этого устройства, если вы используете свой .gitconfig на нескольких машинах:
# This is a host specific config file!
# Note that git 1.7.10+ is needed
# http://stackoverflow.com/a/9733277/859591
[merge]
tool = meld17
Ответ 6
Я обнаружил, что ни один из показанных файлов по умолчанию не был сохранен.
По умолчанию meld показывал $LOCAL
, $REMOTE
и $BASE
. Чтобы заставить его работать, мне нужно было сделать meld show $MERGED
вместо $BASE
. Помещая это в мой ~/.gitconfig
, исправил это для меня:
[merge]
tool = mymeld
[mergetool "mymeld"]
cmd = meld "$LOCAL" "$MERGED" "$REMOTE"
Я использую Arch, с:
$ git --version
git version 1.8.2
$ meld --version
meld 1.7.1
Ответ 7
По какой-то причине новейшие версии meld не отображают строки маркеров, добавленные для конфликтов (< < < < <, <, =======, → → → > ), Если вы хотите увидеть эти строки, вы должны установить meld v 1.3.3 или предыдущий.
Ответ 8
Обратитесь к Сааду за правильным ответом.
С meld 1.8.1 на Ubuntu я получал
неправильное количество аргументов, переданных в -diff
и добавив --output перед $MERGED исправил это для меня:
[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED