Настройка и использование Meld в качестве вашего git difftool и mergetool


256

Хотя большая часть информации в этом вопросе и ответе доступна в StackOverflow , она разбросана по множеству страниц и среди других ответов, которые либо неверны, либо вводят в заблуждение. Мне потребовалось некоторое время, чтобы собрать воедино все, что я хотел знать.

Существует множество различных программ, которые можно использовать в качестве ваших git difftool и mergetool, и, безусловно, нет единого мнения относительно того, какой из них лучший (мнения, требования и операционные системы будут явно различаться).

Meld - это популярный бесплатный кроссплатформенный вариант с открытым исходным кодом (UNIX / Linux, OSX, Windows), как показано в вопросе StackOverflow. Какой лучший инструмент визуального слияния для Git? , в котором ответ на предложение Meld имеет более чем в 3 раза больше голосов, чем любой другой инструмент.

Следующие 2 вопроса будут даны ответы в моем ответе ниже:

  • Как мне настроить и использовать Meld в качестве моего git difftool?
  • Как мне настроить и использовать Meld в качестве моего git mergetool?

Примечание. Нет необходимости использовать одну и ту же программу как для difftool, так и для mergetool, для обоих можно установить разные программы.


Ответы:


423

Как мне настроить и использовать Meld в качестве моего git difftool?

git difftool отображает diff, используя программу сравнения GUI (т.е. Meld) вместо отображения результатов diff на вашем терминале.

Хотя вы можете установить программу с графическим интерфейсом в командной строке, -t <tool> / --tool=<tool>имеет больше смысла настраивать ее в своем .gitconfigфайле. [Примечание: см. Разделы об экранировании кавычек и путей Windows внизу.]

# Add the following to your .gitconfig file.
[diff]
    tool = meld
[difftool]
    prompt = false
[difftool "meld"]
    cmd = meld "$LOCAL" "$REMOTE"

[Примечание: эти настройки не изменят поведение, git diffкоторое продолжит функционировать как обычно.]

Вы используете git difftoolточно так же, как вы используете git diff. например

git difftool <COMMIT_HASH> file_name
git difftool <BRANCH_NAME> file_name
git difftool <COMMIT_HASH_1> <COMMIT_HASH_2> file_name

При правильной настройке окно Meld откроет отображение различий с использованием интерфейса GUI.

Порядок оконных окон Meld GUI может управляться порядком $LOCALи $REMOTEв cmd, то есть, какой файл отображается на левой панели, а какой - на правой. Если вы хотите их наоборот, просто поменяйте их местами так:

    cmd = meld "$REMOTE" "$LOCAL"

Наконец, prompt = falseстрока просто не дает git подсказывать вам, хотите ли вы запустить Meld или нет, по умолчанию git выдаст приглашение.


Как мне настроить и использовать Meld в качестве моего git mergetool?

git mergetool позволяет вам использовать программу слияния GUI (например, Meld) для разрешения конфликтов слияния, возникших во время слияния.

Как и difftool, вы можете установить программу с графическим интерфейсом в командной строке, используя, -t <tool> / --tool=<tool>но, как и прежде, имеет смысл настроить ее в своем .gitconfigфайле. [Примечание: см. Разделы об экранировании кавычек и путей Windows внизу.]

# Add the following to your .gitconfig file.
[merge]
    tool = meld
[mergetool "meld"]
    # Choose one of these 2 lines (not both!) explained below.
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"
    cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"

Вы НЕ используете git mergetoolдля фактического слияния. Перед использованием git mergetoolвы выполняете слияние обычным способом с помощью git. например

git checkout master
git merge branch_name

Если есть конфликт слияния, git отобразит что-то вроде этого:

$ git merge branch_name
Auto-merging file_name
CONFLICT (content): Merge conflict in file_name
Automatic merge failed; fix conflicts and then commit the result.

