Как раскрасить diff в командной строке?

504

Когда у меня есть различия, как я могу раскрасить их так, чтобы они хорошо выглядели? Я хочу это для командной строки, поэтому, пожалуйста, никаких решений с графическим интерфейсом.

Даниэль Куллманн
источник
6
Любая конкретная операционная система / оболочка?
Роуланд Шоу
4
Попробуйте github.com/walles/riff . В качестве дополнительного бонуса, он выделяет, какие части линий изменились.
Йохан Уоллес

Ответы:

608

Страницы руководства для diffпредлагают не решение для раскрашивания изнутри себя. Пожалуйста, подумайте об использовании colordiff. Это оболочка, diffкоторая выдает тот же вывод, что и diff, за исключением того, что она увеличивает вывод, используя цветную подсветку синтаксиса для повышения читабельности:

diff old new | colordiff

или просто:

colordiff old new

Установка:

  • Ubuntu / Debian: sudo apt-get install colordiff
  • OS X: brew install colordiffилиport install colordiff
кажи
источник
45
Просто нашел это сам :-). Он может быть добавлен в меньшее с помощью less -R, который правильно отображает escape-последовательности для цветов.
Даниэль Куллманн
34
Можно просто использовать синтаксис: colordiff file1 file2
Felipe Alvarez
3
Увы, он не работает для параллельного вывода ( -yопция включена ) below vimdiffПредложение ниже, вероятно, лучший способ
Hi-Angel
8
colordiffхорошо работает svn diff | colordiff(например, в ситуациях, когда у вас есть только diff, а не два файла diffd).
Кукурузные стебли
8
В качестве обновления комментария @ Hi-Angel: colordiff был обновлен и теперь включает поддержку рядом ( -y).
Бейли Паркер
333

Используйте Vim :

diff /path/to/a /path/to/b | vim -R -

Или, что еще лучше, VimDiff (или vim -d, что короче, чтобы печатать) будет показывать различия между двумя, тремя или четырьмя файлами рядом.

Примеры:

vim -d /path/to/[ab]

vimdiff file1 file2 file3 file4
Johnsyweb
источник
7
@Jichao: я предпочитаю изучать команды, а не дублировать их. Таким образом, я могу использовать их где угодно, даже когда мои точечные файлы недоступны.
Johnsyweb
1
@ AquariusPower: ctrl-cи ctrl-xдля других целей в Vim. ctrl-qзахвачено многими терминалами. См. Написание и выход, чтобы найти способ, который наилучшим образом соответствует вашим потребностям.
Johnsyweb
1
Во-первых, что это за оболочка? zsh? Я не узнаю =(...)конструкт. Во-вторых, я имел diff -ur a bв виду.
х-юри
1
Это решение лучше, чем принятый ответ, так как оно не требует от вас прав системного администратора и установки какого-либо дополнительного инструмента
amanzoor
173

На самом деле, кажется, есть еще один вариант (который я заметил недавно, когда столкнулся с проблемой, описанной выше):

git diff --no-index <file1> <file2>
# output to console instead of opening a pager
git --no-pager diff --no-index <file1> <file2>

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

Ларс Баерен
источник
19
Это аккуратно, но, к сожалению, это не работает, когда входные данные представляют собой каналы. Например, сравнение двоичных файлов с помощью git diff <(xxd file1) <(xxd filed)не работает.
Майкл Андерсон
8
Как ни странно, по крайней мере, один из файлов должен быть «вне текущего хранилища» git help diff. Так что, если ваш git diff пуст, попробуйте cdвыйти туда, где вы находитесь.
Плохой запрос
7
Чтобы включить цвета для git diff:git config color.diff auto
JWhy
2
супер просто и быстро
EE33
31
Если оба файла находятся внутри текущего репозитория, используйте git diff --no-indexдля сравнения двух файлов.
Оливье Ольбаум Шерлер
95

diff --color опция была добавлена ​​в GNU diffutils 3.4 (2016-08-08)

Это diffреализация по умолчанию на большинстве дистрибутивов, которые скоро получат ее.

Ubuntu 18.04 имеет diffutils3,6 и, следовательно, имеет его.

На 3.5 это выглядит так:

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

Проверено:

diff --color -u \
  <(seq 6 | sed 's/$/ a/') \
  <(seq 8 | grep -Ev '^(2|3)$' | sed 's/$/ a/')

