Виділіть змінені рядки та змінені байти в кожному зміненому рядку


93

Проект з відкритим кодом Trac має чудовий підсвічувач різниць - він виділяє змінені рядки та змінені байти в кожному зміненому рядку! Дивіться тут або тут приклади.

Чи є спосіб використовувати однакові кольорові виділення (тобто змінені рядки та також змінені байти ) у терміналі bash git, або vim для виводу diff (патч-файл)?


Що саме ви хочете виділити? Ви хочете інструмент diff, який підкреслює зміни байтів? (це було б дуже корисно). Ви кажете vim, наскільки я пам’ятаю, vim робить багато маніпуляцій із кольором вже тоді, коли ви використовуєте шаблони мови програмування (та інші). Як би ви це змінили? Існує досить багато способів змінити колір у вікні терміналу, яке визначено VT100 (і є десятки інших визначень, які також підтримуватимуть послідовність кольорових екранів). Докладніше, будь ласка. Або прочитайте en.wikipedia.org/wiki/VT100 та відповідні посилання. Можливо, це може допомогти.
обстріл

Я знаю, що вас цікавлять лише інструменти з відкритим кодом, і лише термінал. Але просто як орієнтир ви можете подивитися на diffzilla slickedit. з небагатьох дифф інструментів , які я використовував це завжди , здається, найкраще представляють відмінності характеру (хоча це безперечно були проблеми , коли диференціали , де комплекс (поєднання форматування і зміни коду, який завжди погана ідея)
nhed


Примітка: GitHub тепер пропонує такий інструмент відмінностей в веб - інтерфейс: stackoverflow.com/a/25723584/6309
VonC

Я опублікував "ще одне" рішення на основі git, diff-highlight з підручниками, щоб легко 1) знайти відповідний файл diff-highlight, 2) зробити його виконуваним 3) встановити необхідні параметри в .gitconfig. Будь ласка, подивіться. Інструкції стосуються Ubuntu 18.04, але вони повинні широко працювати в системах Linux.
Zorglub29,

Відповіді:


59

diff-highlightВно сценарій 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

Це. Це чудово. Дякую. Здається, в деяких місцях це трохи консервативно, проте відсутні деякі рядки, які, очевидно, мають більшість спільного тексту. У вас є для цього помилка-трекер?
naught101

21
Ах, це зараз частина основного git: github.com/git/git/tree/master/contrib/diff-highlight
naught101

2
Зараз його перетворили на модуль, і я думаю, що найпростішою для завантаження версією є версія безпосередньо перед цією зміною на raw.githubusercontent.com/git/git/…
Кріс Мідглі

4
Ця частина не тільки основного git, вона розповсюджується разом з git і, мабуть, уже у вашій системі. Я додав детальну інформацію про те, як його ввімкнути, у своїй відповіді нижче. ↓
Кори Кляйн

2
Це пропускає різниці, які ви бачите через git add -p. Будь ласка, також додайте:git config --global interactive.diffFilter diff-highlight
josch

40

Під час використання git diffабо, git logі, можливо, інших, використовуйте опцію --word-diff=color(є також інші режими для різниці слів до речі)


2
--word-diff=colorсправді краще (особливо з git config color.diff.old "red reverse"і git config color.diff.new "green reverse"), але це не те, що я хочу :(
Микола Францев

4
Тобто єдине, чого вам не вистачає, це маркування кольором / як-то змінені рядки та байти одночасно?
anydot

7
Я хочу виділити змінені рядки та змінені байти в кожному зміненому рядку, як у Trac. Не просто змінені байти, це не те саме.
Микола Францев

Ви також можете використовувати це з git add --patch: stackoverflow.com/questions/10873882 / ...
naught101

Перевага diff-highlightполягає в тому, що він добре працює як для різниці слів, так і для різниці рядків.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

21

diff-so-fancy- це - diffвипромінювач, призначений для очних яблук людини.

Він видаляє провідні +/ -які дратують вирізання / вставлення та робить чіткі розділи між файлами.

Кольорові git(ліворуч) проти diff-so-fancy(праворуч - зверніть увагу на основні моменти):

диференційований висновок

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

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

Наприклад:

dsf original changed-file

Виділення на рівні символів та стандартний diffформат

Якщо вам не подобається нестандартне форматування diff-so-fancy, але ви все-таки хочете gitпідсвічування на рівні символів , скористайтеся методом, diff-highlightякий прийме gitвихідні дані та виведе справді досить гарний diffвихід стандартного формату:

скріншот різного виділення

Щоб використовувати його за замовчуванням з 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до труби його вже colourised висновок , diff-highlightякий colourises на рівні символів, а потім сторінки виведення менше (якщо потрібно), а не просто використовувати за замовчуванням less.


Це дуже цікаво, чи можете ви трохи пояснити ці gitconfigваріанти?
цезарсол

Оновлено, також додано функцію dsf().
Том Хейл

15

Ваша поведінка тепер доступна у самому 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 , не працює.


Я щойно помітив, що це не дозволяє підсвічувати різниці в межах git add -p(інтерактивний режим). Я не знаю, як це можна виправити, хоча просто додавання до списку призводить до зависання.
dshepherd

5
Зараз це має працювати в git 2.9.0:git config interactive.diffFilter diff-highlight
Томас

^ Це! На жаль, diff-highlightце не було на моєму шляху, тому мені довелося знайти його першим. Деталі в моїй відповіді нижче.
Кори Кляйн,

11

Утиліта для байтових відмінностей поширюється з офіційним Git з версії 1.7.8 1 . Вам просто потрібно знайти, де він встановлений на вашому комп'ютері, і увімкнути його.

Знайдіть, де встановлено Git

  • MacOS з Git, встановленим через Homebrew : Це/usr/local/opt/git
  • Windows з Git для Windows : Запустіть, cd / && pwd -Wщоб знайти каталог встановлення.
  • Linux: Nerd. Якщо ви ще не знаєте, де встановлений 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 , але з тих пір було внесено багато змін .


1
Було б непогано вказати, в якій версії він розпочав поширюватися за допомогою git. Також я здогадуюсь, що дистрибутиви помістять його в PATH за замовчуванням, тож крок символічного посилання не знадобиться? І which gitвимагає, щоб він спочатку був у PATH, щоб він не працював, якщо ні :-)
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

2
Було б добре! Не соромтеся додавати цю інформацію. І хоча Git поєднується diff-highlight, він насправді не встановлює його, тому крок символічного посилання дійсно необхідний (принаймні на macOS). Якщо ви виявите, що це не потрібно для вашої платформи, знову сміливо оновлюйте відповідь. Тим часом which gitзазвичай працює, бо Git робить установки gitбінарного де - то на шляху.
Кори Кляйн

Зверніть увагу, що в нестабільному debian мені потрібно було "скомпілювати" цей файл, оскільки я просто мав файл .perl. Компіляція тривіальна: просто запустіть sudo makeу diff-highlightкаталозі.
tobiasBora

10

Я використовую --color-wordsопцію, і вона добре працює для мене:

$ git diff --color-words | less -RS

5
Ні, це тільки показує різницю в словах. Те, що хочуть OP (і я), - це звичайна різниця між рядками, з виділеними різницями слів (так, припустимо, різні рядки - кольоровий текст, а різниці слів у цих рядках - це звичайний кольоровий текст, з кольоровим підсвічуванням або щось). Див. Приклади посилань зараз у питанні.
naught101

1
pastebin.com/1JrhYHRt Насправді я використовую vimdiff як difftool і vimdiff з молокаї кольоровою схемою, щоб отримати гарне виділення, як ви описуєте у своєму питанні. 1- git config --global diff.tool vimdiff 2- in vim ": colo molokai" * Molokai @ github.com/tomasr/molokai * Можлива автоматична схема кольорів з ~ / .vimrc: if & diff set background = dark colorscheme molokai endif
вихвалено

4

як каже @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)+'

1

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

вибачте, я не хочу використовувати emacs, лише bash, git або vim
Микола Францев

Це зрозуміло. Єдине, що я можу придумати, - це використовувати colordiff із stdout з патча: colordiff -u <(patch original_file -i patch_file -o -) <(cat original_file) але це лише виділить змінені лінії, а не укуси ...
Finbar Crago

Я трохи більше подумав про вашу проблему і додав друге рішення, яке вимагає лише dwdiff.
Finbar Crago

1
будь ласка, уважно прочитайте моє запитання, я не хочу порівнювати файли
Микола Францев

1
вибачте за плутанину, отже, ваш спосіб просто виділити змінені байти на змінених рядках файлу diff? якщо так, спробуйтеdwdiff -c --diff-input diff_file
Finbar Crago

1

Diffy

GitLab використовує Diffy https://github.com/samg/diffy (Ruby) для досягнення результатів, схожих на GitHub, і diff-highlight:

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

Diffy робить сам diff, використовуючи один і той же алгоритм і 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було додано до змінених байтів.


0

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

Vim використовує досить простий алгоритм для виділення. Він здійснює пошук у рядку першого зміненого символу, а потім останнього зміненого символу, і просто виділяє всі символи між ними.
Це означає, що у вас не може бути декількох основних моментів у рядку - багато дизайнерських рішень у Vim ставлять за мету ефективність.


на жаль, він не виділяє змінені байти при виведенні різниці (встановити тип файлу = різниця)
Микола Францев

1
Думаю, я зараз розумію ваше запитання - Ви хочете, щоб синтаксис виділив текстовий результат команди diff, щоб він висвітлював будь-які зміни, внесені всередині рядка. Редагування цього тексту у Vim підкреслює різницю рядків, але не зміни, внесені всередині рядка.
PDug

Чи можете ви використати команду Vim's: patchfile для завантаження вихідного файлу, а потім порівняти його з виправленою версією?
PDug

на жаль ні, я хочу використовувати рекурсивний вивід різниці для декількох файлів
Микола Францев

0

vimdiff file1 file2 відображатиме різницю між двома файлами в символьному значенні.

vimdiff - це різний інструмент, що входить до vim. (Vim повинен був скомпільований з опцією + diff, щоб переконатись, що ви можете перевірити :version)

Ви також можете запустити його зсередини vim. Дивіться :help diffдодаткову інформацію та команди.


Я не хочу порівнювати файли, я хочу виділити файл diff (патч).
Микола Францев

@Nikolay Frantsev Якщо ви не дбаєте про виступ, ви можете встановити мій плагін format.vim і зробити vimdiff file.old file.new -c 'FormatCommand diffformat' -c 'w! file.diff.html' -c 'qa!'.
ZyX

Він буде робити різницю в пакетному режимі (додавати screen -D -mабо додавати &>/dev/null(варіант / dev / null іноді видає дивні помилки), якщо ви не хочете бачити, як термінал блимає) і вийти з vim після форматування, але це чисто vimscript навіть при моїй оптимізації це дуже повільно для великих файлів.
ZyX

0

Примітка : це дублікат того, що тут знайдено: Як поліпшити підсвічування різниці git?. Опублікувавши тут і свою відповідь, оскільки це може бути корисно для деяких людей, які знаходять безпосередньо цю тему :)

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

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

  • Знайдіть фрагмент git фрагмента cont-cont:
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щоб отримати бажаний результат, додавши (зверніть увагу, це ТАБУЛКИ, а не 4 пробіли):
[color "diff-highlight"]
    oldNormal = red
    oldHighlight = red 52
    newNormal = green
    newHighlight = green 22
  • Насолоджуйтесь результатом (примітка: це лише для розмальовки різниць + підсвічування, я теж тут маю на увазі інші речі, звичайно :)).

диф-хайлайт

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