На этом этапе file_nameбудет содержаться частично слитый файл с информацией о конфликте слияния (это файл со всеми записями >>>>>>>и и <<<<<<<в нем).

Mergetool теперь можно использовать для разрешения конфликтов слияния. Вы начинаете это очень легко с:

git mergetool

При правильной настройке откроется окно Meld с отображением 3 файлов. Каждый файл будет содержаться в отдельной панели своего графического интерфейса.

В приведенном .gitconfigвыше примере в качестве строки предлагается 2 строки [mergetool "meld"] cmd. На самом деле у опытных пользователей есть все способы настройки cmdлинии, но это выходит за рамки этого ответа.

Этот ответ имеет 2 альтернативные cmdлинии, которые между ними будут ориентированы на большинство пользователей и станут хорошей отправной точкой для опытных пользователей, которые хотят поднять инструмент на новый уровень сложности.

Во-первых, вот что означают параметры:

  • $LOCAL это файл в текущей ветке (например, master).
  • $REMOTE это файл в объединяемой ветке (например, имя_в ветви).
  • $MERGED является частично слитым файлом с информацией о конфликте слияния.
  • $BASEявляется предком общего коммита $LOCALи $REMOTE, то есть файл, каким он был, когда $REMOTEизначально создавалась содержащая ветвь .

Я предлагаю вам использовать либо:

[mergetool "meld"]
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"

или:

[mergetool "meld"]
    cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"
    # See 'Note On Output File' which explains --output "$MERGED".

Выбор - использовать $MERGEDили $BASEмежду $LOCALи $REMOTE.

В любом случае Meld будет отображать 3 панели с $LOCALи $REMOTEв левой и правой панели и либо $MERGEDили $BASEв средней панели.

В обоих случаях средняя панель - это файл, который вы должны отредактировать для разрешения конфликтов слияния. Разница лишь в том, какую начальную позицию редактирования вы бы предпочли; $MERGEDдля файла, который содержит частично слитый файл с информацией о конфликте слияния или $BASEдля предка общего коммита $LOCALи $REMOTE. [Поскольку обе cmdстроки могут быть полезны, я храню их в своем .gitconfigфайле. Большую часть времени я использую $MERGEDстроку, и $BASEстрока закомментирована, но закомментирование можно поменять местами, если я хочу использовать $BASEстроку вместо этого.]

Note On Output File: Не волнуйтесь , что --output "$MERGED"используется в cmdнезависимо от того , $MERGEDили $BASEиспользовался ранее в cmdлинии. --outputВариант просто говорит оплавления , что имя файла мерзавец хочет файл разрешения конфликтов будет сохранен в. Meld сохранит ваши конфликтные изменения в этом файле , независимо от того, используете ли вы $MERGEDили в $BASEкачестве отправной точки для редактирования.

После редактирования средней панели для разрешения конфликтов слияния просто сохраните файл и закройте окно Meld. Git выполнит обновление автоматически, и файл в текущей ветке (например, master) теперь будет содержать все, что у вас получилось в средней панели.

git сделает резервную копию частично слитого файла с информацией о конфликте слияний, добавив .origк исходному имени файла. например file_name.orig. После проверки того, что вы удовлетворены слиянием, и запуска любых тестов, которые вы можете выполнить, .origфайл можно удалить.

На данный момент вы можете сделать коммит, чтобы зафиксировать изменения.

Если во время редактирования конфликтов слияния в Meld вы хотите отказаться от использования Meld, выйдите из Meld, не сохраняя файл разрешения слияния в средней панели. git ответит сообщением file_name seems unchangedи затем спросит Was the merge successful? [y/n], если вы ответите, nразрешение конфликта слияния будет прервано и файл останется без изменений. Обратите внимание, что если вы сохранили файл в Meld в любой момент, вы не получите предупреждение и подсказку от git. [Конечно, вы можете просто удалить файл и заменить его .origфайлом резервной копии , созданным для вас.]

