Какая версия файла git будет окончательно использована: ЛОКАЛЬНАЯ, БАЗОВАЯ или УДАЛЕННАЯ?

Когда во время git merge происходит столкновение, я открываю объединяющий инструмент под названием Meld. Он открывает три файла LOCAL, BASE и REMOTE. Поскольку я читал, что LOCAL - это моя локальная ветвь, BASE - это общий предок, а REMOTE - это ветвь, которую нужно объединить.

Теперь к моему вопросу: какая версия файла будет в конечном итоге использована? Это УДАЛЕННЫЙ? Если да, могу ли я отредактировать его как хочу, независимо от того, что находится, например, в ветке BASE?


person tsusanka    schedule 21.06.2012    source источник


Ответы (8)


Это тот, что посередине: BASE.

Фактически, BASE не является общим предком, а является незавершенным слиянием, где конфликты отмечены >>>> и <<<<.

Вы можете увидеть имена файлов в верхней части окна редактирования объединения.

См. снимок экрана здесь

meld base

Вы можете редактировать BASE файл по своему усмотрению, используя или не используя команды meld.
Вы также можете избавиться от meld и просто отредактировать файл в своем любимом текстовом редакторе.

  • Код между маркерами <<<< HEAD и ===== - это код вашего локального файла до слияния.
  • Код между ==== и >>>> <branch name> - это код удаленного файла.
person Fabien Quatravaux    schedule 21.06.2012
comment
Некоторые люди лучше понимают конфликтующие фрагменты в файле, которые не удалось автоматически объединить, если для параметра конфигурации merge.conflictstyle установлено значение diff3 вместо значения по умолчанию merge. - person kostix; 22.06.2012
comment
Я вообще-то не вижу HEAD, поет ‹** и ===. В случае, если вы указали, среднее окно будет пустым. Но это всего лишь примечание для остальных, спасибо за ответ. - person tsusanka; 22.06.2012
comment
Если вы не видите знаков HEAD, <<<<< и =====, это означает, что конфликта нет вообще. В этом случае среднее окно не будет пустым, в нем будет показан результат слияния, но не будет красной части. - person Fabien Quatravaux; 23.06.2012
comment
Когда я выполняю слияние с Meld, я также не вижу маркеров <<<<<<, ====== или >>>>>> на средней панели (т. Е. В БАЗОВОЙ версии); а иногда средняя панель будет пустой, как сообщает aGr. Возможно эта разница из-за разных настроек. Когда я запускаю инструмент Meld, следующие файлы будут существовать, если предположить, что имя файла в репозитории X.java: X.java, X.java.orig, X.java.BACKUP.#, X.java.BASE.#, X.java.LOCAL.#, X.java.REMOTE.#, где # - некоторое число. Вызов результата слияния БАЗОВОЙ версией сбивает с толку; MERGED было бы лучше. - person Teemu Leisti; 24.09.2012
comment
BASE - это фактически общий предок, MERGED - это имя файла с информацией о частичном слиянии в нем. См. Мой вопрос и ответ Настройка и использование Объедините как ваш git difftool и mergetool, который точно объясняет, как это работает. HTH. - person mattst; 06.12.2015
comment
Причина, по которой вы не видите HEAD, <<<<, & ====, заключается в том, что при настройке конфигурации по умолчанию для среднего окна установлено значение $ BASE (предок). Если вы переключите свою конфигурацию на cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED", тогда ваше среднее значение будет $ MERGED, и вы увидите <<<, === и т. Д. См. эта тема - person Brandon Loudermilk; 02.06.2017
comment
это может быть правильным для Meld, но в целом безумно сбивает с толку - BASE определенно является общим предком, насколько это касается git, например см. другой ответ - person supervacuo; 18.04.2018
comment
Неправильно - База - общий предок. - person ANewGuyInTown; 31.07.2020

В Meld есть скрытая функция трехстороннего слияния, которая активируется путем передачи четвертого параметра:

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-я вкладка, открытая по умолчанию, показывает трехстороннее представление слияния.

