Выделите измененные строки и измененные байты в каждой измененной строке

Проект с открытым исходным кодом Trac имеет отличный инструмент выделения различий, который выделяет измененные строки и измененные байты в каждой измененной строке! См. здесь или здесь примеры.

Есть ли способ использовать ту же цветовую подсветку (т.е. измененные строки а также измененные байты) в терминале bash, git или vim для вывода различий (файл исправления)?


person Nikolay Frantsev    schedule 16.03.2011    source источник
comment
Что именно вы хотите выделить? Вам нужен инструмент сравнения, который выделяет изменения байтов? (Это было бы очень полезно). Вы говорите, vim, насколько я помню, vim уже много манипулирует цветом, когда вы используете шаблоны языка программирования (и другие). Как бы вы изменили это? Существует довольно много методов изменения цвета в окне терминала, которое определено как VT100 (и существуют десятки других определений, которые также будут поддерживать последовательности перехода цвета). Больше конкретики, пожалуйста. Или прочитайте en.wikipedia.org/wiki/VT100 и соответствующие ссылки. Может быть, это может помочь.   -  person shellter    schedule 16.03.2011
comment
Я знаю, что вас интересуют только инструменты с открытым исходным кодом и только терминал. Но в качестве отправной точки вы можете взглянуть на diffzilla от slickedit. из нескольких инструментов сравнения, которые я использовал, он всегда лучше всего представлял различия символов (хотя у него определенно были проблемы, когда различия были сложными (сочетание форматирования и изменений кода, что всегда плохая идея)   -  person nhed    schedule 19.03.2011
comment
Похоже на дубликат stackoverflow.com/questions/3231759/   -  person Adam Monsen    schedule 10.10.2012
comment
Примечание. GitHub теперь предлагает такой инструмент сравнения в своем веб-интерфейсе: stackoverflow.com/a/25723584/6309.   -  person VonC    schedule 08.09.2014
comment
Я опубликовал «еще одно» чистое решение на основе git, основанное на diff-highlight, с учебными пособиями, чтобы легко 1) найти соответствующий файл diff-highlight, 2) сделать его исполняемым 3) установить необходимые параметры в .gitconfig. Пожалуйста, посмотрите. Инструкции предназначены для Ubuntu 18.04, но должны широко работать в системах Linux.   -  person Zorglub29    schedule 01.04.2020


Ответы (12)


diff-highlight Contrib-скрипт Perl выдает такие же выходные данные, что и Скриншоты Trac, которые, вероятно, используют Trac:

введите здесь описание изображения

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

wget https://raw.githubusercontent.com/git/git/fd99e2bda0ca6a361ef03c04d6d7fdc7a9c40b78/contrib/diff-highlight/diff-highlight && chmod +x diff-highlight

Переместите файл diff-highlight в каталог ~/bin/ (или туда, где находится ваш $PATH), а затем добавьте следующее в ваш ~/.gitconfig:

[pager]
        diff = diff-highlight | less
        log = diff-highlight | less
        show = diff-highlight | less

Установка одной копии, предложенная @cirosantilli:

cd ~/bin
curl -O https://raw.githubusercontent.com/git/git/fd99e2bda0ca6a361ef03c04d6d7fdc7a9c40b78/contrib/diff-highlight/diff-highlight
chmod +x diff-highlight
git config --global pager.log 'diff-highlight | less'
git config --global pager.show 'diff-highlight | less'
git config --global pager.diff 'diff-highlight | less'
git config --global interactive.diffFilter diff-highlight
person Community    schedule 01.03.2013
comment
Этот. Это отлично. Спасибо. Однако в некоторых местах он кажется немного консервативным, в нем отсутствуют некоторые строки, которые, очевидно, имеют большую часть общего текста. У вас есть баг-трекер для этого? - person naught101; 26.03.2013
comment
Ах, теперь это часть ядра git: github.com/git/ git/tree/master/contrib/diff-highlight - person naught101; 26.03.2013
comment
@ s1n4: пожалуйста, добавьте сюда также свое объяснение. Это лучший ответ. - person Ciro Santilli 新疆再教育营六四事件ۍ 22.02.2014
comment
Необработанные URL-адреса Github, похоже, изменились, поэтому приведенную выше команду curl необходимо обновить, чтобы она указывала на текущий URL-адрес или используйте тег -L, чтобы перейти к заголовку перенаправления. - person Chris; 14.04.2015
comment
Теперь он превратился в модуль, и я думаю, что проще всего загрузить версию, расположенную непосредственно перед этим изменением, по адресу raw.githubusercontent.com/git/git/ - person Chris Midgley; 29.06.2017
comment
Это не только часть ядра git, но и распространяется вместе с git и, возможно, уже в вашей системе. Я добавил подробности о том, как включить его в своем ответе ниже. ↓ - person Cory Klein; 17.01.2019
comment
Вот прямая ссылка на ответ @CoryKlein. - person Michael; 27.01.2019
comment
Это пропускает различия, которые вы видите через git add -p. Пожалуйста, также добавьте: git config --global interactive.diffFilter diff-highlight - person josch; 25.03.2019

При использовании git diff или git log и, возможно, других, используйте опцию --word-diff=color (кстати, существуют и другие режимы для сравнения слов)

