четверг, 19 ноября 2015 г.

Подружить git и meld за 5 минут

Я не то что бы знаток git, но мне искренне больно смотреть, как некоторые люди пользуются встроенными в IDE инструментами для мёржа или просмотра diff-ов. Особенно когда вокруг так много гораздо более удобных утилит для этой задачи, причём когда настроить взаимодействие git с подобными утилитами это дело 5 минут, включая чтение документации.


Я буду приводить примеры для meld: это бесплатная утилита для просмотров diff-ов с весьма приятным отображением разницы в файлах:
При желании можно сравнить 2 разные директории:
Так же там присутствует 3-х сторонний merge:
В добавок она ещё и кроссплатформенная. На мой вкус это лучший бесплатный инструмент для подобных вещей. С araxis конечно не сравниться, но последний может себе позволить далеко не каждый.

Итак начнём с diff-а. Первое что стоит сделать это посмотреть документацию у meld: "meld –help", из которой узнаём, что достаточно передать ему, в качестве параметров, 2 пути к сравниваемым файлам или директориям.

Теперь разберёмся с git, опять пойдём в документацию и вытащим из неё вот такие пару строк для git config:
[diff]
    tool = meld
[difftool "meld"]
    cmd = meld $LOCAL $REMOTE
Ну или для Windows вот так:
[diff]
    tool = meld
[difftool "meld"]
    cmd = meld.exe $LOCAL $REMOTE
Плюс для Windows нужно будет добавить директорию "meld.exe" в PATH.

В секции "difftool", как можно догадаться, определяется команда, для вызова внешнего инструмента. А в "diff" - название используемой секции по умолчанию.

Тут единственная магия это 2 служебных переменных, которые предоставляет git:

  • $LOCAL - это путь к временному файлу, в котором храниться текущее (локальное) состояние файла.
  • $REMOTE - это тоже путь к временному файлу, в котором храниться содержимое файла с которым мы будем сравнивать, в зависимости от параметров сравнения там может лежать например последняя закомиченная версия файла из ветки master.
Всё, теперь можно посмотреть например разницу между локальными изменениями и версиями файлов в HEAD, запустив:
$git difftool
Чуть улучшить результат можно вот так:
$git difftool --dir-diff
Теперь meld будет открывать не каждый файл по очереди, а покажет сразу все изменения, которые мы запросили в виде сравнения двух директорий.

Что бы не писать такую большую команду каждый раз, git даёт нам возможность настроить алиасы:
[alias]
    df = difftool --dir-diff
Теперь разницу между мастером и branch1, можно посмотреть вот так:
$git df master branch1
И т.д. думаю все возможные флаги diff команды вы знаете не хуже меня.

Для мержа всё не сильно сложнее, опять смотрим справку по meld, там пишут что нужно в качестве параметров указать 3 файла и в параметре "–output" указать какой из них использовать для сохранения результата.

Для git тоже обратимся к документации и получим вот это:
[alias]
    mt = mergetool -t meld
[merge]
    tool = meld
[mergetool "meld"]
    prompt = false
    keepBackup = true
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output="$MERGED"
Из незнакомых опций тут следующие:

  • prompt = false - не делать запросов перед мёржем каждого файла.
  • keepBackup = true - создавать бекапы исходных файлов, перед объединением, хотя многим может не понравиться, т.к. их придётся потом удалять, но как отключить такое поведение я думаю понятно.
  • $MERGED - служебная переменная, в которой храниться файл, в который, как ожидает git мы запишем результат мёржа.
Ну и запуск, с учётом алиасов, выглядит вот так:
$git mt
Git в ответ будет последовательно открывать meld для каждого конфликта в режиме 3-х стороннего мёржа.

Всё вместе это выглядит вот так:
[alias]
    df = difftool --dir-diff
    mt = mergetool -t meld
[diff]
    tool = meld
[difftool "meld"]
    cmd = meld $LOCAL $REMOTE
[merge]
    tool = meld
[mergetool "meld"]
    prompt = false
    keepBackup = true
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output="$MERGED"
Конечно возможных параметров намного больше, но я не собирался пересказывать документацию, а хотел лишь показать подход, с помощью которого можно настроить взаимодействие git с подобного рода утилитами