Jak pokolorować diff w wierszu poleceń?

502

Kiedy mam różnicę, jak mogę ją pokolorować, aby dobrze wyglądała? Chcę tego w wierszu poleceń, więc proszę nie rozwiązywać GUI.

Daniel Kullmann
źródło
6
Jakiś konkretny system operacyjny / powłoka?
Rowland Shaw
4
Spróbuj github.com/walles/riff . Jako dodatkowy bonus podkreśla, które części linii uległy zmianie.
Johan Walles,

Odpowiedzi:

607

Strony diffpodręcznika dla sugerują, że nie ma rozwiązania dla samego kolorowania. Proszę rozważyć użycie colordiff. Jest to opakowanie, diffktóre wytwarza takie same dane wyjściowe jak diff, z tym wyjątkiem, że zwiększa dane wyjściowe za pomocą kolorowego podświetlania składni w celu zwiększenia czytelności:

diff old new | colordiff

Lub tylko:

colordiff old new

Instalacja:

  • Ubuntu / Debian: sudo apt-get install colordiff
  • OS X: brew install colordifflubport install colordiff
kaji
źródło
45
Właśnie to znalazłem :-). Można go potokować do mniej za pomocą less -R, która wyświetla poprawnie sekwencje specjalne dla kolorów.
Daniel Kullmann
34
Można po prostu użyć składni: colordiff plik1 plik2
Felipe Alvarez
3
Niestety, nie działa to w przypadku wyjścia równoległego ( -yopcja włączenia)vimdiffSugestia poniżej prawdopodobnie lepszym sposobem
Hi-Angel
8
colordiffdziała dobrze dla svn diff | colordiff(tj. w sytuacjach, w których masz tylko różnicę, a nie dwa różnicowane pliki).
Cornstalks
8
Jako aktualizacja komentarza @ Hi-Angel: colordiff został zaktualizowany i teraz zawiera -ywsparcie obok siebie ( ).
Bailey Parker,
333

Użyj Vima :

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

Lub jeszcze lepiej, VimDiff (lubvim -d , który jest krótszy do pisania) pokaże różnice między dwoma, trzema lub czterema plikami obok siebie.

Przykłady:

vim -d /path/to/[ab]

vimdiff file1 file2 file3 file4
Johnsyweb
źródło
7
@Jichao: Wolę uczyć się poleceń niż je aliasować. W ten sposób mogę ich używać w dowolnym miejscu, nawet gdy moje pliki dot nie są dostępne.
Johnsyweb,
1
@AquariusPower: ctrl-ci ctrl-xmają inne zastosowania w Vimie. ctrl-qjest przechwytywany przez wiele terminali. Zobacz Pisanie i rzucanie, aby znaleźć sposób, który najlepiej odpowiada Twoim potrzebom.
Johnsyweb
1
Po pierwsze, co to za skorupa? zsh? Nie rozpoznaję =(...)konstrukcji. Po drugie, miałem diff -ur a bna myśli.
x-yuri
1
To rozwiązanie jest lepsze niż zaakceptowana odpowiedź, ponieważ nie wymaga posiadania uprawnień administratora systemu i instalowania dodatkowego narzędzia
amanzoor
173

Właściwie wydaje się, że istnieje jeszcze jedna opcja (którą zauważyłem niedawno, gdy napotkałem wyżej opisany problem):

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

Jeśli masz Git w pobliżu (z którego już i tak możesz już korzystać), będziesz mógł użyć go do porównania, nawet jeśli same pliki nie są pod kontrolą wersji. Jeśli opcja ta nie jest domyślnie włączona, włączenie obsługi kolorów wydaje się znacznie łatwiejsze niż niektóre z wcześniej wspomnianych obejść.

Lars Baehren
źródło
19
To jest fajne, ale niestety nie działa, gdy wejściowe są potoki. Na przykład porównywanie plików binarnych za pomocą git diff <(xxd file1) <(xxd filed)nie działa.
Michael Anderson
8
Co dziwne, co najmniej jeden z plików musi znajdować się „poza bieżącym repozytorium”, zgodnie z git help diff. Więc jeśli twój git diff jest pusty, wypróbuj to cd, gdzie jesteś.
Złe żądanie
7
Aby włączyć kolory dla git diff:git config color.diff auto
JWhy
2
bardzo proste i szybkie
EE33
31
Jeśli oba pliki znajdują się w bieżącym repozytorium, użyj git diff --no-indexdo porównania dwóch plików.
Olivier „Ölbaum” Scherler
94