person anydot    schedule 20.03.2011
comment
--word-diff=color действительно лучше (особенно с git config color.diff.old "red reverse" и git config color.diff.new "green reverse"), но это не то, что мне нужно :( - person Nikolay Frantsev; 21.03.2011
comment
Так что единственное, чего вам не хватает, это маркировка цветом/каким-то образом измененные строки и байты одновременно? - person anydot; 21.03.2011
comment
Я хочу выделить измененные строки и измененные байты в каждой измененной строке, как в Trac. Не просто изменились байты, это не то же самое. - person Nikolay Frantsev; 22.03.2011
comment
Вы также можете использовать это с git add --patch: stackoverflow.com/questions/10873882/ - person naught101; 17.09.2013
comment
Преимущество diff-highlight в том, что он хорошо работает как для сравнения слов, так и для сравнения строк. - person Ciro Santilli 新疆再教育营六四事件ۍ 05.07.2014
comment
Если вы включите diff-highlight, он автоматически подсветит байтовые различия во всех различиях патчей git. Подробности в моем ответе ниже. ↓ - person Cory Klein; 17.01.2019

diff-so-fancy — это diff-хайлайтер, разработанный для человеческого глаза.

Он удаляет ведущие +/-, которые раздражают при вырезании/вставке, и делает четкими разделы между файлами.

Цветные git (слева) и diff-so-fancy (справа — обратите внимание на выделение на уровне персонажа):

отличный вывод

Если вы хотите, чтобы diff-so-fancy (справа) выводился, но не ограничивался файлами в git добавьте в свой .bashrc следующую функцию, чтобы использовать ее для любых файлов:

dsf() { git diff --no-index --color "$@" | diff-so-fancy; }

Eg:

dsf original changed-file

Подсветка уровня символов и стандартный формат diff

Если вам не нравится нестандартное форматирование diff-so-fancy, но вы хотите выделить git на уровне символов, используйте diff-highlight, который возьмет вывод git и создаст очень красивый стандартный вывод diff-формата:

скриншот diff-highlight

Чтобы использовать его по умолчанию с git, добавьте к вашему .gitconfig:

[color "diff-highlight"]
  oldNormal = red bold
  oldHighlight = red bold 52
  newNormal = green bold
  newHighlight = green bold 22

[pager]
  diff = diff-highlight | less -FRXsu --tabs=4

Секция [pager] указывает git передать свой уже раскрашенный вывод в diff-highlight, который раскрашивает на уровне символов, а затем выводит меньше страниц (если требуется), а не просто использует значение по умолчанию less.

person Tom Hale    schedule 15.09.2016
comment
Это очень интересно, не могли бы вы немного рассказать об этих gitconfig параметрах? - person caesarsol; 09.03.2017
comment
Обновлено, также добавлена ​​функция dsf(). - person Tom Hale; 10.03.2017

Требуемое поведение теперь доступно в самом git (как было указано в комментарии naught101). Чтобы включить его, вам нужно настроить пейджер на

perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less

где /usr/share/doc/git/contrib/diff-highlight/diff-highlight — это расположение скрипта подсветки в Ubuntu 13.10 (я понятия не имею, почему он находится в папке doc). Если его нет в вашей системе, попробуйте найти его с помощью locate diff-highlight. Обратите внимание, что скрипт подсветки не является исполняемым (по крайней мере, на моей машине), поэтому требуется perl.

Чтобы всегда использовать подсветку для различных команд, похожих на различия, просто добавьте следующее в файл ~/.gitconfig:

[pager]
    log = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less
    show = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less
    diff = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less

Я добавил это, поскольку комментарий нового ответа naught101 скрыт, а также потому, что настройка не так тривиальна, как должна быть, и, по крайней мере, в версии Ubuntu, в которой у меня есть инструкции в README не работают.

person dshepherd    schedule 15.09.2014
comment
Я только что заметил, что это не включает подсветку различий в git add -p (интерактивный режим). Я не знаю, как это можно исправить, простое добавление в список приводит к зависанию. - person dshepherd; 17.09.2014
comment
Теперь это должно работать в git 2.9.0: git config interactive.diffFilter diff-highlight - person Thomas; 16.06.2016
comment
^ Это! К сожалению, diff-highlight не было на моем пути, поэтому мне пришлось сначала найти его. Подробности в моем ответе ниже. - person Cory Klein; 17.01.2019

Утилита для байтовых различий распространяется вместе с официальным Git, начиная с версии 1.7.81. Вам просто нужно найти, где он установлен на вашем компьютере, и включить его.

Найдите, где установлен Git

  • MacOS с Git, установленным через Homebrew: это /usr/local/opt/git
  • Windows с Git для Windows: запустите cd / && pwd -W, чтобы найти каталог установки.
  • Линукс: Ботаник. Если вы еще не знаете, где установлен Git, вам помогут ll $(which git) или locate git.

Свяжите diff-highlight с вашим каталогом bin, чтобы ваш PATH мог его найти

GIT_HOME='/usr/local/opt/git/'  # Use the value from the first step.
ln -s "${GIT_HOME}/share/git-core/contrib/diff-highlight/diff-highlight" \
      '/usr/local/bin/diff-highlight'

Включите его в конфигурации Git.

git config --global interactive.diffFilter diff-highlight # Use on interactive prompts
git config --global pager.diff "diff-highlight | less"    # Use on git diff
git config --global pager.log  "diff-highlight | less"    # Use on git log
git config --global pager.show "diff-highlight | less"    # Use on git show

1 Вот версия v1.7.8 , но с тех пор было внесено множество изменений.

person Cory Klein    schedule 17.01.2019
comment
Хорошо бы указать, в какой версии он начал распространяться с git. Также я предполагаю, что дистрибутивы по умолчанию помещают его в PATH, поэтому шаг символической ссылки не понадобится? И which git требует, чтобы он был в PATH в первую очередь, поэтому он не будет работать, если это не так :-) - person Ciro Santilli 新疆再教育营六四事件ۍ 12.03.2019
comment
Было бы хорошо! Не стесняйтесь добавлять эту информацию. И хотя Git объединяет diff-highlight, на самом деле он не устанавливает его, поэтому шаг с символической ссылкой действительно необходим (по крайней мере, в macOS). Если вы обнаружите, что это не нужно для вашей платформы, снова не стесняйтесь обновлять ответ. Между тем, which git обычно работает, потому что Git действительно устанавливает двоичный файл git где-то по пути. - person Cory Klein; 12.03.2019
comment
Обратите внимание, что в нестабильной версии Debian мне нужно было скомпилировать этот файл, потому что у меня только что был файл .perl. Компиляция тривиальна: просто запустите sudo make в каталоге diff-highlight. - person tobiasBora; 01.04.2020

Я использую опцию --color-words, и она отлично работает для меня:

