Как я могу получить разностное сравнение, когда я делаю "git diff"?

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

20 ответов

Решение

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

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

  1. установка GIT_EXTERNAL_DIFF и GIT_DIFF_OPTS переменные среды
  2. настройка внешнего инструмента сравнения с помощью git config

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

При выполнении 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)

  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

Попробуй 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/ является довольно хорошим выбором.

Другие вопросы по тегам