Как я могу получить разностное сравнение, когда я делаю "git diff"?
Когда я набираю "git diff", я хотел бы видеть параллельный diff, например "diff -y", или отображать diff в интерактивном инструменте diff, например "kdiff3". Как это может быть сделано?
20 ответов
Хотя Git имеет внутреннюю реализацию diff, вы можете вместо этого настроить внешний инструмент.
Есть два разных способа указать внешний инструмент сравнения:
- установка
GIT_EXTERNAL_DIFF
иGIT_DIFF_OPTS
переменные среды - настройка внешнего инструмента сравнения с помощью
git config
Смотрите также:
- https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration
git diff --help
- http://www.pixelbeat.org/programming/diffs/
При выполнении git diff
, Git проверяет как настройки вышеупомянутых переменных окружения, так и его .gitconfig
файл.
По умолчанию Git передает следующие семь аргументов программе diff:
path old-file old-hex old-mode new-file new-hex new-mode
Обычно вам нужны только параметры old-file и new-file. Конечно, большинство инструментов сравнения принимают в качестве аргумента только два имени файла. Это означает, что вам нужно написать небольшой скрипт-обертку, который принимает аргументы, которые Git предоставляет скрипту, и передает их внешней программе git по вашему выбору.
Допустим, вы поместили свой скрипт-обертку под ~/scripts/my_diff.sh
:
#!/bin/bash
# un-comment one diff tool you'd like to use
# side-by-side diff with custom options:
# /usr/bin/sdiff -w200 -l "$2" "$5"
# using kdiff3 as the side-by-side diff:
# /usr/bin/kdiff3 "$2" "$5"
# using Meld
/usr/bin/meld "$2" "$5"
# using VIM
# /usr/bin/vim -d "$2" "$5"
Затем вам нужно сделать этот скрипт исполняемым:
chmod a+x ~/scripts/my_diff.sh
Затем вам нужно сообщить Git, как и где найти ваш собственный скрипт для оболочки diff. У вас есть три варианта, как это сделать: (Я предпочитаю редактировать файл.gitconfig)
С помощью
GIT_EXTERNAL_DIFF
,GIT_DIFF_OPTS
например, в вашем файле.bashrc или.bash_profile вы можете установить:
GIT_EXTERNAL_DIFF=$HOME/scripts/my_diff.sh export GIT_EXTERNAL_DIFF
С помощью
git config
используйте "git config", чтобы определить, где находится ваш скрипт-обертка:
git config --global diff.external ~/scripts/my_diff.sh
Редактирование вашего
~/.gitconfig
файлВы можете редактировать свой
~/.gitconfig
файл для добавления этих строк:[diff] external = ~/scripts/my_diff.sh
Замечания:
Аналогично установке вашего специального инструмента сравнения, вы также можете установить собственный инструмент слияния, который может быть визуальным инструментом слияния, чтобы лучше помочь визуализировать слияние. (см. страницу progit.org)
См.: http://fredpalma.com/518/visual-diff-and-merge-tool/ и https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration
Попробуй git difftool
использование git difftool
вместо git diff
, Ты никогда не вернешься.
ОБНОВЛЕНИЕ, чтобы добавить пример использования:
Вот ссылка на другой стекопоток, который говорит о git difftool
: Как просмотреть вывод 'git diff' с помощью моего предпочтительного инструмента сравнения / средства просмотра?
Для более новых версий git
, difftool
Команда поддерживает множество внешних инструментов сравнения. Например vimdiff
поддерживается автоматически и может быть открыт из командной строки:
cd /path/to/git/repo
git difftool --tool=vimdiff
Другие поддерживаемые внешние инструменты сравнения перечислены через git difftool --tool-help
Вот пример вывода:
'git difftool --tool=<tool>' may be set to one of the following:
araxis
kompare
vimdiff
vimdiff2
The following tools are valid, but not currently available:
bc3
codecompare
deltawalker
diffuse
ecmerge
emerge
gvimdiff
gvimdiff2
kdiff3
meld
opendiff
tkdiff
xxdiff
Вы также можете попробовать git diff --word-diff
, Это не совсем бок о бок, но как-то лучше, так что вы можете предпочесть это вашим реальным потребностям.
cdiff
может отображать параллельные, инкрементные и цветные различия, подробности и демонстрацию см. на домашней странице по адресу https://github.com/ymattw/cdiff
Вы можете сделать бок о бок diff
с помощью sdiff
следующее:
$ git difftool -y -x sdiff HEAD^ | less
где HEAD^
Это пример, который вы должны заменить тем, против чего хотите.
Я нашел это решение здесь, где есть несколько других предложений. Тем не менее, этот единственный ответ - вопрос ОП кратко и ясно.
См. Man git-difftool для объяснения аргументов.
Для Unix, объединяя просто git
и встроенный diff
:
git show HEAD:path/to/file | diff -y - path/to/file
Конечно, вы можете заменить HEAD любой другой ссылкой на git, и вы, вероятно, захотите добавить что-то вроде -W 170
к команде diff.
Это предполагает, что вы просто сравниваете содержимое своего каталога с прошлым коммитом. Сравнение двух коммитов более сложное. Если ваша оболочка bash
Вы можете использовать "процесс замены":
diff -y -W 170 <(git show REF1:path/to/file) <(git show REF2:path/to/file)
где REF1
а также REF2
это git ссылки - теги, ветки или хеши.
Недавно я реализовал инструмент, который делает именно это: https://github.com/banga/git-split-diffs
Вот как это использовать:
npm install -g git-split-diffs
git config --global core.pager "git-split-diffs --color | less -RFX"
И вот как это выглядит в вашем терминале (с темой по умолчанию):
Как видите, он также поддерживает выделение синтаксиса и выделение измененных слов в строках.
export GIT_EXTERNAL_DIFF='meld $2 $5; echo >/dev/null'
тогда просто:
git diff
Если вы хотите видеть параллельные различия в браузере без использования GitHub, вам может понравиться git webdiff, замена для git diff
:
$ pip install webdiff
$ git webdiff
Это дает ряд преимуществ по сравнению с традиционными графическими интерфейсами, такими как tkdiff
в том, что он может дать вам подсветку синтаксиса и показать различия в изображениях.
Подробнее об этом читайте здесь.
Я использую Colordiff.
В Mac OS X установите его с
$ sudo port install colordiff
На линуксе возможно apt get install colordiff
или что-то в этом роде, в зависимости от вашего дистрибутива.
Затем:
$ git difftool --extcmd="colordiff -ydw" HEAD^ HEAD
Или создайте псевдоним
$ git alias diffy "difftool --extcmd=\"colordiff -ydw\""
Тогда вы можете использовать его
$ git diffy HEAD^ HEAD
Я назвал это "диффузным", потому что diff -y
это параллельный diff в unix. Colordiff также добавляет цвета, которые приятнее. В варианте -ydw
, y
для бок о бок, w
игнорировать пробелы, и d
это произвести минимальный diff (обычно вы получите лучший результат как diff)
Мне лично очень нравится icdiff!
Если вы на Mac OS X
с HomeBrew
, просто делать brew install icdiff
,
Чтобы правильно получить метки файлов, а также другие интересные функции, я имею в своем ~/.gitconfig
:
[pager]
difftool = true
[diff]
tool = icdiff
[difftool "icdiff"]
cmd = icdiff --head=5000 --highlight --line-numbers -L \"$BASE\" -L \"$REMOTE\" \"$LOCAL\" \"$REMOTE\"
И я использую это как: git difftool
Этот вопрос появился, когда я искал быстрый способ использовать встроенный способ git для определения различий. Мои критерии решения:
- Быстрый запуск, нужны встроенные опции
- Может легко обрабатывать множество форматов, XML, различные языки программирования
- Быстро определять небольшие изменения кода в больших текстовых файлах
Я нашел этот ответ, чтобы получить цвет в мерзавце.
Чтобы получить параллельный diff вместо строки diff, я mb14 отличный ответ mb14 на этот вопрос со следующими параметрами:
$ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]"
Если вам не нравится дополнительная [- или {+ опция --word-diff=color
может быть использован.
$ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]" --word-diff=color
Это помогло получить правильное сравнение как с json, так и с xml текстом и java кодом.
В итоге --word-diff-regex
Опции имеют полезную видимость вместе с настройками цвета, чтобы получить возможность раскрашивать исходный код рядом друг с другом по сравнению со стандартной разницей строк при просмотре больших файлов с небольшими изменениями строк.
Откройте Intellij IDEA, выберите одну или несколько фиксаций в окне инструмента "Контроль версий", просмотрите измененные файлы и дважды щелкните их, чтобы просмотреть изменения рядом для каждого файла.
С помощью встроенного средства запуска командной строки вы можете вывести IDEA куда угодно с помощью простого idea some/path
Несколько других уже упоминали cdiff для git- сравнения, но никто не дал полной реализации этого.
Настройте cdiff:
git clone https://github.com/ymattw/cdiff.git
cd cdiff
ln -s `pwd`/cdiff ~/bin/cdiff
hash -r # refresh your PATH executable in bash (or 'rehash' if you use tcsh)
# or just create a new terminal
Отредактируйте ~/.gitconfig, вставив эти строки:
[pager]
diff = false
show = false
[diff]
tool = cdiff
external = "cdiff -s $2 $5 #"
[difftool "cdiff"]
cmd = cdiff -s \"$LOCAL\" \"$REMOTE\"
[alias]
showw = show --ext-dif
Выключение пейджера необходимо для работы cdiff с Diff, в любом случае это пейджер, так что это нормально. Difftool будет работать независимо от этих настроек.
Псевдоним show необходим, потому что git show поддерживает только внешние инструменты сравнения через аргумент.
Знак "#" в конце команды diff external важен. Команда diff в Git добавляет $@ (все доступные переменные diff) к команде diff, но нам нужны только два имени файла. Таким образом, мы вызываем эти два явно с $2 и $5, а затем скрываем $ @ за комментарием, который в противном случае запутал бы sdiff. В результате возникает ошибка, которая выглядит следующим образом:
fatal: <FILENAME>: no such path in the working tree
Use 'git <command> -- <path>...' to specify paths that do not exist locally.
Команды Git, которые теперь производят параллельное сравнение:
git diff <SHA1> <SHA2>
git difftool <SHA1> <SHA2>
git showw <SHA>
Использование Cdiff:
'SPACEBAR' - Advances the page of the current file.
'Q' - Quits current file, thus advancing you to the next file.
Теперь у вас есть сторонний diff через git diff и difftool. И у вас есть исходный код Python для настройки опытных пользователей, если вам это нужно.
Использоватьdelta
.
В вашем файле gitconfig (обычно~/.gitconfig
или~/.config/git/config
),
добавлять:
[core]
pager = delta --light --side-by-side
Есть несколько решений:
Решение 1: Объединиться:
Установите meld (в Ubuntu я использовал sudo apt install meld
). Затем настройте его, как показано ниже.
git config --global diff.tool meld
git config --global difftool.meld.path "$(which meld)"
git config --global difftool.prompt false
git config --global merge.tool meld
git config --global mergetool.meld.path "$(which meld)"
Решение 2: Дельта:
Если вы решите использовать cli, установите delta. Конфигурация, которую я использую:
git config --global core.pager 'delta'
git config --global interactive.diffFilter 'delta --color-only'
git config --global delta.side-by-side true
git config --global delta.line-numbers true
git config --global delta.syntax-theme 'Solarized (dark)'
Решение 3: Растопить:
Вы также можете использовать Melt. Подсветка синтаксиса осуществляется с помощью bat. Это также инструмент командной строки.
Вот подход. Если вы пропустили меньше, ширина xterm будет равна 80, что не так уж и жарко. Но если вы продолжите команду, например, с COLS=210, вы можете использовать ваш расширенный xterm.
gitdiff()
{
local width=${COLS:-$(tput cols)}
GIT_EXTERNAL_DIFF="diff -yW$width \$2 \$5; echo >/dev/null" git diff "$@"
}
Это может быть несколько ограниченное решение, но оно работает с использованием системных diff
команда без внешних инструментов:
diff -y <(git show from-rev:the/file/path) <(git show to-rev:the/file/path)
- фильтровать только строки изменения
--suppress-common-lines
(если твойdiff
поддерживает вариант). - никаких цветов в этом случае, просто обычные
diff
маркеры - можно настроить ширину столбца
--width=term-width
; в Bash можно получить ширину как$COLUMNS
илиtput cols
.
Это также можно обернуть во вспомогательный git-скрипт для большего удобства, например, для такого использования:
git diffy the/file/path --from rev1 --to rev2
Есть много хороших ответов на эту тему. Моим решением этой проблемы было написать сценарий.
Назовите это "git-scriptname" (и сделайте его исполняемым и поместите его в PATH, как любой скрипт), и вы можете вызвать его как обычную команду git, выполнив
$ git scriptname
Фактическая функциональность - это только последняя строка. Вот источник:
#!/usr/bin/env zsh
#
# Show a side-by-side diff of a particular file how it currently exists between:
# * the file system
# * in HEAD (latest committed changes)
function usage() {
cat <<-HERE
USAGE
$(basename $1) <file>
Show a side-by-side diff of a particular file between the current versions:
* on the file system (latest edited changes)
* in HEAD (latest committed changes)
HERE
}
if [[ $# = 0 ]]; then
usage $0
exit
fi
file=$1
diff -y =(git show HEAD:$file) $file | pygmentize -g | less -R
Если вы работаете на Mac, GitUp http://gitup.co/ является довольно хорошим выбором.