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

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

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

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

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

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

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

Ответ 1

Как мне настроить и использовать 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 выше примере записи .gitconfig качестве строки cmd [mergetool "meld"] строки. На самом деле у опытных пользователей есть все способы настройки строки 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 и $MERGED или $BASE на средней панели.

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

Примечание к --output "$MERGED" файлу: не беспокойтесь о том, что --output "$MERGED" используется в cmd независимо от того, использовались ли ранее $MERGED или $BASE в строке cmd. Опция --output просто сообщает Meld, в каком имени файла git требуется сохранить файл разрешения конфликта. 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] 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, вероятно, потребуется дополнительная настройка, добавленная в строки Meld cmd. Им может понадобиться использовать полный путь к meldc, который предназначен для meldc в Windows из командной строки, или им может понадобиться или захотеть использовать оболочку. Они должны прочитать страницы StackOverflow, ссылки на которые приведены ниже и посвящены настройке правильной строки Meld cmd для Windows. Поскольку я являюсь пользователем Linux, я не могу протестировать различные строки Windows cmd и не имею никакой дополнительной информации по этому вопросу, кроме как рекомендовать использовать мои примеры с добавлением полного пути к 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

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

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

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

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

Ответ 3

Для 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

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

which meld

Ответ 4

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

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

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

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

git meld

Ответ 5

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

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

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

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

Ответ 6

Это ответ, предназначенный в первую очередь для разработчиков, использующих 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 showing list of files with changes between the $LOCAL and $REMOTE

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

Ответ 7

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

[merge]
    tool = mymeld
    conflictstyle = diff3

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

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

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

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

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

Примечания:

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