По-видимому, добавлено в коммит c0fa19fe92da71404f809aafb5f51cfd99b1bee2 (март 2015).

Различия на уровне слов

Как diff-highlight. Не представляется возможным, запрос функции: https://lists.gnu.org/archive/html/diffutils-devel/2017-01/msg00001.html

Связанные темы:

ydiff хотя, смотрите ниже.

ydiff параллельный уровень слова diff

https://github.com/ymattw/ydiff

Это Нирвана?

python3 -m pip install --user ydiff
diff -u a b | ydiff -s

Результат:

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

Если линии слишком узкие (по умолчанию 80 столбцов), поместите их на экран с помощью:

diff -u a b | ydiff -w 0 -s

Содержание тестовых файлов:

a

1
2
3
4
5 the original line the original line the original line the original line
6
7
8
9
10
11
12
13
14
15 the original line the original line the original line the original line
16
17
18
19
20

б

1
2
3
4
5 the original line teh original line the original line the original line
6
7
8
9
10
11
12
13
14
15 the original line the original line the original line the origlnal line
16
17
18
19
20

ydiff Git интеграция

ydiff интегрируется с Git без какой-либо настройки.

Внутри Git-репозитория вместо этого git diffвы можете сделать просто:

ydiff -s

и вместо git log:

ydiff -ls

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

Протестировано на Ubuntu 16.04, git 2.18.0, ydiff 1.1.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
источник
Вот документация.
Алексей
1
В этой ветке списка рассылки: There is no word-highlighting, yet- есть обновления? Это то, для чего я пришел к этому вопросу (я хочу получить grep --colorаналогичный вывод).
i336_
@ i336_ нет обновлений к сожалению, если получу, обновлю вопрос. Пинг мне, если найдешь.
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
Кстати git diff --colorтоже работает. Полезно при работе над ssh.
Нагев
Дифф слишком большой? использованиеdiff --color=always | less -R
inetphantom
69

И в тех случаях, когда yum install colordiffили или apt-get install colordiffне вариант из-за какого-то безумного ограничения вне вашего непосредственного контроля, или вы просто чувствуете себя сумасшедшим , вы можете заново изобрести колесо с помощью строки sed:

sed 's/^-/\x1b[41m-/;s/^+/\x1b[42m+/;s/^@/\x1b[34m@/;s/$/\x1b[0m/'

Добавьте это в сценарий оболочки и передайте через него унифицированный вывод diff .

Он делает маркеры фрагментов синим цветом и выделяет новые / старые имена файлов и добавленные / удаленные строки на зеленом и красном фоне соответственно. 1 И это сделает изменения в конце 2 более заметными, чем может сделать colordiff.


1 Кстати, причина для выделения имен файлов , так же , как модифицированные линии является то , что правильно различать имена файлов и модифицированные строки требует правильно разбор формата различия, который не является чем - то решать с регулярным выражением. Выделение их одинаково работает «достаточно хорошо» визуально и делает задачу тривиальной. Тем не менее, есть некоторые интересные тонкости .

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

retracile
источник
5
@Matt: Вот подход грубой силы для Mac: sed "s/^-/`echo -e \"\x1b\"`[41m-/;s/^+/`echo -e \"\x1b\"`[42m+/;s/^@/`echo -e \"\x1b\"`[34m@/;s/$/`echo -e \"\x1b\"`[0m/"(хотя я ожидаю, что есть лучший способ).
откат
1
Хм, это вроде сработало ... дало 3 черточкам между блоками розовый фон.
Мэтт Монтег
Ручной нечитаемый, не поддерживаемый способ без возможности легко менять цвета например.
1
Чувак это круто! Путь! Это немного хорошего волшебства седа.
Fthinker
6
sed 's / ^ - / \ x1b [31m - /; s / ^ + / \ x1b [32m + /; s / ^ @ / \ x1b [34m @ /; s / $ / \ x1b [0m /' также выглядит великолепно
Юра
16

Вы можете изменить конфигурацию Subversion для использования Colordiff

~ / .Subversion / config.diff

 ### Set diff-cmd to the absolute path of your 'diff' program.
 ###   This will override the compile-time default, which is to use
 ###   Subversion's internal diff implementation.
-# diff-cmd = diff_program (diff, gdiff, etc.)
+diff-cmd = colordiff

через: https://gist.github.com/westonruter/846524