Причина, по которой эта функция скрыта, заключается в том, что она еще недостаточно доработана. Это очень полезно и сейчас, но Кай Уилладсен, автор слияния, указал на несколько морщин, которые нужно разгладить. Например, нет графического интерфейса для запуска режима 3-стороннего слияния, синтаксис командной строки немного запутан и тому подобное. Если вы говорите на питоне и у вас есть свободное время - вы знаете, что делать.

Изменить: в более новых версиях Meld немного изменился синтаксис. Это было в комментариях, но это должно быть в ответе.

Команда meld теперь использует параметр --output, поэтому последняя строка из приведенного выше фрагмента должна быть:

cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED
person Tomek Bury    schedule 19.09.2012
comment
@Jesse Кажется, это работает с Meld 1.6.0, но не с Meld 1.7.0. - person lumbric; 21.01.2014
comment
@Jesse, @lumbric, похоже, что более новые версии meld используют флаг --output для результата $ MERGED. Я обнаружил это, глядя на скрипт запуска meld, который поставлялся с моей версией git: github.com/git/git/blob/master/mergetools/meld - person Johann; 12.02.2014
comment
@Johann Хм, да, вы правы, но это не решает проблемы. Сценарий запуска, который вы связали, не обеспечивает расширенных функций, описанных в решении Томека Бери. - person lumbric; 07.04.2014
comment
@lumbric Я думаю, что да, для Meld 1.7.x + с --output option. См. Эту строку в сценарии запуска: "$merge_tool_path" --output "$MERGED" "$LOCAL" "$BASE" "$REMOTE" - person Johann; 07.04.2014
comment
@ Джоханн Да. Вы правы, спасибо большое! На самом деле последняя версия git поставляется с правильно настроенным сценарием запуска. После обновления dist я заметил, что моя конфигурация meld больше не работает. Простое удаление моей пользовательской конфигурации для meld решает все проблемы. - person lumbric; 08.04.2014
comment
В последней версии meld (версия ›1.8.4) мы должны использовать параметр --auto-merge. cmd = meld --diff $ BASE $ LOCAL --diff $ BASE $ REMOTE --auto-merge $ LOCAL $ BASE $ REMOTE --output $ MERGED - person RoboAlex; 25.10.2014
comment
В Meld 1.8.4 третья вкладка не открывается по умолчанию. Мой .gitconfig содержит: [merge] tool = mymeld conflictstyle = diff3 [mergetool "mymeld"] cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --auto-merge $LOCAL $BASE $REMOTE --output $MERGED - person pingpongboss; 28.07.2015
comment
У меня была та же проблема, что и у @pingpongboss при использовании Meld 1.8.4: Meld открывал вещи на отдельной панели, вместо того, чтобы открывать третью вкладку. Команда, которая наконец-то сработала нормально: cmd = meld $LOCAL $BASE $REMOTE --auto-merge --output $MERGED. Итак, это открывает 3 вкладки (старый добрый способ), автоматическое слияние неконфликтных слияний в середину, где середина $ MERGED, и будет использоваться в качестве выходных данных разрешения конфликтов. - person farmir; 25.09.2015
comment
Синтаксис вывода может быть --output=<file> или -o <file>, см. meld --help - person levsa; 11.11.2015
comment
Часть, которую мне не хватало, чтобы заставить это работать, заключается в том, что я не знал, какую командную строку git нужно запустить, чтобы заставить это работать: git merge otherbranch, за которым следует git mergetool. Вторая команда запускает слияние для каждого конфликтующего файла. - person Edwin Hoogerbeets; 15.02.2017
comment
Я вижу, что использование более короткого meld $LOCAL $BASE $REMOTE --output $MERGED работает нормально. Для чего нужны три отдельных --diff в командной строке? Я не могу заставить его (команда с --diff) работать с моим SourceTree (в Windows) - Meld открывается нормально, но SourceTree преждевременно считает слияние завершенным. - person aff; 01.03.2017

Здесь задействованы 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) и позволяет вам < em> полностью выполнить слияние с нуля.

Суть в том, что в конфликтах ручного и визуального слияния вы не просматриваете одни и те же файлы, а конечный результат записывается в один и тот же файл (это файл $MERGED).

Ручное исправление конфликтов выполняется $MERGED, потому что git не имеет возможности представить вам три файла, поэтому он сжимает информацию из трех файлов ($LOCAL, $BASE, $REMOTE) в этом $MERGED файле.

