Какая версия файла git будет окончательно использована: LOCAL, BASE или REMOTE?
Когда есть столкновение во время git merge
Я открываю mergetool под названием Meld. Открываются три файла LOCAL, BASE и REMOTE. Поскольку я читал, что LOCAL - это моя локальная ветвь, BASE - это общий предок, а REMOTE - ветвь, которую нужно объединить.
Теперь на мой вопрос: какая версия файла будет окончательно использована? Это удаленный? Если да, могу ли я редактировать его так, как я хочу, независимо от того, что находится, например, в ветке BASE?
8 ответов
Это тот, что в середине: BASE
,
По факту, BASE
не общий предок, а незавершенное слияние, где конфликты отмечены >>>>
а также <<<<
,
Вы можете увидеть имена файлов в верхней части окна редактирования слияния.
Вы можете редактировать BASE
файл, как вы хотите с или без использования команд слияния.
Вы также можете избавиться от слияния и просто отредактировать файл в своем любимом текстовом редакторе.
- Код между
<<<< HEAD
а также=====
маркеры - это один из ваших локальных файлов до слияния. - Код между
====
а также>>>> <branch name>
это один из удаленных файлов.
У 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-я вкладка, открытая по умолчанию, показывает трехстороннее представление слияния.
Теперь, причина, по которой функция скрыта, заключается в том, что она еще недостаточно отшлифована. Это очень полезно, как сейчас, но Кай Вилладсен, автор слияния, указал на несколько морщин, которые нужно сгладить. Например, нет графического интерфейса для запуска режима трехстороннего слияния, синтаксис командной строки немного загадочный и тому подобное. Если вы говорите на питоне и у вас есть немного времени - вы знаете, что делать.
Изменить: В более новых версиях Мелд, Синакс немного изменился. Это было в комментариях, но это относится к ответу.
Команда meld теперь использует параметр --output, поэтому последняя строка из приведенного выше фрагмента должна быть:
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED
Есть 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
файл.
Решение 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
С Meld 1.7 решение Томека Бери больше не работает.
Настройки по умолчанию меня не удовлетворяли:
Вместо Meld >=1,7 я предлагаю одно из двух других решений.
Первое решение:
meld $LOCAL $BASE $REMOTE --auto-merge
Второе решение:
meld $LOCAL $MERGED $REMOTE
.gitconfig
Скопируйте и вставьте это в свой .gitconfig
файл, чтобы получить решения, как описано выше:
[merge]
tool = meld16
[mergetool "meld17"]
# use this for Meld >=1.7
# see http://stackru.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://stackru.com/a/9733277/859591
[merge]
tool = meld17
Я обнаружил, что ни один из файлов по умолчанию не был сохранен. Мельд показывал $LOCAL
, $REMOTE
а также $BASE
по умолчанию. Чтобы это сработало, мне нужно было сделать смешное шоу $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
По некоторым причинам в новейших версиях meld не отображаются строки маркеров, добавленные для конфликтов (<<<<<<<, =======, >>>>>>>). Если вы хотите увидеть эти строки, вам следует установить meld v 1.3.3 или более раннюю версию.
Пожалуйста, смотрите ответ Саада для правильного ответа.
С Meld 1.8.1 на Ubuntu я получал
неверное количество аргументов, переданных в --diff
и добавив --output до того, как $MERGED исправил это для меня:
[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED