TL; DR: Git сам ничего не знает о других командах, поэтому вы должны предоставить вспомогательный набор инструкций от до Git, чтобы сообщить ему: для использования программы X в качестве difftool,делать _____ . Лучше всего найти инструкции, уже созданные кем-то еще, например, комментарий EncryptedWatermelon, добавленный к его собственному ответу , но не получится, ну, см. Ниже.
См. Бесполезныеответьте за несколько практических советов.
Обратите внимание, что для самого Git, говоря проще, diff означает сравните две ревизии ,Например, две ревизии могут быть двумя коммитами или одним коммитом и содержимым вашего рабочего дерева. Git имеет несколько дополнительных особых случаев, так что вы можете использовать его как более изящную версию стандартной команды Unix / Linux diff
, но в основном это две ревизии, каждая из которых представляет собой целый набор файлов:
Если ревизия слева содержит файл с именем F , а ревизия справа содержит файл с именем F , Git будет сравнивать содержимоедве версии F .
Если на левой стороне есть файл D , и его нет в правосторонней ревизии, файл D был удалено .
Если на левой стороне нет файла A , но в правом - файл A боковая ревизия, файл A был добавлен .
Если вы включите обнаружение переименования - что является значением по умолчанию с Git 2.9 - Git будет,в случае добавленных и удаленных файлов попытайтесь выяснить, может ли вновь добавленный файл в основном совпадать со старым, но удаленным файлом, и, если это так, сообщить об этом как переименованный файл,со старым именем D (удалено) и новым именем A (добавлено). Затем Git сравнивает содержимое левой стороны D с содержимым правой стороны A .
При сравнениисодержимое файлов, если все одинаково, Git вообще ничего не говорит о файле. В противном случае вы можете сделать так, чтобы Git дал вам набор инструкций в форме «удалить эту строку» и / или «добавить эту другую строку». Следуя инструкциям, преобразует старую версию файла в новую версию файла. Эти инструкции не обязательно то, что кто-то на самом деле сделал! Они просто достигнут того же результата . (Обычно есть только один очевидный способ достижения результата, так что оказывается, что кто-то сделал.)
Имея это в виду, вот что git difftool
делает:
Во-первых, Git сравнил две ревизии, чтобы сгенерировать список файлов, в которых есть изменения, а подавил фактические сравнения этих файлов.
Затем со списком измененных файлов - набор имен F , которые были в обеих ревизиях, но не совпадали в двух ревизиях, - он создает копию левойбоковая версия файла и копия правой версии. В большинстве случаев он должен делать эти копии, потому что файлы, хранящиеся в Git, хранятся в замороженном и сжатом виде, который на самом деле может прочитать только Git. Git должен распаковать / разморозить их, «перегидратировав» внутреннюю высушенную лиофилизированную форму файла, чтобы другие программы могли ее прочитать.
В некоторых случаях, например, при сравнении определенного коммита с работой-дерево, это может просто использовать копию рабочего дерева, когда это уместно. Это все еще может сделать свою собственную копию. Здесь вы не получите никакого реального обещания, так или иначе.
Теперь, когда есть две копии файла, Git использует вспомогательную программу для запуска выбранного вами инструмента сравнения. Эта вспомогательная программа получает несколько частей информации, таких как:
- имя каждой временной копии
- оригинальное имя файла (временная копия обычно имеет какое-то уродливое временное имянапример
.tmp-123456
Работа вспомогательной программы состоит в том, чтобы запустить инструмент diff, чтобы он отображал эти файлы в удобной для пользователя форме. Затем он должен дождаться, пока инструмент покажет, что пользователь завершил просмотр файлов, и выяснить, указал ли пользователь желание отменить просмотр файлов или перейти к следующей паре файлов.
Это вспомогательная программа. Это относительно простой сценарий оболочки, весящий чуть более 100 строк. Но он использует больше сценариев оболочки: в частности, он использует эту большую вспомогательную библиотеку mergetool , которая весит более 450 строк сценария оболочки.
Чтобы предоставить собственный инструмент, вы должны:в любом случае для лучшего использования - напишите сценарий оболочки, который используется второй библиотекой (помощник по слиянию) вместе с первым сценарием, который предоставляет знания о том, как запустить выбранный вами инструмент. Ключевые элементы этого взаимодействия:
- открытие двух файлов
- с более полезным именем, чем
.tmpwhatever
- определение того, когда и хочет ли пользовательперейдите к следующему diff или выйдите.
Две существующие библиотеки вспомогательного кода сценария оболочки имеют некоторые недостатки, так что если ваша программа относительно проста в использовании, существующие помощники могут запустить ее самостоятельно. Им просто нужно знать , где находится исполняемый файл и какие аргументы передать и , доверять ли его коду выхода . Вы можете установить их с помощью git config
, установив difftool.<em>name</em>.cmd
и mergetool.<em>name</em>.trustExitCode
. Например:
git config --global difftool.foo.cmd '<path> "$LOCAL" "$REMOTE"'
git config --global mergetool.foo.trustExitCode true
будет в порядке (но не так уж и здорово: имена файлов будут странными и бесполезными), если команда в path
выйдет из нуля для "перейти кnext diff "и ненулевое значение для" выйти сейчас ".