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

  1. $LOCAL Файл на ветке, где вы объединяете; не тронут процесс слияния при показе вам

  2. $REMOTE Файл на ветке, из которой вы сливаетесь; не тронут процесс слияния при показе вам

  3. $BASE Общий предок $LOCAL и $REMOTE, т.е. точка, в которой две ветви начали отклонять рассматриваемый файл; не тронут процесс слияния при показе вам

  4. $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
Другие вопросы по тегам