Если у вас есть более 1 файла с конфликтами слияния, то git откроет новое окно Meld для каждого, одно за другим, пока они не будут завершены. Не все они будут открыты одновременно, но когда вы закончите редактировать конфликты в одном и закроете Meld, git откроет следующий и так далее, пока все конфликты слияния не будут разрешены.

Было бы разумно создать фиктивный проект, чтобы проверить его использование, git mergetoolпрежде чем использовать его в живом проекте. Обязательно используйте имя файла, содержащее пробел в вашем тесте, на случай, если ваша ОС требует экранирования кавычек в cmdстроке, см. Ниже.


Экранирующие символы цитаты

Некоторым операционным системам может потребоваться cmdэкранировать кавычки . Менее опытные пользователи должны помнить, что командные строки config должны быть проверены с именами файлов, которые содержат пробелы, и если cmdстроки не работают с именами файлов, которые содержат пробелы, попробуйте экранировать кавычки. например

cmd = meld \"$LOCAL\" \"$REMOTE\"

В некоторых случаях может потребоваться более сложное экранирование кавычек. Первая из ссылок пути Windows ниже содержит пример тройного экранирования каждой кавычки. Это зануда, но иногда необходимо. например

cmd = meld \\\"$LOCAL\\\" \\\"$REMOTE\\\"

Пути Windows

Пользователям Windows, вероятно, понадобится дополнительная настройка, добавленная к cmdлиниям Meld . Им может понадобиться использовать полный путь к meldc, который предназначен для вызова в Windows из командной строки, или им может понадобиться или захотеть использовать оболочку. Они должны прочитать страницы StackOverflow, ссылки на которые приведены ниже и посвящены настройке правильной cmdлинии Meld для Windows. Поскольку я пользователь Linux, я не могу протестировать различные cmdстроки Windows и не имею никакой дополнительной информации по этому вопросу, кроме как рекомендовать использовать мои примеры с добавлением полного пути к Meld meldcили добавлением папки программ Meld в вашу path.

Игнорирование конечных пробелов с Мелдом

У Meld есть ряд параметров, которые можно настроить в графическом интерфейсе.

На Text Filtersвкладке настроек есть несколько полезных фильтров, которые игнорируют такие вещи, как комментарии, при выполнении сравнения. Хотя есть фильтры, которые нужно игнорировать, All whitespaceи фильтр Leading whitespaceигнорирования отсутствует Trailing whitespace(это было предложено в качестве дополнения в списке рассылки Meld, но недоступно в моей версии).

Игнорирование конечных пробелов часто очень полезно, особенно при совместной работе, и может быть легко добавлено вручную с помощью простого регулярного выражения на Text Filtersвкладке настроек Meld .

# Use either of these regexes depending on how comprehensive you want it to be.
[ \t]*$
[ \t\r\f\v]*$

Я надеюсь, что это помогает всем.


2
Спасибо, что так гораздо проще использовать [mergetool "meld"] cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"в ~/.gitconfig, то просто разрешить конфликты , выделенные красным цветом в средней кастрюле и сохранить! Это должна быть настройка по умолчанию.
KrisWebDev

1
$LOCAL $MERGED $REMOTEэто настройка, которую я использую большую часть времени, когда есть только несколько конфликтов, чтобы решить, это превосходно, и это также по умолчанию. $LOCAL $BASE $REMOTEдействительно приходит в себя, когда есть чем заняться, и вы точно знаете, какие разделы кода поступают из какого файла; предок общего коммита может быть отличной отправной точкой, свободной от беспорядка, иногда на самом деле мешает выделение конфликтов, а чистая основа - это благословение.
Mattst

4
Примечание. Если вы работаете в OSX и установили соединение через homebrew, для выходного параметра потребуется =следующее:cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output="$MERGED"
Alteisen

2
Для пользователей Mac, которые установили .dmg и обнаружили, что 'meld' не в их пути, обязательно следуйте альтернативному набору инструкций здесь: yousseb.github.io/meld
KC Baltz