$ git diff --color-words | less -RS
person amized    schedule 11.05.2011
comment
Нет, это только показывает разницу в словах. То, что OP (и я) хочу, - это обычное построчное различие с выделенными различиями слов (так, скажем, разные строки - это цветной текст, а различия слов в этих строках - обычный цветной текст с цветным выделением или что-то). Смотрите примеры ссылок сейчас в вопросе. - person naught101; 26.03.2013
comment
pastebin.com/1JrhYHRt На самом деле я использую vimdiff как difftool и vimdiff с цветовой схемой molokai, чтобы получить красивое выделение, как вы описываете в вашем вопросе. 1- git config --global diff.tool vimdiff 2- в vim :colo molokai * Molokai @ github.com/tomasr /molokai * Возможна автоматическая цветовая схема с ~/.vimrc: if &diff set background=dark colorscheme molokai endif - person amized; 10.06.2013

как говорит @dshepherd :

Требуемое поведение теперь доступно в самом git.

Но diff-highlight находится в DOC и недоступен из оболочки.
Чтобы установить diff-highlight в каталог ~/bin, выполните следующие действия (это сохранит ваш ввод):

$ locate diff-highlight
$ cd /usr/share/doc/git/contrib/diff-highlight  #or path you locate
$ sudo make
$ mv diff-highlight ~/bin

Затем настройте свой .gitconfig, как говорится в официальном документе:

[pager]
    log  = diff-highlight | less
    show = diff-highlight | less
    diff = diff-highlight | less

UPD
Также вы можете попробовать следующее на последней версии git без какой-либо установки:

git diff --color-words=.

Более сложный:

git diff --color-words='[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'
person Eugen Konkov    schedule 26.01.2018

В Emacs есть функция ediff-patch-buffer, которая должна удовлетворить ваши потребности.

Откройте неисправленный файл в emacs, введите ESC-x, ediff-patch-buffer.

Следуйте инструкциям, и вы должны увидеть выделенное сравнение исправленной и исходной версий вашего файла.

В соответствии с вашим комментарием следующее даст вам решение bash, требующее только dwdiff:

