Как я могу получить параллельный diff, когда я делаю git diff?

Когда я набираю «git diff», я хотел бы видеть параллельную разницу, например, с «diff -y», или хотел бы отобразить разницу в интерактивном инструменте сравнения, таком как «kdiff3». Как это может быть сделано?


person Community    schedule 06.10.2011    source источник
comment
возможный дубликат Как просмотреть 'git diff ' вывод с помощью программы визуального сравнения?   -  person Greg Hewgill    schedule 06.10.2011
comment
Примечание. У вас есть параллельное сравнение на GitHub.   -  person VonC    schedule 04.09.2014


Ответы (17)


Хотя в Git есть внутренняя реализация diff, вместо этого вы можете настроить внешний инструмент.

Существует два разных способа указать внешний инструмент сравнения:

  1. установка переменных окружения GIT_EXTERNAL_DIFF и GIT_DIFF_OPTS.
  2. настройка внешнего инструмента сравнения через git config

Ответ ymattw тоже довольно аккуратный, используя ydiff

Смотрите также:

При выполнении git diff Git проверяет как настройки указанных выше переменных среды, так и свой файл .gitconfig.

По умолчанию Git передает программе diff следующие семь аргументов:

path  old-file  old-hex old-mode  new-file  new-hex new-mode

Обычно вам нужны только параметры старого файла и нового файла. Конечно, большинство инструментов сравнения принимают в качестве аргумента только два имени файла. Это означает, что вам нужно написать небольшой сценарий-оболочку, который принимает аргументы, которые 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)

  1. Использование GIT_EXTERNAL_DIFF, GIT_DIFF_OPTS

    например в вашем файле .bashrc или .bash_profile вы можете установить:

     GIT_EXTERNAL_DIFF=$HOME/scripts/my_diff.sh
     export GIT_EXTERNAL_DIFF
    
  2. Использование git config

    используйте git config, чтобы определить, где можно найти ваш скрипт-оболочку:

     git config --global diff.external ~/scripts/my_diff.sh
    
  3. Редактирование файла ~/.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

person Tilo    schedule 06.10.2011
comment
Сохраняет ли это раскраску терминала git? - person Sridhar Sarnobat; 01.08.2013
comment
Это здорово, но запускает новый просмотрщик для каждого файла. Любой способ создать консолидированный diff, скажем, meld? - person HRJ; 12.11.2013
comment
@Tilo Я получаю сообщение об ошибке для vim as im: Предупреждение: вывод не на терминал - person dead programmer; 25.05.2017
comment
Можно ли настроить версию meld для сравнения каталогов, где я могу выбрать, для каких файлов я хочу видеть различия? В настоящее время он запускает отдельную команду meld для каждого файла, и мне приходится выходить из meld, чтобы увидеть следующий файл. Я бы предпочел, чтобы meld показал мне список каталогов измененных файлов, как это происходит, когда meld используется из Mercurial. - person kasperd; 14.01.2019
comment
Я не хочу голосовать за этот ответ. Но ответ от ymattw было очень легко реализовать. - person MarkWayne; 07.08.2020

Попробуйте git диффтул

Используйте git difftool вместо git diff. Ты никогда не вернешься.

ОБНОВЛЕНИЕ, чтобы добавить пример использования:

Вот ссылка на другой stackoverflow, в котором говорится о 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
person Matt Ball    schedule 06.10.2011
comment
Или, может быть, вы вернетесь, если получите This message is displayed because 'diff.tool' is not configured.. Возможно, обновить ответ с минимальными инструкциями по настройке этой вещи, чтобы он отображал параллельные различия в терминале, о чем просил OP? Инструменты с графическим интерфейсом совершенно бесполезны на удаленном сервере, к которому вы подключаетесь с помощью ssh. - person Petr; 22.05.2016
comment
Интересный момент, хотя я не думаю, что лично мне когда-либо приходилось использовать git во время использования SSH. Одной из приятных особенностей DVCS является распределенная часть: по крайней мере, в моих средах никогда не возникает проблем с локальным клонированием любого репозитория, который я хочу покопаться. - person Matt Ball; 22.05.2016
comment
По крайней мере, в моей конфигурации git difftool с vimdiff не всегда правильно выравнивают два файла/буфера. - person Rohmer; 23.04.2017
comment
Это хорошо, и так ниже в списке ответов: O Я использую git difftool -y, чтобы предотвратить приглашение tkdiff - person gawkface; 13.06.2017
comment
Связано: объедините свой git difftool в Windows и Linux: stackoverflow.com/a/48979939/4561887 - person Gabriel Staples; 20.09.2019
comment
Нам нужно сравнение командной строки по другим причинам, например, в текстовом чате при совместной работе (например, при проверке кода) или при выполнении чего-либо через ssh. - person Sridhar Sarnobat; 10.06.2021