3
Это намного лучше, чем объяснение в Git Configuration - git mergetool . Большое спасибо, особенно за объяснение разницы между $ MERGED и $ BASE. Спас меня от сумасшествия!
ChrisG

81

Хотя другой ответ верен, вот самый быстрый способ просто настроить Meld как инструмент визуального сравнения. Просто скопируйте / вставьте это:

git config --global diff.tool meld
git config --global difftool.prompt false

Теперь запустите git difftoolв каталоге, и Meld будет запущен для каждого отдельного файла.

Примечание: Мелд удивительно медленно сравнивает CSV-файлы, и ни один инструмент Linux diff, который я обнаружил, не работает быстрее, чем этот инструмент Windows под названием Compare It! (последнее обновление в 2010 году).


13
Вы, вероятно, хотите git config --global difftool.meld.cmd 'meld "$LOCAL" "$REMOTE"'линию там тоже. Это «значение по умолчанию», но как только вы настроите a mergetool, difftoolон начнет использовать конфигурацию mergetool в качестве значения по умолчанию, если не найден diff config. Поскольку слияние обычно настроено на передачу трех файлов для трехстороннего слияния, это означает, что в вашем meld разностном окне внезапно появятся три панели, которые не имеют никакого смысла.
BeeOnRope

Почему бы не проверить конфигурацию после установки с помощью $ git config -l
agfe2

56

Для Windows . Запустите эти команды в Git Bash:

git config --global diff.tool meld
git config --global difftool.meld.path "C:\Program Files (x86)\Meld\Meld.exe"
git config --global difftool.prompt false

git config --global merge.tool meld
git config --global mergetool.meld.path "C:\Program Files (x86)\Meld\Meld.exe"
git config --global mergetool.prompt false

(Обновите путь к файлу для Meld.exe, если у вас другой.)

Для Linux . Запустите эти команды в Git Bash:

git config --global diff.tool meld
git config --global difftool.meld.path "/usr/bin/meld"
git config --global difftool.prompt false

git config --global merge.tool meld
git config --global mergetool.meld.path "/usr/bin/meld"
git config --global mergetool.prompt false

Вы можете проверить путь Мелда, используя эту команду:

which meld

1
Я получаю сообщение об ошибке при запуске git difftool «Объединение инструментов сравнения недоступно как« D: \ software \ melddiff \ Meld.exe »»
Аллен Ворк,

@AllenVork: Вы подтвердили, что Meld.exe находится в указанной вами папке? Можете ли вы запустить его за пределами Git успешно? Что возвращает Git при запуске git config --global --get-regex diff*?
MarredCheese

Я решил это. Я изменяю его на «D: /software/melddiff/Meld.exe», и он работает. Формат .gitconfig - это Ubuntu, а не Windows.
Аллен Ворк

Не должно быть: git config --global difftool.meld.path "C:\Program Files (x86)\Meld\Meld.exe"?
Джонатан Розен

@AllenVork, вы используете Git для Cygwin?
Адриан

25

Я предпочитаю настраивать объединение как отдельную команду, например так:

git config --global alias.meld '!git difftool -t meld --dir-diff'

Это делает его похожим на скрипт git-meld.pl здесь: https://github.com/wmanley/git-meld

Вы можете просто запустить

git meld

Я только что работал с Cygwin, и теперь он сломался. Это исправило это. Спасибо! (Хотя я удалил --dir-diffчасть как личное предпочтение.)
PfunnyGuy

3

Для Windows 10 я должен был поместить это в мой .gitconfig:

[merge]
  tool = meld
[mergetool "meld"]
  cmd = 'C:/Program Files (x86)/Meld/Meld.exe' $LOCAL $BASE $REMOTE --output=$MERGED
[mergetool]
  prompt = false

Все остальное, что вам нужно знать, написано в этом супер ответе Mattst далее выше.

