Как заставить diff работать как git-diff? - PullRequest
118 голосов
/ 01 февраля 2011

Мне нравится форматирование вывода git diff.Цвет и представление изменений между строками в + / - легче читать, чем в GNU diff.

Я могу запустить git diff, используя флаг --no-index вне git-репо, и все работает нормально,Однако, по-видимому, отсутствует опция --exclude для исключения файлов или подкаталогов из рекурсивного diff.

Есть ли способ получить лучшее из обоих миров?(варианты цвета и + / - формат git diff и --exclude опция GNU diff).

Я экспериментировал с colordiff, но я все еще предпочитаю формат вывода git diff

Ответы [ 11 ]

136 голосов
/ 01 февраля 2011

Я не знаю, как сделать цвет, но это будет делать +/-, а не < и >.

diff -u file1 file2
82 голосов
/ 02 июля 2013

Вы также можете использовать git diff --no-index -- A B (через manpage ).

23 голосов
/ 29 ноября 2013
  1. Установка colordiff .

  2. Обновите ~ / .colordiffrc (сначала скопируйте / etc / colordiffrc, если необходимо):

    # be more git-like:
    plain=off
    newtext=darkgreen
    oldtext=darkred
    diffstuff=darkcyan
    
  3. Используйте colordiff -u file1 file2 для двух файлов или colordiff -ruN path1 path2 для рекурсивного сравнения путей.

Это не совсем то же самое, но это очень близко.

15 голосов
/ 21 августа 2014

Это то, что я предлагаю, и это довольно близко

diff -u FILE1 FILE2 | colordiff | less -R
  • colordiff: вам придется установить
  • -R: это говорит Меньше показывать цвета вместо необработанных кодов.

В конечном итоге я использовал -w, потому что не хотел видеть различия между пробелами.

diff -w -u FILE1 FILE2 | colordiff | less -R

Редактировать: Как подсказывает @Ciprian Tomoiaga в комментарии, вы можете сделать это функцией и поместить еев вашем ~/.bashrc файле тоже.

function gdiff () { diff -u $@ | colordiff | less -R; }
2 голосов
/ 12 июня 2018

GNU diff имеет опцию --color с версии 3.4 в конце 2016 года в соответствии с этим ответом в Unix SE.Этого вместе с -u должно быть достаточно для имитации вывода git diff:

diff -u --color=always file1 file2 | less -r

--color должно быть always при использовании в трубе, auto будетотключить цвет в каналах.

Я пробовал это только с Git Bash на Windows, где less -R будет окрашивать только первую строку фрагмента.less -r исправил это для меня в этом случае.

2 голосов
/ 22 октября 2015

Используя только bash, diff, tput и less, мы можем близко приблизиться к результату git diff.Однако будут некоторые заметные различия из-за близорукости diff программистов.

Поместите следующее определение функции Bash в некоторый файл, который автоматически создается вашей учетной записью пользователя, и выиметь возможность доступа к функции из командной строки:

function gdiff()
{
    local REG=`tput op`
    local GRP=`tput setaf 6`
    local ADD=`tput setaf 2`
    local REM=`tput setaf 1`

    local NL=$'\n'
    local GRP_LABEL="${GRP}@@ %df,%dn +%dF,%dN @@${REG}"

    local UNCH_GRP_FMT=''

    [[ "${1}" == '@full' ]] && {

        UNCH_GRP_FMT="${GRP_LABEL}${NL}%="
        shift
    }

    diff \
        --new-line-format="${ADD}+%L${REG}" \
        --old-line-format="${REM}-%L${REG}" \
        --unchanged-line-format=" %L${REG}" \
        --new-group-format="${GRP_LABEL}${NL}%>" \
        --old-group-format="${GRP_LABEL}${NL}%<" \
        --changed-group-format="${GRP_LABEL}${NL}%<%>" \
        --unchanged-group-format="${UNCH_GRP_FMT}" \
            "${@}" | less -FXR
}

Эта функция работает следующим образом:

  1. В конечном итоге, diff вызывается с различными параметрами форматирования, чтобы указать, как изменениявнутри файлов будут отображаться.
  2. tput используется для вставки цветовых кодов ANSI в эти параметры форматирования.Обратите внимание, что при использовании не-ANSI терминалов вам, возможно, придется заменить tput setaf на tput setf.
  3. Выход diff передается по каналу less.-R позволяет сохранить цвета ANSI.-X не позволяет less очистить экран при выходе.-F не позволяет less работать как пейджер, если выход помещается на одном экране.
  4. Если первый параметр - @full, функция отобразит все неизмененные строки в дополнение к добавленным и удаленным строкам.

Обратите внимание на следующие различия между этим подходом и git diff:

  1. git diff сообщает о трех строках контекста, окружающих каждое изменение.К сожалению, diff, похоже, выдает жалобу и завершает работу, если вы хотите указать количество строк контекста и одновременно указать параметры форматирования.(По крайней мере, в Mac OS X Yosemite).Спасибо diff программистам.Следовательно, вы можете либо запросить отсутствие строк контекста, окружающих каждое изменение, что является поведением по умолчанию, либо вы также можете запросить, чтобы также сообщались все неизмененные строки в файле, указав @full в качестве первого параметра.
  2. Поскольку строки контекста отличаются от git diff, номера строк, сообщаемые этой функцией, также будут отличаться от тех, о которых сообщается git diff.
  3. Вы можете увидеть наличие сообщаемых однострочных изменений, которыеэто правильное поведение, но раздражает, когда ваш измененный файл содержит вставку одиночных пустых строк.Я думаю, что git diff справляется с этим лучше с точки зрения контекста.Вы можете попробовать передать различные опции в diff, чтобы лучше справляться с пробелами, если хотите.
2 голосов
/ 17 января 2013

Вы ищете colordiff:

sudo apt-get install colordiff
1 голос
/ 28 ноября 2017

Поместите это в ваш .bashrc или .zshrc:

diff() { git diff --no-index "$1" "$2" | colordiff; }

требования: git и colordiff должны быть установлены заранее.

использование: diff file1 file2

пример: за $ diff .tmux.conf .zshrc.pre-oh-my-zsh

diff function example

0 голосов
/ 23 августа 2018

Использование colordiff :

Установка:

sudo apt-get install colordiff

Usage:

colordiff -u file_one file_two

Дает такую ​​же разницу, как показано git diff.

0 голосов
/ 03 февраля 2011

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

gdiff() {
    (
        dir=`pwd`
        cd ./$(git rev-parse --show-cdup)/..
        git diff  $dir/$1 $dir/$2
    )
}
...