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.