Jak mogę wizualizować różnice między znakami w ujednoliconym pliku różnicowym?


122

Powiedzmy, że mam łatkę utworzoną za pomocą git format-patch. Plik jest w zasadzie ujednoliconym plikiem różnicowym z niektórymi metadanymi. Jeśli otworzę plik w Vimie, widzę, które linie zostały zmodyfikowane, ale nie mogę zobaczyć, które znaki w zmienionych wierszach się różnią. Czy ktoś zna sposób (w Vimie lub innym bezpłatnym oprogramowaniu działającym w systemie Ubuntu) na wizualizację różnic dla poszczególnych znaków?

Przykładem licznika, w którym różnica na znak jest wizualizowana, jest wykonanie vimdiff a b.

aktualizacja pt., 12 listopada, 22:36:23 UTC 2010

diffpatch jest pomocny w scenariuszu, w którym pracujesz z jednym plikiem.

aktualizacja czw., 16 czerwca, 17:56:10 UTC 2016

Sprawdź diff-highlight w git 2.9 . Ten skrypt robi dokładnie to , czego początkowo szukałem.


To może być lepsze na superuser.com
Daenyth,

13
Być może. Wybrałem stackoverflow.com, ponieważ FAQ wspomina, że ​​jest to miejsce na pytania dotyczące „narzędzi programowych powszechnie używanych przez programistów”
Adam Monsen

7
Nie jestem pewien, czy to bezpośrednio odpowiada na twoje pytanie, ale git diff --color-wordsjest bardzo przydatne, aby zobaczyć, jakie słowa zmieniają się w wierszach, zamiast zwykłego ujednoliconego wyniku różnicowego. Jest on jednak oparty na słowach, a nie znakach, więc jeśli w treści, którą porównujesz, nie ma zbyt wielu białych znaków, wynik może być mniej czysty. (Edytowano: Ups, widzę, że źle zrozumiałem, o co prosisz - niemniej może ten komentarz byłby dla kogoś przydatny.)
Mark Longair.

Odpowiedzi:


13

Biorąc pod uwagę twoje odniesienia do Vima w pytaniu, nie jestem pewien, czy to jest odpowiedź, której chcesz :) ale Emacs może to zrobić. Otwórz plik zawierający diff, upewnij się, że jesteś w diff-mode(jeżeli plik jest nazwany foo.difflub foo.patchdzieje się automatycznie, w przeciwnym razie wpisz M-x diff-mode RET), przejdź do przystojniak jesteś zainteresowany i trafiła C-c C-bdo refine-hunk. Lub przechodź przez plik po kolei za pomocą M-n; który dokona rafinacji automatycznie.


1
Pracuje dla mnie! Heh, używam Vima od 10 lat, ale właśnie zainstalowałem emacsa. :)
Adam Monsen

Ale emacs nie obsługuje czytania ze standardowego wejścia, nie mogę zrobić np.git log master.. -p | emacs -
Hi-Angel,

1
@ Hi-Angel Możesz otworzyć Emacsa i wpisać polecenie, M-!aby uruchomić polecenie i przechwycić wyjście do bufora.
legoscia

172

W git możesz scalać bez zatwierdzania. Najpierw scal swoją łatkę, a następnie wykonaj:

git diff --word-diff-regex=.

Zwróć uwagę na kropkę po znaku równości.


139
Lepiej: git diff --color-words=..
ntc2

4
@ ntc2 Twój komentarz powinien być odpowiedzią.
Tyler Collier

1
Upvoters, pamiętajcie, mój oryginalny przypadek użycia zakłada, że ​​macie tylko plik łatki , nie ma repozytorium git, a nawet wersje bazowe / zmodyfikowane. Dlatego przyjąłem odpowiedź @ legoscia ... dokładnie opisuje to, o co prosiłem.
Adam Monsen

2
@ ntc2 git diff --color-words=.i git diff --color-words .działa inaczej. Lepiej jest git diff --color-words ..
abhisekp

2
@abhisekp: dzięki za zdjęcie. Myślę, że to rozgryzłem: to git diff --color-words .jest naprawdę to samo co git diff --color-words -- .! To .znaczy , jest interpretowane jako ścieżka. Możesz zweryfikować za pomocą 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

Oto niektóre wersje z mniej hałaśliwe niż wyjście git diff --word-diff-regex=<re>i że wymagają mniej niż pisanie, ale są równoważne, git diff --color-words --word-diff-regex=<re>.

Proste (podkreśla zmiany przestrzeni):

git diff --color-words

Prosty (podkreśla indywidualne zmiany znaków; nie podkreśla zmian spacji):

git diff --color-words=.

Bardziej złożone (podkreśla zmiany przestrzeni):

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

Ogólnie:

git diff --color-words=<re>

gdzie <re>jest wyrażeniem regularnym definiującym „słowa” w celu identyfikacji zmian.

Są one mniej hałaśliwe, ponieważ kolorują zmienione „słowa”, podczas gdy po prostu --word-diff-regex=<re>otaczają dopasowane „słowa” kolorowymi -/+znacznikami.


9
Ja lubię --color-words, bez =.roli.
Tyler Collier