Вы также можете попробовать git diff --word-diff. Это не совсем бок о бок, но в чем-то лучше, поэтому вы можете предпочесть это вашей реальной потребности бок о бок.

person mb14    schedule 11.11.2013
comment
Это самый простой способ. А еще лучше git diff --word-diff=color - person Rolf; 14.08.2014
comment
@Rolf --word-diff=color выдает ошибку недопустимой опции. В какой версии он был представлен? - person Holloway; 14.10.2014
comment
@Trengot Я запускаю git 1.7.9 от 02/2012. - person Rolf; 15.10.2014
comment
Установленная версия @Rolf по умолчанию здесь 1.7.1. Могли бы объяснить разницу. git diff --color-words работает. - person Holloway; 15.10.2014
comment
Да, git diff --color-words подходит для современных версий git. - person VasiliNovikov; 13.01.2017

ydiff

Этот инструмент, ранее называвшийся cdiff, может отображать бок о бок, добавочные и красочные различия.

Вместо git diff выполните:

ydiff -s -w0

Это запустит ydiff в режиме параллельного отображения для каждого из файлов с различиями.

Установить с помощью:

python3 -m pip install --user ydiff

-or-

brew install ydiff

Для git log вы можете использовать:

ydiff -ls -w0

-w0 автоматически определяет ширину вашего терминала. См. ydiff страницу репозитория GitHub для подробностей и демонстрации.

Протестировано в Git 2.18.0, ydiff 1.1.

person ymattw    schedule 01.02.2013
comment
@RyneEverett: Можете ли вы объяснить, как сделать эквивалент git diff | cdiff -s с icdiff? - person einpoklum; 07.01.2019
comment
Просто запустите ydiff -s из рабочей области git/svn/hg, вам не нужно подключаться. - person ymattw; 08.01.2019
comment
если вы хотите ограничить сравнение определенным файлом через историю Git, cd <git repo>, а затем запустите ydiff -ls <path/to/file> - person slm; 16.01.2020

Вы можете сделать параллельное diff, используя sdiff, следующим образом:

$ git difftool -y -x sdiff  HEAD^ | less

где HEAD^ - это пример, который вы должны заменить тем, с чем вы хотите сравнить.

Я нашел это решение здесь, где есть пара других предложений также. Тем не менее, этот ответ на вопрос ОП лаконичен и ясен.

См. man git-difftool для объяснения аргументов.


Принимая во внимание комментарии, вы можете создать удобную команду git sdiff, написав следующий исполняемый скрипт:

#!/bin/sh
git difftool -y -x "sdiff -w $(tput cols)" "${@}" | less

Сохраните его как /usr/bin/git-sdiff и chmod +x его. Тогда вы сможете сделать это:

$ git sdiff HEAD^

Дополнительный совет

Как было предложено в комментариях, вы можете использовать icdiff, чтобы делать то, что sdiff делает с цветным выводом:

$ more /usr/bin/git-sdiff
#!/bin/sh
git difftool -y -x "icdiff --cols=$(tput cols)" "${@}" | less
person starfry    schedule 30.08.2016

export GIT_EXTERNAL_DIFF='meld $2 $5; echo >/dev/null'

тогда просто:

git diff
person krzych    schedule 12.10.2012
comment
«слияние». тоже работает! И он показывает все изменения в консолидированном окне. - person HRJ; 12.11.2013
comment
@HRJ работает отлично! Так просто и практично :) - person waldyrious; 28.09.2016

Для 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 — теги, ветки или хэши.

person Walker Hale IV    schedule 07.05.2018
comment
Спасибо - ваша команда «git show HEAD:path/to/file» была тем, что мне было нужно, чтобы придумать собственное решение, «vimdfiff ‹(git show HEAD:path/to/file) path/to/file». Биты все еще не выровнены правильно, но это лучшее решение, которое у меня есть прямо сейчас. - person talexb; 30.04.2019

Если вы хотите увидеть параллельные различия в браузере без использования GitHub, вам может понравиться git webdiff, замена git diff:

$ pip install webdiff
$ git webdiff

