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.