diff --color opcja została dodana do GNU diffutils 3.4 (2016-08-08)

To jest domyślne diff implementacja większości dystrybucji, która wkrótce ją otrzyma.

Ubuntu 18.04 ma wersję diffutils3.6 i dlatego ją posiada.

W wersji 3.5 wygląda to tak:

wprowadź opis zdjęcia tutaj

Przetestowany:

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

Najwyraźniej dodano w zatwierdzeniu c0fa19fe92da71404f809aafb5f51cfd99b1bee2 (marzec 2015).

Różnica na poziomie słowa

Jak diff-highlight. Wygląda na to, że nie jest możliwe, żądanie funkcji: https://lists.gnu.org/archive/html/diffutils-devel/2017-01/msg00001.html

Powiązane wątki:

ydiff robi to, patrz poniżej.

ydiff diff poziom słowa obok siebie

https://github.com/ymattw/ydiff

Czy to jest nirwana?

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

Wynik:

wprowadź opis zdjęcia tutaj

Jeśli linie są zbyt wąskie (domyślnie 80 kolumn), dopasuj do ekranu za pomocą:

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

Zawartość plików testowych:

za

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

b

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 Integracja z Git

ydiff integruje się z Git bez wymaganej konfiguracji.

Z repozytorium git zamiast git diffmożesz zrobić tylko:

ydiff -s

i zamiast git log:

ydiff -ls

Zobacz także: Jak mogę uzyskać diff side-by-side, gdy robię „git diff”?

Testowane na Ubuntu 16.04, git 2.18.0, ydiff 1.1.

Ciro Santilli
źródło
Oto dokumentacja.
Alexey,
1
W tym wątku listy adresowej: There is no word-highlighting, yet- jakieś aktualizacje? Właśnie do tego doszedłem do tego pytania (chcę grep --colorwynik wyjściowy diff).
i336_
@ i336_ brak aktualizacji niestety, jeśli je otrzymam, zaktualizuję pytanie. Pinguj mnie, jeśli coś znajdziesz.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Nawiasem mówiąc, git diff --colordziała również. Przydatne podczas pracy nad ssh.
Nagev
Różnica zbyt duża? usediff --color=always | less -R
inetphantom
69

A w przypadkach, gdy a yum install colordifflub an apt-get install colordiffnie jest opcją z powodu jakiegoś szalonego ograniczenia poza twoją bezpośrednią kontrolą lub po prostu oszalałeś , możesz ponownie wymyślić koło z linią sed:

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

Rzuć to w skrypcie powłoki i potokuj przez nią ujednolicone wyjście różnicowe .

Sprawia, że ​​znaczniki przystojniaków stają się niebieskie, a nowe / stare nazwy plików i dodane / usunięte linie odpowiednio na zielonym i czerwonym tle. 1 I sprawi, że końcowe zmiany spacji 2 będą bardziej widoczne niż kolordiff może.


1 Nawiasem mówiąc, powodem podświetlenia nazw plików tak samo, jak zmodyfikowanych linii jest to, że prawidłowe rozróżnienie między nazwami plików a zmodyfikowanymi liniami wymaga odpowiedniego parsowania formatu diff, co nie jest czymś, z czym trzeba się zmierzyć za pomocą wyrażenia regularnego. Podkreślenie ich to samo działa „wystarczająco dobrze” wizualnie i sprawia, że ​​problem staje się trywialny. To powiedziawszy, istnieje kilka interesujących subtelności .

2 Ale nie końcowe tabulatory. Najwyraźniej zakładki nie mają ustawionego tła, przynajmniej w moim Xtermie. To sprawia, że ​​zmiany tabulacji i spacji nieco się wyróżniają.

retracile
źródło
5
@Matt: Oto podejście brutalne dla komputerów Mac: sed "s/^-/`echo -e \"\x1b\"`[41m-/;s/^+/`echo -e \"\x1b\"`[42m+/;s/^@/`echo -e \"\x1b\"`[34m@/;s/$/`echo -e \"\x1b\"`[0m/"(ale spodziewam się, że jest lepszy sposób).
retracile
1
Hmm, to trochę działało ... dało 3 kreski między każdym kawałkiem różowym tłem.
Matt Montag,
Ręczny nieczytelny, niemożliwy do utrzymania sposób bez opcji łatwej zmiany kolorów, na przykład.
1
Koleś, to jest niesamowite! Tak trzymać! To niezła magia sed.
myśliciel
6
sed 's / ^ - / \ x1b [31m - /; s / ^ + / \ x1b [32m + /; s / ^ @ / \ x1b [34m @ /; s / $ / \ x1b [0m /' ') również wygląda świetnie
Yura
16

