Come posso visualizzare le differenze per carattere in un file diff unificato?


122

Diciamo che ottengo una patch creata con git format-patch. Il file è fondamentalmente un diff unificato con alcuni metadati. Se apro il file in Vim, posso vedere quali righe sono state modificate, ma non riesco a vedere quali caratteri differiscono nelle righe modificate. Qualcuno conosce un modo (in Vim o qualche altro software gratuito che gira su Ubuntu) per visualizzare le differenze per carattere?

Un esempio di contatore in cui viene visualizzata la differenza per carattere è durante l'esecuzione vimdiff a b.

aggiornamento ven 12 novembre 22:36:23 UTC 2010

diffpatch è utile per lo scenario in cui stai lavorando con un singolo file.

aggiornamento Thu Jun 16 17:56:10 UTC 2016

Controlla l'evidenziazione delle differenze in git 2.9 . Questo script fa esattamente quello che stavo cercando originariamente.


Questo potrebbe essere migliore su superuser.com
Daenyth

13
Forse. Ho scelto stackoverflow.com poiché le FAQ menzionano che questo è il luogo per domande sugli "strumenti software comunemente usati dai programmatori"
Adam Monsen

7
Non sono sicuro che questo risponda direttamente alla tua domanda, ma git diff --color-wordsè molto utile solo per vedere quali parole cambiano all'interno delle righe, piuttosto che il solito output di diff unificato. Tuttavia, è basato su parole piuttosto che su caratteri, quindi se non c'è molto spazio bianco nel contenuto che differisci, l'output potrebbe essere meno pulito. (Modificato: Oops, vedo che ho frainteso quello che stai chiedendo - tuttavia forse questo commento sarebbe utile a qualcuno.)
Mark Longair

Risposte:


13

Dati i tuoi riferimenti a Vim nella domanda, non sono sicuro che questa sia la risposta che vuoi :) ma Emacs può farlo. Aprire il file contenente il diff, assicurarsi che siete in diff-mode(se il file è denominato foo.diffo foo.patchquesto avviene automaticamente, in caso contrario digitare M-x diff-mode RET), andare il pezzo che ti interessa e premi C-c C-bper refine-hunk. Oppure scorri il file un pezzo alla volta con M-n; quello farà la raffinazione automaticamente.


1
Per me va bene! Heh, ho usato Vim per 10 anni, ma ho appena installato emacs. :)
Adam Monsen

Ma emacs non supporta la lettura da stdin, non posso fare ad esempiogit log master.. -p | emacs -
Hi-Angel

1
@ Hi-Angel Potresti aprire Emacs e digitare M-!per eseguire il comando e catturare l'output in un buffer.
legoscia

172

In git, puoi unire senza impegnarti. Unisci prima la tua patch, quindi fai:

git diff --word-diff-regex=.

Nota il punto dopo il segno di uguale.


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

4
@ ntc2 Dovresti rendere il tuo commento una risposta.
Tyler Collier

1
Upvoters per favore nota, il mio caso d'uso originale presuppone che tu abbia solo un file patch , nessun repository git o anche versioni base / modificate. Ecco perché ho accettato la risposta di @ legoscia ... descrive esattamente quanto richiesto.
Adam Monsen

2
@ ntc2 git diff --color-words=.e git diff --color-words .funziona in modo diverso. È meglio git diff --color-words ..
abhisekp

2
@abhisekp: grazie per la foto. Penso di aver capito: git diff --color-words .è davvero lo stesso di git diff --color-words -- .! Cioè, .viene interpretato come un percorso. Puoi verificare con 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

Qui ci sono alcune versioni con uscita meno rumorosa di git diff --word-diff-regex=<re>e che richiedono la digitazione meno, ma sono equivalenti a, git diff --color-words --word-diff-regex=<re>.

Semplice (evidenzia i cambiamenti di spazio):

git diff --color-words

Semplice (evidenzia i singoli cambiamenti di carattere; non evidenzia i cambiamenti di spazio):

git diff --color-words=.

Più complesso (evidenzia i cambiamenti di spazio):

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

In generale:

git diff --color-words=<re>

dove <re>è un'espressione regolare che definisce "parole" allo scopo di identificare i cambiamenti.

Questi sono meno rumorosi in quanto colorano le "parole" modificate, mentre utilizzano solo --word-diff-regex=<re>"parole" abbinate circondano con -/+indicatori colorati .


9
Mi piace anche --color-wordssenza la =.parte.
Tyler Collier

1
git diff --color-words='\w'funzionerebbe meglio con i segni diacritici (git v1.7.10.4)
nr