1
git diff --color-words='\w'działałby lepiej ze znakami diakrytycznymi (git v1.7.10.4)
nr

1
Twoja bardziej złożona wersja działa świetnie. Dołączyłem, --word-diff=plainaby dodatkowo mieć [-i -]otaczać usunięcia {+i +}otaczające dodatki. Jednak, jak ostrzega instrukcja, faktycznym wystąpieniom tych separatorów w źródle nie udało się w żaden sposób uniknąć
Tobias Kienzler

2
Twoja bardziej złożona wersja niestety nie wydaje się podkreślać np. Zmian wcięć, otworzyłem pytanie na ten temat
Tobias Kienzler

Ta odpowiedź jest świetna! Czy jest jednak sposób, aby faktycznie zmienić tło tych zmian na zielone / czerwone?
WoLfPwNeR

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

Powyższe wyrażenie regularne ( od Thomasa Rasta ) wykonuje dobrą robotę, oddzielając fragmenty różnic na poziomie interpunkcji / znaku (nie będąc tak hałaśliwym jak --word-diff-regex=.).

Zamieściłem zrzut wynikowej tutaj .


Aktualizacja:

Ten artykuł zawiera kilka świetnych sugestii. W szczególności contrib/drzewo repozytorium git zawiera diff-highlightskrypt w języku Perl, który wyświetla szczegółowe informacje.

Szybki start korzystania z niego:

$ 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
Możesz to skrócić do--color-words=[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'
Eddified

musiałem dodać 'tam wartość na początku. w przeciwnym razie wystąpił błąd. Ponadto, po prostu używam --color-wordsi otrzymuję dokładnie to samo zachowanie, co przy użyciu tego wyrażenia regularnego.
gcb

3
@gcb Treść tekstu ma znaczenie. Jeśli twoje zmiany są oddzielone spacjami, nie ma różnicy. Ale jeśli się zmienisz, jeśli zmienisz coś takiego jak foo.barna foo.qux, zobaczysz różnicę.
Justin M. Keyes,

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

1
Zainstalowałem git z Homebrew i miałem już ten skrypt pod adresem /usr/local/share/git-core/contrib/diff-highlight/diff-highlight. To zdaje się sugerować, że nie jest git Homebrew zainstalować całą contrib w /usr/local/share/git-core/contrib/. Więc w końcu dodaje pracował dla mniegit diff --color=always | /usr/local/share/git-core/contrib/diff-highlight/diff-highlight
Ashutosh Jindal

6

Jeśli nie masz nic przeciwko instalacji NodeJS, istnieje pakiet o nazwie „diff-so-fancy” ( https://github.com/so-fancy/diff-so-fancy ), który jest bardzo łatwy w instalacji i działa doskonale:

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

Edycja: Właśnie się dowiedziałem, że to w rzeczywistości opakowanie dla oficjalnego wyróżnienia różnic ... Przynajmniej jest łatwiejsze do zainstalowania dla perlofobów takich jak ja, a strona GitHub jest ładnie udokumentowana :)


2

Nie znam narzędzia do różnicowania znaków, ale istnieje narzędzie do różnicowania słów: wdiff.

zobacz przykłady 4 Najważniejsze narzędzia różnicowania plików w systemie UNIX / Linux - Diff, Colordiff, Wdiff, Vimdiff .


wdiff jest interesujący, dzięki! Aby wyjaśnić moje pierwotne pytanie, szukam czegoś, co zapewnia ulepszone podświetlanie składni dla pojedynczego pliku, który jest w ujednoliconym formacie różnicowym.
Adam Monsen,

Nieco offtopic (o różnicach słowo w słowo, bez ulepszania istniejącego wcześniej wyjścia różnicowego), ale znalazłem następujące kombinacje najlepsze dla wizualizacji słowo w słowo: * wdiff old_file new_file | cdiff * vimdiff , a następnie wewnątrz vim :windo wincmd K, aby przełączyć się na pionowy układ okna (jeden pod drugim) jeden obok drugiego. Ten układ jest znacznie lepszy dla plików z długimi wierszami.
Aleksander Adamowski

2
BTW, kilka innych narzędzi warto sprawdzić, nie wymienione w połączonej artykuł: wdiff2, mdiff, a narzędzie online Google'a .
Aleksander Adamowski

1

Po krótkich badaniach zauważyłem, że to pytanie pojawiło się ostatnio dwukrotnie na głównej liście mailingowej Vima. Wtyczki NrrwRgn wspomniano oba razy (marka dwa wąskie regiony i ich diff). Korzystanie z NrrwRgn zgodnie z opisem Christiana Brabandta wydaje się bardziej obejściem niż rozwiązaniem, ale może to wystarczy.

Wypróbowałem NrrwRgn i razem z: diffthis było rzeczywiście przydatne do zilustrowania różnic między znakami w częściach pojedynczego pliku. Ale wymagało to wielu naciśnięć klawiszy. Mój Vimscript jest dość zardzewiały, ale prawdopodobnie zawiera skrypt. Może NrrwRgn można ulepszyć, aby zapewnić pożądaną funkcjonalność.

Myśli?

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.