Możesz zmienić konfigurację subversion, aby używać 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

przez: https://gist.github.com/westonruter/846524

Azd325
źródło
svn: Nie można rozpocząć procesu „colordiff”: zasób tymczasowo niedostępny
niken
Czy zainstalowałeś colordiff?
Azd325,
Tak, próbowałem też zakodować ścieżkę na stałe (bieganie w cygwinie)
niken,
idk spróbuj może ten superuser.com/questions/635995/…
Azd325,
12

Kolorowe wyjście na poziomie słowa diff

Oto, co możesz zrobić z poniższym skryptem i wyróżnieniem różnic :

Kolorowy zrzut ekranu różnicy

#!/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

( Podziękowania dla odpowiedzi @ retracile dla sedwyróżnienia)

Tom Hale
źródło
Jak korzystać z tego wyjścia w GVim?
Hemant Sharma
Do vimużyj wtyczki, np . Diffchar .
Tom Hale,
10

Używam grc(Generic Colouriser), który pozwala pokolorować wyjście wielu poleceń, w tym diff.

Jest to skrypt Pythona, który można zawinąć wokół dowolnego polecenia. Zamiast więc wywoływać diff file1 file2, można wywoływać, grc diff file1 file2aby zobaczyć kolorowe wyjście. Mam alias diff, aby grc diffułatwić.

dogbane
źródło
Nie działa w systemie Windows z mingw / cygwin z powodu fork()wywołań, chociaż prawdopodobnie działa z WSL.
Gabriel Devillers
6

Oto kolejne rozwiązanie, które wywołuje sedwstawić odpowiednie sekwencje ANSI ewakuacyjnych na kolory, aby pokazać +, -i @linii w kolorze czerwonym, zielonym i błękitnym, odpowiednio.

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

W przeciwieństwie do innych rozwiązań tego pytania, to rozwiązanie nie określa wprost sekwencji ucieczki ANSI. Zamiast tego wywołuje polecenia tput setafi tput sgr0, aby wygenerować sekwencje specjalne ANSI, aby odpowiednio ustawić odpowiedni kolor i zresetować atrybuty terminala.

Aby zobaczyć dostępne kolory dla każdego argumentu tput setaf, użyj tego polecenia:

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

Oto jak wygląda wyjście:

wprowadź opis zdjęcia tutaj

Oto dowód, że polecenia tput setafi tput sgr0generują odpowiednie sekwencje specjalne 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
Susam Pal
źródło
5

Ponieważ wdiffakceptuje argumenty określające ciąg na początku i na końcu zarówno wstawiania, jak i usuwania, możesz użyć sekwencji kolorów ANSI jako tych ciągów:

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

Na przykład jest to wynik porównania dwóch plików CSV:

wyjście różnicowe plików CSV

Przykład z https://www.gnu.org/software/wdiff/manual/html_node/wdiff-Examples.html

jcomeau_ictx
źródło
1
colordiffteraz (1.0.16) rozumie wdiff, więc można też po prostu rury: wdiff -n f1 f2 | colordiff. wdiffpowinny zostać połączone w diffutils ...
Ciro Santilli 20 冠状 病 六四 六四 法轮功 法轮功
3

Sugerowałbym, abyś zrobił coś tak fantazyjnego . Używam go podczas pracy i na pewno wydaje się świetny na teraz. Dostarczany jest z wieloma opcjami i naprawdę łatwo skonfigurować dyfuzję tak, jak chcesz.

Możesz go zainstalować:

sudo npm install -g diff-so-fancy

lub na Macu:

brew install diff-so-fancy

Następnie możesz wyróżnić swoje różnice w następujący sposób:

diff -u file1 file2 | diff-so-fancy
Naveen
źródło
1

Z poleceniem nietoperza :

diff file1 file2 | bat -l diff
Jian Weihang
źródło
0

W najnowszych wersjach git na Ubuntu możesz włączyć wyróżnianie różnic za pomocą:

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

A następnie dodając to do .gitconfig:

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

Możliwe jest, że skrypt znajduje się gdzie indziej w innych dystrybucjach, możesz locate diff-highlightdowiedzieć się gdzie.

naught101
źródło
0

Różnica kolorów na poziomie znaków: zainstaluj ccdiff

ccdiff -r /usr/share/dict/words /tmp/new-dict

Wyjście ccdiff

morela
źródło