1
La tua versione più complessa funziona alla grande. Ho aggiunto --word-diff=plainper aggiungere [-e -]circondare le eliminazioni {+e +}le aggiunte. Come avverte il manuale, tuttavia, le occorrenze effettive di questi delimitatori nella sorgente non sono sfuggite in alcun modo
Tobias Kienzler

2
La tua versione più complessa purtroppo non sembra evidenziare, ad esempio, le modifiche al rientro, ho aperto una domanda su questo
Tobias Kienzler

Questa risposta è fantastica! Tuttavia, esiste un modo per modificare effettivamente lo sfondo di tali modifiche in verde / rosso?
WoLfPwNeR

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

L'espressione regolare sopra ( da Thomas Rast ) fa un lavoro decente nel separare i frammenti diff a livello di punteggiatura / carattere (pur non essendo rumorosa come --word-diff-regex=.).

Ho pubblicato uno screenshot dell'output risultante qui .


Aggiornare:

Questo articolo contiene alcuni ottimi suggerimenti. Nello specifico, l' contrib/albero del repository git ha uno diff-highlightscript perl che mostra evidenziazioni a grana fine.

Inizio rapido per usarlo:

$ 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
Puoi accorciarlo a--color-words=[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'
Eddified

ho dovuto aggiungere 'all'inizio del valore lì. altrimenti ho ricevuto un errore. Inoltre, usando semplicemente --color-wordsottengo lo stesso identico comportamento dell'uso di quella regexp.
gcb

3
@gcb Il contenuto del testo è importante. Se le modifiche sono separate da spazi bianchi, non c'è differenza. Ma se si cambia se si cambia qualcosa di simile foo.bara foo.quxsi vedrà la differenza.
Justin M. Keyes

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

1
Avevo installato git con Homebrew e avevo già quello script su /usr/local/share/git-core/contrib/diff-highlight/diff-highlight. Questo sembra suggerire che il git di Homebrew installa l'intero contributo in /usr/local/share/git-core/contrib/. Quindi, alla fine, il seguente ha funzionato per megit diff --color=always | /usr/local/share/git-core/contrib/diff-highlight/diff-highlight
Ashutosh Jindal il

6

Se non hai nulla contro l'installazione di NodeJS, c'è un pacchetto chiamato "diff-so-fancy" ( https://github.com/so-fancy/diff-so-fancy ), che è molto facile da installare e funziona perfettamente:

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

Modifica: ho appena scoperto che in realtà è un wrapper per il diff-highlight ufficiale ... Almeno è più facile da installare per perlophobes come me e la pagina GitHub è ben documentata :)


2

Non sono a conoscenza dello strumento per la differenza per carattere, ma esiste uno strumento per la differenza per parola: wdiff.

fare riferimento agli esempi I 4 migliori strumenti per la differenza di file su UNIX / Linux: Diff, Colordiff, Wdiff, Vimdiff .


wdiff è interessante, grazie! Per chiarire la mia domanda originale, sto cercando qualcosa che fornisca un'evidenziazione della sintassi migliorata per un singolo file che risulta essere in formato diff unificato.
Adam Monsen

Leggermente fuori tema (sulle differenze parola per parola, che non migliorano un output diff preesistente), ma ho trovato le seguenti combinazioni migliori per le visualizzazioni parola per parola: * wdiff old_file new_file | cdiff * vimdiff , quindi all'interno di vim :windo wincmd Kper passare al layout della finestra verticale (uno sotto l'altro) fianco a fianco. Questo layout è molto migliore per i file con lunghe file.
Aleksander Adamowski

2
BTW, alcuni altri strumenti pena di verificare, non è menzionato nell'articolo collegato: wdiff2, mdiff, e lo strumento online di Google .
Aleksander Adamowski

1

Dopo un po 'di ricerca, ho notato che questa domanda è stata recentemente posta due volte sulla principale mailing list di Vim. Il plugin NrrwRgn è stato menzionato entrambe le volte (crea due regioni ristrette e diffondile). Usare NrrwRgn come descritto da Christian Brabandt sembra più una soluzione alternativa che una soluzione, ma forse è abbastanza buono.

Ho provato NrrwRgn e, insieme a: diffthis, è stato davvero utile per illustrare le differenze per carattere all'interno di parti di un singolo file. Ma ci sono voluti molti tasti. Il mio Vimscript è piuttosto arrugginito, ma potrebbe essere scritto in uno script. Forse NrrwRgn potrebbe essere migliorato per fornire la funzionalità desiderata.

Pensieri?

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.