Azd325
источник
svn: не удается запустить процесс 'colordiff': ресурс временно недоступен
niken
Вы установили colordiff?
Azd325
Да, я тоже пытался
жестко запрограммировать
idk попробовать может это superuser.com/questions/635995/…
Azd325
12

Цветной вывод на уровне слов diff

Вот что вы можете сделать с помощью приведенного ниже сценария и diff-highlight :

Цветной скриншот diff

#!/bin/sh -eu

# Use diff-highlight to show word-level differences

diff -U3 --minimal "$@" |
  sed 's/^-/\x1b[1;31m-/;s/^+/\x1b[1;32m+/;s/^@/\x1b[1;34m@/;s/$/\x1b[0m/' |
  diff-highlight

( Благодарим за ответ @ retracile за sedвыделение)

Том Хейл
источник
Как мне использовать этот вывод в GVim?
Хемант Шарма
Для vim, используйте плагин, например, diffchar .
Том Хейл,
10

я использую grc (Generic Colouriser), который позволяет раскрасить вывод ряда команд, в том числе diff.

Это скрипт на python, который можно обернуть вокруг любой команды. Таким образом, вместо того diff file1 file2, чтобы вызывать, вы бы вызывали, grc diff file1 file2чтобы увидеть цветной вывод. Я псевдонимы , diffчтобы grc diffсделать его проще.

кендырь
источник
Не работает в Windows с mingw / cygwin из-за fork()вызовов, хотя, скорее всего, будет работать с WSL.
Габриэль Девиллерс
6

Вот еще одно решение , которое вызывает sedвставить соответствующие последовательности ANSI спасая цвета , чтобы показать +, -и @линию в красном, зеленый и голубой, соответственно.

diff -u old new | sed "s/^-/$(tput setaf 1)&/; s/^+/$(tput setaf 2)&/; s/^@/$(tput setaf 6)&/; s/$/$(tput sgr0)/"

В отличие от других решений этого вопроса, в этом решении явно не указаны escape-последовательности ANSI. Вместо этого он вызывает tput setafиtput sgr0 команды для генерации последовательностей ANSI побега для установки соответствующего цвета и сброса атрибутов терминала, соответственно.

Чтобы увидеть доступные цвета для каждого аргумента tput setaf, используйте эту команду:

for i in {0..255}; do tput setaf $i; printf %4d $i; done; tput sgr0; echo

Вот как выглядит результат:

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

Вот доказательство того , что tput setafи tput sgr0команды генерируют соответствующие управляющие последовательности ANSI:

$ tput setaf 1 | xxd -g1
00000000: 1b 5b 33 31 6d                                   .[31m
$ tput setaf 2 | xxd -g1
00000000: 1b 5b 33 32 6d                                   .[32m
$ tput setaf 6 | xxd -g1
00000000: 1b 5b 33 36 6d                                   .[36m
$ tput sgr0 | xxd -g1
00000000: 1b 28 42 1b 5b 6d                                .(B.[m
Сусам Пал
источник
5

Так как wdiffпринимает аргументы, указывающие строку в начале и конце как вставок, так и удалений, вы можете использовать цветовые последовательности ANSI в качестве этих строк:

wdiff -n -w $'\033[30;41m' -x $'\033[0m' -y $'\033[30;42m' -z $'\033[0m' file1 file2

Например, это результат сравнения двух CSV-файлов:

Дифференциальный вывод файлов CSV

Пример из https://www.gnu.org/software/wdiff/manual/html_node/wdiff-Examples.html

jcomeau_ictx
источник
1
colordiffТеперь (1.0.16) понимает wdiff, так что вы можете просто труба: wdiff -n f1 f2 | colordiff. wdiffдолжны быть объединены в diffutils ...
Сиро Сантилли 法轮功 冠状 病 六四 事件 法轮功
3

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

Вы можете установить его:

sudo npm install -g diff-so-fancy

или на Mac:

brew install diff-so-fancy

После этого вы можете выделить свои различия следующим образом:

diff -u file1 file2 | diff-so-fancy
Нэвин
источник
0

В последних версиях git на Ubuntu вы можете включить подсветку diff с помощью:

sudo ln -s /usr/share/doc/git/contrib/diff-highlight/diff-highlight /usr/local/bin
sudo chmod a+x /usr/share/doc/git/contrib/diff-highlight/diff-highlight

И затем добавив это к вашему .gitconfig:

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

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

naught101
источник