четверг, 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 с подобного рода утилитами

10 комментариев:

  1. > это бесплатная утилита

    RMS бы тебя заживо съел))

    ОтветитьУдалить
    Ответы
    1. А что не так-то? Что-то из сериала "Свободное не значит бесплатное" ?

      Удалить
    2. Ты же эмаксер, как у тебя рука поднимается так опошлять gpl, опуская до уровня жалких мирских денежных отношений? )) "Как свобода слова, а не халявный пивас" и все такое, ага)

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

      Удалить
    3. Ну в данном случае я говорю именно о "халявном пивасе", я бы с удовольствием пользовался araxis pro, не обращая внимание на лицензию, но он стоит запредельных 249.00 €

      Удалить
  2. Добавил статью в закладки, очень полезно. Сегодня проблемы с твитором, когда починят - там тоже ссылку опубликую. Спасибо!

    ОтветитьУдалить
  3. я не понял, в ide от jetbrains есть все то же самое и даже лучше, или фишка именно в бесплатности?

    ОтветитьУдалить
    Ответы
    1. А ты тут откуда? )

      Я как понял ты о meld? В принципе это только пример, но в любом случае я не готов платить немаленькие деньги и держать открытой IDEA только ради того, что бы посмотреть в ней diff.

      Удалить
    2. у нас работодатель покупает ide от jetbrains, дома ломаный правда стоит))
      Насчет первого вопроса - да я решил разок в твиттор заглянуть, ну я смотрю там ты и блог у тебя есть, надо же откомментить полюбому что-то))

      Удалить
    3. Ну вот как не стыдно обкрадывать коллег программистов? У меня вот ни одной ломаной программы )

      Удалить