Какая версия файла 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