Як я можу візуалізувати відмінності між персонажами в уніфікованому файлі diff?


122

Скажіть, я отримую патч, створений за допомогою git format-patch. Файл, в основному, є уніфікованим розходженням з деякими метаданими. Якщо я відкрию файл у Vim, я бачу, які рядки були змінені, але я не бачу, які символи в змінених рядках відрізняються. Хтось знає спосіб (у Vim чи іншому вільному програмному забезпеченні, що працює на Ubuntu) візуалізувати відмінності між персонажами?

Приклад лічильника, коли візуалізується різниця символів, - це при виконанні vimdiff a b.

оновлення Пт 12 листопада 22:36:23 UTC 2010

diffpatch корисний для сценарію, коли ви працюєте з одним файлом.

оновлення Чт 16 червня 17:56:10 UTC 2016

Ознайомтеся з відміткою підсвічування в git 2.9 . Цей сценарій робить саме те , чого я спочатку шукав.


Це може бути краще на superuser.com
Daenyth

13
Можливо, Я вибрав stackoverflow.com, оскільки FAQ часто згадує, що це місце для запитань про "програмні засоби, якими зазвичай користуються програмісти"
Адам Монсен,

7
Я не впевнений, що це безпосередньо відповідає на ваше запитання, але git diff --color-wordsдуже корисно для того, щоб побачити, які слова змінюються в рядках, а не звичайний уніфікований різний вихід. Це, однак, на основі слів, а не на основі символів, тому, якщо у вмісті, який ви відрізняєте, не так багато пробілів, вихід може бути менш акуратним. (Відредаговано: На жаль, я бачу, що я неправильно зрозумів, про що ви просите - все ж, можливо, цей коментар комусь буде корисний.)
Марк Лонгейр,

Відповіді:


13

З огляду на ваші посилання на Vim у запитанні, я не впевнений, чи це відповідь, яку ви хочете :), але Emacs може це зробити. Відкрийте файл, що містить diff, переконайтеся, що ви перебуваєте diff-mode(якщо файл названий foo.diffабо foo.patchце відбувається автоматично; в іншому випадку введіть M-x diff-mode RET), перейдіть до потрібної частини, і натисніть C-c C-bна refine-hunk. Або перегляньте файл один раз за разом M-n; це зробить очищення автоматично.


1
Для мене працює! Хе, я використовую Vim 10 років, але я просто встановив emacs. :)
Адам Монсен

Але emacs не підтримує читання з stdin, я не можу робити, наприклад,git log master.. -p | emacs -
Привіт-Ангел,

1
@ Hi-Angel Ви можете відкрити Emacs і набрати M-!для запуску команди та захоплення виводу в буфер.
legoscia

172

У git ви можете зливатися, не вчиняючи. Спочатку з’єднайте свій патч, а потім виконайте:

git diff --word-diff-regex=.

Відмітьте крапку після знака рівності.


139
Краще : git diff --color-words=..
ntc2

4
@ ntc2 Ви повинні зробити свій коментар відповіддю.
Тайлер Колліер

1
Оголошення, будь ласка, зауважте, що в моєму оригінальному випадку використання ви маєте лише файл виправлення , відсутність git repo або навіть базові / модифіковані версії. Ось чому я прийняв відповідь @ legoscia ... в ній точно описується те, що просили.
Адам Монсен

2
@ ntc2 git diff --color-words=.і git diff --color-words .працює інакше. Краще git diff --color-words ..
abhisekp

2
@abhisekp: дякую за фото. Я думаю, я зрозумів це: git diff --color-words .справді те саме, що git diff --color-words -- .! Тобто, .інтерпретується як шлях. Ви можете підтвердити за допомогою mkdir x y; echo foo > x/test; git add x/test; git commit -m test; echo boo > x/test; cd y; git diff --color-words=.; git diff --color-words .; git diff --color-words -- ..
ntc2

145

Ось деякі версії з менш гучним , ніж виходом git diff --word-diff-regex=<re>і вимагає менше , ніж друкувати, але еквівалентні, git diff --color-words --word-diff-regex=<re>.

Просте (чи підкреслює простір):

git diff --color-words

Простий (виділяє окремі зміни символів; не виділяє змін у просторі):

git diff --color-words=.

Більш складні (чи підкреслює зміни місця):

git diff --color-words='[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'

В загальному:

git diff --color-words=<re>

де <re>є регулярне вираження, що визначає "слова" з метою виявлення змін.

Вони менш галасливі тим, що вони забарвлюють змінені "слова", тоді як за допомогою просто --word-diff-regex=<re>оточуючих зібраних "слів" кольоровими -/+маркерами.


9
Мені самому подобається --color-words, без =.частини.
Тайлер Коллієр

1
git diff --color-words='\w'буде краще працювати з діакритикою (git v1.7.10.4)
nr

1
Ваша більш складна версія чудово працює. Я доклав --word-diff=plainдодатково мати [-і -]тилові делеции і {+і +}об'ємне додаток. Як зазначає посібник, однак, фактичного виникнення цих роздільників у джерелі жодним чином не уникнути
Тобіас Кіенцлер

2
На жаль, ваша більш складна версія, на жаль, не висвітлює, наприклад, зміни відступів, я відкрив питання щодо цього
Тобіас Кіенцлер

Ця відповідь чудова! Однак чи є спосіб фактично змінити фон цих змін на зелений / червоний?
WoLfPwNeR

45
git diff --color-words="[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+"

Вищенаведений регекс ( від Thomas Rast ) справляє гідну роботу по розділенню розрізних фрагментів на рівні пунктуації / символів (при цьому не настільки шумно, як --word-diff-regex=.).

Я розмістив скріншот отриманого результату тут .


Оновлення:

У цій статті є кілька чудових пропозицій. Зокрема, contrib/дерево git repo має diff-highlightсценарій perl, який показує дрібнозернисті виділення.

Швидкий початок його використання:

$ curl https://git.kernel.org/cgit/git/git.git/plain/contrib/diff-highlight/diff-highlight > diff-highlight
$ chmod u+x diff-highlight
$ git diff --color=always HEAD~10 | diff-highlight | less -R

5
Можна скоротити його до--color-words=[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'
Відредаговано

я повинен був додати 'до початку значення там. в іншому випадку я отримав помилку. Крім того, я просто за допомогою --color-wordsя отримую абсолютно таку ж поведінку, що і за допомогою цього regexp.
gcb

3
@gcb Зміст тексту має значення. Якщо ваші зміни розділені пробілом, різниці немає. Але якщо змінити , якщо змінити що - щось подібне , foo.barщоб foo.quxви побачите різницю.
Justin M. Keyes

5
Simpler: git diff --color-words='[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'.
ntc2

1
Я встановив git з Homebrew і вже мав цей сценарій у /usr/local/share/git-core/contrib/diff-highlight/diff-highlight. Це дозволяє припустити , що мерзотник доморощеного в це встановити весь вно в /usr/local/share/git-core/contrib/. Отже, нарешті, для мене спрацювало наступнеgit diff --color=always | /usr/local/share/git-core/contrib/diff-highlight/diff-highlight
Ашутош

6

Якщо у вас немає нічого проти встановлення NodeJS, є пакет під назвою "diff-so-fancy" ( https://github.com/so-fancy/diff-so-fancy ), який дуже легко встановити і прекрасно працює:

npm install -g diff-so-fancy
git diff --color | diff-so-fancy | less -R

Редагувати: Щойно з’ясували, що це насправді обгортка для офіційного розрізнення ... Принаймні, простіше встановити для перлофобів, як я, і сторінка GitHub чудово задокументована :)


2

Я не знаю про інструмент різниці символів, але є інструмент різниці в слові: wdiff.

наведені приклади. Найпопулярніші 4 інструменти різниці файлів у UNIX / Linux - Diff, Colordiff, Wdiff, Vimdiff .


wdiff цікаво, дякую! Щоб уточнити своє первісне запитання, я шукаю те, що забезпечує розширене підсвічування синтаксису для одного файлу, який має бути в уніфікованому форматі diff.
Адам Монсен

Трохи офтопік (про слово в слово розрізняється, не посилюючи попередній диференціальний вихід), але я знайшов такі комбінації, найкращі для візуалізації «слово за словом»: * wdiff old_file new_file | cdiff * vimdiff , потім всередині vim :windo wincmd K, щоб перейти на вертикальний макет вікна (один під іншим) з боку на бік. Такий макет набагато краще для файлів з довгими рядками.
Олександр Адамовський

2
До речі, перевірити деякі інші інструменти стоять, не згаданих в пов'язаної статті: wdiff2, mdiffі в онлайн - інструмент від Google .
Олександр Адамовський

1

Після невеликого дослідження, я помічаю, що це питання в останній раз виникало двічі в головному списку розсилки Vim. Плагін NrrwRgn був згаданий як раз (зробити дві вузькі області та дифф їх). Використання NrrwRgn, описане Крістіаном Брабандом, більше схоже на рішення, ніж на рішення, але, можливо, це досить добре.

Я спробував NrrwRgn, і він, разом з: diffthis, справді був корисним для ілюстрації відмінностей між персонажами в частинах одного файлу. Але знадобилося багато натискань на клавіші. Мій Vimscript досить іржавий, але це, ймовірно, може бути сценарієм. Можливо, NrrwRgn можна було б покращити, щоб забезпечити бажану функціональність.

Думки?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.