Обзор инструментов для визуального сравнения и разрешения конфликтов слияния

в 12:40, , рубрики: DVCS, Git, Mercurial, разработка, Системы управления версиями, метки: , ,

На хабре уже было много статей о распределенных системах управления версиями (DVCS), их сравнений, а также сравнений GUI-клиентов для них. Также были обсуждения плагинов к IDE для работы с git и mercurial. Но практически не было информации об инструментах визуального сравнения и разрешения конфликтов слияния.

Pistol

Недавно я «перескочил» с mercurial (который до сих пор считаю более удобным и логичным) на git, потому что, подавляющее большинство проектов, которые мне интересны, используют git и хостятся на github. В связи с этим, встал вопрос о пересмотре арсенала инструментов, в частности вопрос выбора инструмента визуального сравнения и слияния (diff and merge). По горячим следам, я решил написать этот мини-обзор.

Под катом Вы также найдете примеры настроек Git для использования с DiffMerge и WinMerge под Windows. Думаю многим сэкономит время.

Название Особенности Платформа

KDiff3

http://kdiff3.sourceforge.net/

[скриншот]

С этим инструментом скорее всего сталкивались как пользователи git, так и пользователи системы mercurial, так что оставлю эту ячейку «без комментариев».
Примечание: устанавливается вместе с TortoiseHg.
Windows, Mac OS X, Linux

DiffMerge

http://www.sourcegear.com/diffmerge/index.html

[скриншот]

Плюсы:

  • бесплатен;
  • поддерживает трехстороннее слияние.

Минусы:

  • к сожалению, у DiffMerge проблемы при работе с кириллицей. На данный момент я не нашел решения этой проблемы, может кто-то в комментариях подскажет.
  • DiffMerge по умолчанию, не поддерживает подсветку синтаксиса языков программирования.

Windows, Mac OS X, Linux

WinMerge

http://www.winmerge.org
http://ru.wikipedia.org/wiki/Winmerge

[скриншот]

Плюсы:

  • Open Source;
  • никаких проблем с кодировками;
  • подсветка синтаксиса без лишних телодвижений.

Минусы:

  • инструмент слияния является двусторонним, что может создавать неудобства в некоторых случаях;
  • only Windows.

Примечание: этим инструментом я начал пользоваться очень давно (еще до того, как стал использовать mercurial и git) и тот факт, что инструмент слияния является двусторонним в большинстве случаев не доставляет особых неудобств.

Windows

SmartSynchronize

http://www.syntevo.com/smartsynchronize/index.html

[скриншот]

Плюсы:

  • трехстороннее слияние;
  • нет проблем с кодировками;
  • помимо файлов, может сравнивать директории.

Минусы:

  • для коммерческого использования требуется лицензия;
  • подсветка синтаксиса для языков программирования по умолчанию не предусмотрена. Не исключено, что можно как-то сделать.

Примечание: SmartySynctonize встроен в программу SmartGit — удобный GUI-инструмент для работы с Git (тоже бесплатен для некоммерческого использования).

Windows, Mac OS X, Linux

BeyondCompare

http://www.scootersoftware.com/
http://en.wikipedia.org/wiki/Beyond_Compare

[скриншот]

Плюсы:

  • трехстороннее слияние;
  • может сравнивать файлы, директории, удаленные директории, архивы, а также MP3-файлы, изображения и др. Но последние пункты — это в принципе не нужный функционал.

Минусы:

  • ShareWare.

Windows, Linux

Meld

http://meld.sourceforge.net/

[скриншот]

Данный инструмент я не пробовал в действии, т.к. для установки под Windows требуется установить Python, GTK+, Glib, GtkSourceView, что не каждому понравиться.
На официальном сайте сказано о поддержке двустороннего и трехстороннего слияния.
Meld распространяется под лицензией GPL v2.
Windows, Linux
Инструкция по установке под Windows:
https://live.gnome.org/Meld/Windows

В принципе, все перечисленные инструменты хорошо справляются со своими задачами и данный обзор не тема для спора, т.к. каждый выбирает инструмент по вкусу.
Далее приводятся примеры настроек Git для работы с DiffMerge и WinMerge. По аналогии можно настроить взаимодействие Git с другими инструментами.

Git и DiffMerge