PS: Почему-то это работало только с Meld 3.18.x, Meld 3.20.x выдает ошибку.


1

Это ответ, ориентированный в первую очередь на разработчиков, использующих Windows, поскольку синтаксис пути инструмента diff отличается от других платформ.

Я использую Kdiff3 в качестве git mergetool, но чтобы настроить git difftool как Meld, я сначала установил последнюю версию Meld с Meldmerge.org, а затем добавил следующее в мой глобальный .gitconfig, используя:

git config --global -e

Обратите внимание: если вы предпочитаете Sublime Text 3 вместо Vim по умолчанию в качестве основного редактора, вы можете добавить его в файл .gitconfig:

[core]
editor = 'c:/Program Files/Sublime Text 3/sublime_text.exe'

Затем вы добавляете Inn Meld в качестве difftool

[diff]
tool = meld
guitool = meld 

[difftool "meld"]
cmd = \"C:/Program Files (x86)/Meld/Meld.exe\" \"$LOCAL\" \"$REMOTE\" --label \"DIFF 
(ORIGINAL MY)\"
prompt = false
path = C:\\Program Files (x86)\\Meld\\Meld.exe

Обратите внимание на косую черту в cmd выше, в Windows это необходимо.

Также можно настроить псевдоним для отображения текущего git diff с параметром --dir-diff . Это выведет список измененных файлов внутри Meld, что удобно, когда вы изменили несколько файлов (действительно очень распространенный сценарий).

Псевдоним выглядит так внутри файла .gitconfig, ниже раздела [alias] :

showchanges = difftool --dir-diff

Чтобы показать изменения, которые я внес в код, я просто введите следующую команду:

git showchanges

На следующем рисунке показано, как эта опция --dir-diff может отображать список измененных файлов (пример): Meld показывает список файлов с изменениями между $ LOCAL и $ REMOTE

Затем можно нажать на каждый файл и показать изменения внутри Meld.


0

Может быть сложно вычислить разницу в вашей голове из различных разделов в $ MERGED и применить это. В моей настройке meld помогает, показывая вам эти различия визуально, используя:

[merge]
    tool = mymeld
    conflictstyle = diff3

[mergetool "mymeld"]
    cmd = meld --diff $BASE $REMOTE --diff $REMOTE $LOCAL --diff $LOCAL $MERGED

Это выглядит странно, но предлагает очень удобный рабочий процесс, используя три вкладки:

  1. на вкладке 1 вы видите (слева направо) изменение, которое вы должны внести на вкладке 2, чтобы разрешить конфликт слияния.

  2. в правой части вкладки 2 вы применяете «изменения, которые вы должны внести» и копируете все содержимое файла в буфер обмена (используя ctrl-a и ctrl-c).

  3. на вкладке 3 замените правую сторону содержимым буфера обмена. Если все правильно, теперь вы увидите - слева направо - то же самое изменение, как показано на вкладке 1 (но в других контекстах). Сохраните изменения, сделанные на этой вкладке.

Ноты:

  • не редактируйте ничего на вкладке 1
  • не сохраняйте ничего на вкладке 2, потому что это приведет к раздражающим всплывающим окнам на вкладке 3

Это лучше, чем трехстороннее слияние (локальное / базовое / удаленное) в одной вкладке?
Андре Верланг

@ AndréWerlang Преимущество трехстороннего слияния на одной вкладке заключается в том, что вам нужно иметь дело только с конфликтующими изменениями (другие изменения объединяются автоматически). Но я предпочитаю «мой» подход в тех случаях, когда при трехстороннем объединении трудно понять, что изменилось, и как объединить таким образом, чтобы сохранить все изменения. Если в какой-то момент трехстороннее слияние больше не смущает меня, я могу вернуться к нему.
mnieber

Как указал пользователь mattst, вы можете использовать $BASEвместо того, $MERGEDчтобы начать операцию слияния
Андре Werlang
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.