#!/bin/bash
paste -d'\n' <(dwdiff -2 -L -c <(cat $2) <(patch $2 -i $1 -o -)) <(dwdiff -1 -L -c <(cat $2) <(patch $2 -i $1 -o -))| uniq
person Finbar Crago    schedule 20.03.2011
comment
извините, я не хочу использовать emacs, только bash, git или vim - person Nikolay Frantsev; 23.03.2011
comment
Это понятно. Единственное, что я могу придумать, это использовать colordiff со стандартным выводом из patch: colordiff -u <(patch original_file -i patch_file -o -) <(cat original_file), но это будет выделять только измененные строки, а не укусы... - person Finbar Crago; 24.03.2011
comment
Я немного обдумал вашу проблему и добавил второе решение, для которого требуется только dwdiff. - person Finbar Crago; 24.03.2011
comment
пожалуйста прочитайте внимательно мой вопрос, я не хочу сравнивать файлы - person Nikolay Frantsev; 24.03.2011
comment
извините за путаницу, так что вы только что нашли способ выделить измененные байты в измененных строках файла различий? если да то попробуй dwdiff -c --diff-input diff_file - person Finbar Crago; 25.03.2011
comment
Я попробовал это, прежде чем написать предыдущий комментарий. к сожалению, он не выделяет измененные строки, а только измененные байты :( - person Nikolay Frantsev; 25.03.2011

Диффи

GitLab использует Diffy https://github.com/samg/diffy (Ruby) для получения вывода, аналогичного на GitHub и diff-highlight:

введите здесь описание изображения

Diffy создает различия, используя тот же алгоритм, что и Git, и поддерживает различные типы вывода, включая вывод HTML, который использует GitLab:

gem install diffy
echo '
  require "diffy"    
  puts Diffy::Diff.new("a b c\n", "a B c\n").to_s(:html)
' | ruby

Выход:

<div class="diff">
  <ul>
    <li class="del"><del>a <strong>b</strong> c</del></li>
    <li class="ins"><ins>a <strong>B</strong> c</ins></li>
  </ul>
</div>

Обратите внимание, как к измененным байтам добавилось strong.

person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 19.07.2014

Да, Vim делает это, включая выделение текста, измененного в строке.
См. :h diff и :h 08.7 для получения дополнительной информации о том, как сравнивать файлы.

Vim использует довольно простой алгоритм для выделения. Он ищет в строке первый измененный символ, а затем последний измененный символ и просто выделяет все символы между ними.
Это означает, что вы не можете выделять несколько строк в строке — многие дизайнерские решения в Vim отдают предпочтение эффективности.

person PDug    schedule 16.03.2011
comment
к сожалению, он не выделяет измененные байты при выводе diff (установите тип файла = diff) - person Nikolay Frantsev; 16.03.2011
comment
Думаю, теперь я понимаю ваш вопрос. Вы хотите синтаксически выделить текстовый вывод команды diff, чтобы он выделял любые изменения, сделанные внутри строки. Редактирование этого текста в Vim выделяет различия строк, но не изменения, сделанные внутри строки. - person PDug; 16.03.2011
comment
Не могли бы вы использовать команду Vim :patchfile для загрузки исходного файла, а затем сравнить его с исправленной версией? - person PDug; 16.03.2011
comment
к сожалению нет, я хочу использовать рекурсивный вывод diff для нескольких файлов - person Nikolay Frantsev; 16.03.2011

vimdiff file1 file2 отобразит разницу в символах между двумя файлами.

vimdiff — это инструмент сравнения, включенный в vim. (Vim должен быть скомпилирован с параметром +diff, чтобы убедиться, что вы можете проверить с помощью :version )

Вы также можете запустить его из vim. См. :help diff для получения дополнительной информации и команд.

person Xavier T.    schedule 16.03.2011
comment
Я не хочу сравнивать файлы, я хочу выделить diff (патч) файл. - person Nikolay Frantsev; 16.03.2011
comment
@Nikolay Frantsev Если вас не волнует производительность, вы можете установить мой формат. vim и выполните vimdiff file.old file.new -c 'FormatCommand diffformat' -c 'w! file.diff.html' -c 'qa!'. - person ZyX; 16.03.2011
comment
Он выполнит diff в пакетном режиме (добавьте screen -D -m или добавьте &>/dev/null (вариант /dev/null иногда вызывает странные ошибки), если вы не хотите, чтобы терминал мигал) и выйдет из vim после завершения форматирования, но это чистый vimscript, и даже с моей оптимизацией он очень медленный для больших файлов. - person ZyX; 16.03.2011

Примечание: это дубликат того, что можно найти здесь: Как улучшить выделение различий в git? . Тем не менее, публикую свой ответ здесь, так как он может быть полезен для некоторых людей, которые найдут непосредственно эту тему :)

Как было сказано в некоторых предыдущих ответах, это возможно только с помощью git. Я публикую это, так как инструкции могут быть немного проще в зависимости от вашей системы, но это похоже на несколько других ответов.

Одно решение, которое полностью полагается на git и его вклад. Для этого не требуются дополнительные файлы, кроме тех, что поставляются с git. Все пояснения относятся к Ubuntu (проверено на 18.04LTS), должно работать аналогично на других системах Linux:

  • Найдите фрагмент кода git diff-highlight:
find -L /usr -name diff-highlight -type f

в моей системе единственный правильный ответ:

/usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Сделайте соответствующий Perl-скрипт исполняемым. В моем случае мне нужно было сделать:
sudo chmod +x /usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Обновите свой ~/.gitconfig, чтобы получить желаемый результат, добавив (обратите внимание, что это TABS, а не 4 пробела):
[color "diff-highlight"]
    oldNormal = red
    oldHighlight = red 52
    newNormal = green
    newHighlight = green 22
  • Наслаждайтесь результатом (примечание: это только для окраски diff + подсветки, у меня здесь есть и другие вещи для подсказки, конечно :)).

diff-highlight

person Zorglub29    schedule 01.04.2020