Но у визуальных инструментов есть средства, чтобы показать вам три файла: они показывают вам файлы $LOCAL, $BASE, $REMOTE. Вы выбираете изменения из файлов $LOCAL и $REMOTE и вносите их в файл $BASE, полностью перестраивая и даже перезаписывая неудачную попытку слияния, то есть файл $MERGED.

person user1284631    schedule 02.08.2013
comment
Я просто хотел, чтобы были инструменты (например, вне всякого сравнения), которые показывают все 4 файла. - person yoniLavi; 30.12.2013
comment
@yoniYalovitsky: да, или p4merge - person user1284631; 31.12.2013
comment
Раньше я использовал инструмент слияния из пакета ClearCase - person mishmashru; 20.03.2015
comment
@yoniLavi - ну, эти инструменты показывают 4 панели, но не обязательно все четыре файла, как описано в этом ответе. В частности, вы можете настроить эти 4-панельные инструменты, чтобы показать вам $LOCAL, $REMOTE, $BASE и результат, изначально равный $BASE, но который отличается от $MERGED тем, что в нем нет попытки git объединить файлы и конфликт маркеры и тд. Фактически, это был бы способ использования этих инструментов, который больше всего похож на трехпанельный подход LOCAL / REMOTE / BASE + OUTPUT, который не отображается объединенным. 4-я панель просто позволяет вам отделить базу от вывода. - person BeeOnRope; 16.08.2018

Решение 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
person Saad Malik    schedule 06.03.2014
comment
Я могу подтвердить это, решение Саада у меня работает на Ubuntu. Что касается исходного вопроса, это текущий правильный ответ. - person cosmin; 14.03.2014
comment
В моей версии meld - 3.11 отлично работает эта команда: cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE - person MartinM; 07.01.2015
comment
зачем тебе --diff $BASE $LOCAL --diff $BASE $REMOTE в конце? для меня на 1.8.4 это работает нормально (насколько я понимаю): cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE - person farmir; 25.09.2015
comment
@farmir: В этом нет необходимости. Он открывает еще две вкладки в сочетании, чтобы вы могли видеть ЛОКАЛЬНОЕ и УДАЛЕННОЕ в сравнении с БАЗОВОЙ по отдельности. - person Sam Kauffman; 01.12.2015
comment
Независимо от того, какой порядок я пытаюсь использовать с этими аргументами, трехсторонняя вкладка всегда является третьей вкладкой, а первая вкладка всегда выбирается по умолчанию. Есть ли способ сделать трехстороннюю вкладку выбранной по умолчанию? - person Sam Kauffman; 01.12.2015
comment
Я обновился до Debian 9, и вместе с ним появился Meld 3.16.4, который больше не работает. Meld открывает только одну вкладку, хотя команда включает три вкладки. Кто-нибудь знает, как это исправить? - person Sam Kauffman; 16.08.2017

В 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://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
person lumbric    schedule 07.04.2014
comment
Это не работает в Meld 1.8.4. Если вы запустите cmd = meld $LOCAL $BASE $REMOTE --auto-merge, средняя панель будет $ BASE, а не $ MERGE, которая фактически используется как результат разрешения конфликтов. - person farmir; 25.09.2015
comment
@farmir Вы выбрали $ BASE в качестве второй вкладки. - person Alex78191; 06.05.2017

Я обнаружил, что ни один из показанных файлов по умолчанию не сохраняется. 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
person Thomas Leonard    schedule 22.03.2013
comment
Простите, совместима ли эта конфигурация с inux? - person MadMad666; 02.08.2016

По какой-то причине в новейших версиях meld не отображаются линии маркеров, добавленные для конфликтов. Если вы хотите увидеть эти строки, вам следует установить meld v 1.3.3 или более раннюю.

person wnasich    schedule 04.09.2013
comment
Я нашел полезным ответ @lumbric stackoverflow.com/a/22911793/641892 - person wnasich; 27.07.2017

Правильный ответ см. В ответе Саада.

С meld 1.8.1 на Ubuntu я получал

неправильное количество аргументов передано --diff

и добавив --output до того, как $ MERGED исправил это для меня:

[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED
person cosmin    schedule 05.03.2014