Это дает ряд преимуществ по сравнению с традиционными инструментами сравнения с графическим интерфейсом, такими как tkdiff, поскольку оно может подсвечивать синтаксис и отображать различия изображений.

Подробнее об этом читайте здесь.

person danvk    schedule 20.11.2014

Я использую colordiff.

В Mac OS X установите его с помощью

$ sudo port install colordiff

В Linux возможно apt get install colordiff или что-то в этом роде, в зависимости от вашего дистрибутива.

Потом:

$ git difftool --extcmd="colordiff -ydw" HEAD^ HEAD

Или создайте псевдоним

$ git alias diffy "difftool --extcmd=\"colordiff -ydw\""

Тогда вы можете использовать его

$ git diffy HEAD^ HEAD

Я назвал это «diffy», потому что diff -y — это параллельный diff в unix. Colordiff также добавляет более приятные цвета. В опции -ydw y для бок о бок, w для игнорирования пробелов, а d для получения минимального различия (обычно вы получаете лучший результат при различии)

person Luigi R. Viggiano    schedule 17.07.2014
comment
добавьте -y, чтобы пропустить подсказку Launch 'colordiff' [Y/n]:. - person Beni Cherniavsky-Paskin; 10.08.2014
comment
вы уверены, что это git alias diffy "difftool --extcmd=\"colordiff -ydw\""? Разве это не должно быть git config --global alias.diffy "difftool --extcmd=\"colordiff -ydw\"" ? - person nonopolarity; 07.04.2020

Лично мне очень нравится 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

person Jose Alban    schedule 29.10.2015

Этот вопрос возник, когда я искал быстрый способ использовать встроенный способ git для поиска различий. Мои критерии решения:

  • Быстрый запуск, необходимые встроенные опции
  • Может легко обрабатывать многие форматы, xml, разные языки программирования
  • Быстрое определение небольших изменений кода в больших текстовых файлах

Я нашел этот ответ, чтобы получить цвет в git.

Чтобы получить параллельный diff вместо линейного diff, я настроил превосходный 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 имеют полезную видимость вместе с настройками цвета, чтобы получить раскрашенный параллельный исходный код по сравнению со стандартным различием строк при просмотре больших файлов с небольшими изменениями строк.

person Mike    schedule 20.07.2015
comment
Это потрясающе, спасибо! - person Ian Dunn; 01.02.2021

Несколько других уже упоминали cdiff для параллельного сравнения git, но никто не дал полной реализации этого. .

Настройка компакт-диска:

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 важен. Команда Git diff добавляет $@ (все доступные переменные 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.

Теперь у вас есть параллельное сравнение через git diff и difftool. И у вас есть исходный код cdiff python для настройки опытного пользователя, если он вам понадобится.

person Eric    schedule 02.02.2018

Вот подход. Если вы передаете меньше, ширина xterm устанавливается на 80, что не так уж и важно. Но если вы продолжите команду, например. COLS=210, вы можете использовать расширенный xterm.

gitdiff()
{
    local width=${COLS:-$(tput cols)}
    GIT_EXTERNAL_DIFF="diff -yW$width \$2 \$5; echo >/dev/null" git diff "$@"
}
person Thomas Mellman    schedule 27.06.2016
comment
Смешной. Я подписался псевдонимом, но это было проигнорировано... Спасибо, что выложили меня, Stack Overflow. :( - person Thomas Mellman; 27.06.2016

Откройте Intellij IDEA, выберите один или несколько коммитов в окне инструмента "Контроль версий", просмотрите измененные файлы и дважды щелкните их, чтобы просмотреть изменения рядом для каждого файла.

С помощью прилагаемой программы запуска командной строки вы можете запускать IDEA в любом месте с помощью простого idea some/path

представление управления версиями diff view

person Holger Brandl    schedule 05.12.2017

В этой теме есть много хороших ответов. Мое решение этой проблемы состояло в том, чтобы написать сценарий.

Назовите это «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
person Jon Carter    schedule 02.01.2016

Это может быть несколько ограниченным решением, но оно выполняет работу с помощью системной команды 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
person nomadbyte    schedule 18.07.2020

Недавно я реализовал инструмент, который делает именно это: https://github.com/banga/git-split-diffs

Вот как это использовать:

npm install -g git-split-diffs

git config --global core.pager "git-split-diffs --color | less -RFX"

А вот как это выглядит в вашем терминале (с темой по умолчанию):

Предварительный просмотр параллельных различий

Как видите, он также поддерживает подсветку синтаксиса и выделение измененных слов внутри строк.

person Shrey    schedule 10.05.2021