1) Добавим в директорию c:/Git/libexec/git-core/mergetools/
файл diffmerge следующего содержания:

diff_cmd () {
   "c:/Program Files/SourceGear/Common/DiffMerge/sgdm.exe" 
       "$LOCAL" "$REMOTE" >/dev/null 2>&1
}

merge_cmd () {
   "c:/Program Files/SourceGear/Common/DiffMerge/sgdm.exe" 
   --merge --result="$MERGED" "$LOCAL" "$BASE" "$REMOTE" >/dev/null 2>&1

   status=$?
}

2) Теперь добавим в файл c:/Users/swipe/.gitconfig
следующие строки:

[diff]    
   tool = diffmerge
[merge]
   tool = diffmerge
[mergetool "diffmerge"]
   cmd = "diffmerge"
   trustExitCode = true

3) Создадим конфликт и вызовем DiffMerge для его разрешения

git init // инициализируем репозиторий
создадим пустой файл readme.txt
git add . // добавим созданный файл в индекс
git commit -m "empty readme" // зафиксируем изменения
git branch new // создадим новую ветку
git checkout new // переключимся на новую ветку
добавим строку в файл readme.txt
git add . // добавим изменения в индекс
git commit -m "new string" // зафиксируем изменения в новой ветке
git checkout master // переключися на master ветку
добавим изменения в файл readme.txt
git add . // добавим изменения в индекс
git commit -m "master string" // зафиксируем их
git hist --all // посмотрим на дерево

tree

git difftool master new // сравним две ветви

diff

git merge new // сольем изменения в new с веткой master

conflict

Выводится сообщение о конфликте слияния, чего мы и добивались.

git mergetool // разрешим этот конфликт

merge

В среднем окне, приведем файл к требуемому состоянию и сохраним изменения.
Конфликт разрешен.

Настройку DiffMegre подсмотрел тут:
http://twobitlabs.com/2011/08/install-diffmerge-git-mac-os-x/

Git и WinMerge

1) Добавим в директорию c:/Git/libexec/git-core/mergetools/
файл winmerge следующего содержания:

diff_cmd () {
   "c:/Program Files (x86)/WinMerge/WinMergeU.exe" 
       "$LOCAL" "$REMOTE" >/dev/null 2>&1
}

merge_cmd () {
   "c:/Program Files (x86)/WinMerge/WinMergeU.exe" 
   "$PWD/$LOCAL" "$PWD/$REMOTE" "$PWD/$MERGED" >/dev/null 2>&1

   status=$?
}

Когда Git не может автоматически объединить изменения, происходит конфликт слияния и в конфликтующий файл добавляются маркеры слияния (<<<<<<<, =======, и >>>>>>>). Они необходимы для разрешения конфликта с помощью сторонних инструментов.
Рассмотрим файл redme.txt который образуется в результате выполнения слияния веток master и new в приведенном выше примере:

<<<<<<< HEAD
master str
=======
new str
>>>>>>> new

Мы можем открыть файл конфликтов с помощью программы WinMerge для разрешения конфликта.

open

После этого откроется средство двухстороннего слияния:

winmerge

Исходя из описанной логики перепишем команду слияния merge_cmd следующим образом:

merge_cmd () {
   "c:/Program Files (x86)/WinMerge/WinMergeU.exe" 
       "$MERGED" >/dev/null 2>&1

   status=$?
}

По сути, оба приведенных варианта эквивалентны.

2) Отредактируем .gitconfig

[diff]    
   tool = winmerge
[difftool "winmerge"]
   cmd = "winmerge"

[merge]
   tool = winmerge
[mergetool "winmerge"]
    cmd = "winmerge"
    trustExitCode = false  
    keepBackup = false

последняя строчка отменяет сохранение backup-файлов в директории репозитория.

3) Создадим конфликт при слиянии двух веток (см. пример с использованием DiffMerge).

git difftool master new // сравним две ветви

windiff

Для разрешения конфликта при слиянии веток, воспользуемся командой

git mergetool

winmerge

Отредактируем наш файл. После сохранения изменений, конфликт будет разрешен.

Настройки WinMerge подсмотрел тут:
http://stackoverflow.com/questions/636253/msys-git-merge-tool-command-options-issue

Автор: vitalyswipe


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js