Evidenzia le righe modificate e i byte modificati in ogni riga modificata


91

Il progetto Open Source Trac ha un eccellente evidenziatore di differenze: evidenzia le linee modificate e i byte modificati in ogni riga modificata! Vedi qui o qui per esempi.

C'è un modo per usare lo stesso colore di evidenziazione (cioè righe modificate e anche byte modificati ) nel terminale bash git, o vim per l'output diff (file patch)?


Cosa vuoi evidenziare? Vuoi uno strumento diff che evidenzi i cambiamenti di byte? (Questo sarebbe molto utile). Dici vim, a mio ricordo vim fa già molta manipolazione del colore quando usi i modelli del linguaggio di programmazione (e altri). Come lo cambieresti? Ci sono alcune tecniche disponibili per cambiare colore su una finestra di terminale definita VT100 (e ci sono dozzine di altre definizioni che supporteranno anche sequenze di fuga del colore). Maggiori dettagli per favore. Oppure leggi en.wikipedia.org/wiki/VT100 e link correlati. Forse questo può aiutare.
bombardamento

So che sei interessato solo agli strumenti open source e solo al terminale. Ma proprio come punto di riferimento potresti voler guardare la diffzilla di Slickedit. dei pochi strumenti diff che ho usato è sempre sembrato rappresentare al meglio le differenze di carattere (anche se ha sicuramente avuto problemi quando le differenze erano complesse (combinazione di formattazione e modifiche al codice, che è sempre una cattiva idea)
nhed


Nota: GitHub offre ora tale strumento un diff nella sua GUI Web: stackoverflow.com/a/25723584/6309
VonC

Ho pubblicato "ancora un altro" puro git, soluzione basata su diff-highlight con tutorial per 1) trovare facilmente il file diff-highlight pertinente, 2) renderlo eseguibile 3) impostare i parametri necessari in .gitconfig. Per favore guarda. Le istruzioni sono per Ubuntu 18.04 ma dovrebbero funzionare ampiamente sui sistemi Linux.
Zorglub 29

Risposte:


57

Lo diff-highlightscript Perl contrib produce un output così simile a quello degli screenshot di Trac che è probabile che Trac lo stia usando:

inserisci qui la descrizione dell'immagine

Installa con:

wget https://raw.githubusercontent.com/git/git/fd99e2bda0ca6a361ef03c04d6d7fdc7a9c40b78/contrib/diff-highlight/diff-highlight && chmod +x diff-highlight

Sposta il file diff-highlightnella ~/bin/directory (o ovunque tu $PATHsia), quindi aggiungi quanto segue a ~/.gitconfig:

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

Installazione singola copia incolla suggerita da @cirosantilli:

cd ~/bin
curl -O https://raw.githubusercontent.com/git/git/fd99e2bda0ca6a361ef03c04d6d7fdc7a9c40b78/contrib/diff-highlight/diff-highlight
chmod +x diff-highlight
git config --global pager.log 'diff-highlight | less'
git config --global pager.show 'diff-highlight | less'
git config --global pager.diff 'diff-highlight | less'

Questo. Questo è eccellente. Grazie. Sembra essere un po 'conservatore in alcuni punti, tuttavia, mancano alcune righe che ovviamente hanno la maggior parte del testo in comune. Hai un bug tracker per questo?
nought101

20
Ah, questo fa parte del core git adesso: github.com/git/git/tree/master/contrib/diff-highlight
nought101

2
Ora è stato trasformato in un modulo e penso che la versione più semplice da scaricare sia quella immediatamente prima di tale modifica su raw.githubusercontent.com/git/git/…
Chris Midgley,

4
Non solo questa parte del core git, è distribuita con git e probabilmente già sul tuo sistema. Ho aggiunto dettagli su come abilitarlo nella mia risposta di seguito. ↓
Cory Klein

1
Questo manca le differenze che vedi tramite git add -p. Si prega di aggiungere anche:git config --global interactive.diffFilter diff-highlight
Josch

40

Durante l'utilizzo di git diffo git loge possibilmente altri, usa l'opzione --word-diff=color(ci sono anche altre modalità per le differenze di parole BTW)


2
--word-diff=colorè davvero meglio (specialmente con git config color.diff.old "red reverse"e git config color.diff.new "green reverse"), ma non è quello che voglio :(
Nikolay Frantsev

4
Quindi l'unica cosa che ti manca è contrassegnare a colori / in qualche modo sia le righe che i byte modificati nello stesso tempo?
anydot

6
Voglio evidenziare le righe modificate e i byte modificati in ogni riga modificata, come in Trac. Non solo byte modificati, non è la stessa cosa.
Nikolay Frantsev

È inoltre possibile utilizzare questo con git add --patch: stackoverflow.com/questions/10873882/...
naught101

Il vantaggio di diff-highlightè che funziona bene sia per differenze di parola che per differenze di linea.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

20

diff-so-fancy è un diff illuminante progettato per i bulbi oculari umani.

Rimuove il leader +/- che sono fastidiose per taglia / incolla e rende chiare le sezioni tra i file.

Colorato git(a sinistra) vs diff-so-fancy(a destra - nota i punti salienti a livello di personaggio):

output diff-so-fancy

Se vuoi l' diff-so-fancyoutput (lato destro) ma non vincolato ai file in un gitrepository, aggiungi la seguente funzione al tuo .bashrcper usarlo su qualsiasi file:

dsf() { git diff --no-index --color "$@" | diff-so-fancy; }

Per esempio:

dsf original changed-file

Evidenziazione del livello di carattere e diffformato standard

Se non ti piace la formattazione non standard di diff-so-fancy, ma desideri comunque l' gitevidenziazione a livello di carattere , usadiff-highlight che prenderà gitl'output di e produrrà l' diffoutput in formato standard davvero piuttosto :

screenshot diff-highlight

Per usarlo di default da git , aggiungi a .gitconfig:

[color "diff-highlight"]
  oldNormal = red bold
  oldHighlight = red bold 52
  newNormal = green bold
  newHighlight = green bold 22

[pager]
  diff = diff-highlight | less -FRXsu --tabs=4

La [pager]sezione dice gitdi reindirizzare il suo output già colorato al diff-highlightquale si colora a livello di carattere, quindi impagina l'output in meno (se richiesto), piuttosto che usare solo il valore predefinito less.


Questo è molto interessante, potresti spiegare un po 'di queste gitconfigopzioni?
caesarsol

Aggiornato, aggiungendo anche la funzione dsf().
Tom Hale

14

Il comportamento che desideri è ora disponibile in git stesso (come è stato sottolineato in un commento da nought101). Per abilitarlo devi impostare il tuo cercapersone su

perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less

dov'è /usr/share/doc/git/contrib/diff-highlight/diff-highlightla posizione dello script dell'evidenziatore su Ubuntu 13.10 (non ho idea del perché sia ​​in una doccartella). Se non è presente nel tuo sistema, prova a utilizzarlo locate diff-highlightper trovarlo. Nota che lo script di evidenziazione non è eseguibile (almeno sulla mia macchina), da qui il requisito per perl.

Per utilizzare sempre l'evidenziatore per i vari comandi simili a diff, aggiungi quanto segue al tuo ~/.gitconfigfile:

[pager]
    log = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less
    show = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less
    diff = perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight | less

L'ho aggiunto come nuova risposta il commento di naught101 è sepolto e poiché la configurazione non è così banale come dovrebbe essere e almeno sulla versione di Ubuntu che ho le istruzioni nel README non funzionano.


Ho appena notato che questo non abilita l'evidenziazione delle differenze all'interno git add -p(modalità interattiva). Non so come risolverlo, la semplice aggiunta di aggiungi all'elenco ne causa il blocco.
dshepherd

5
Questo dovrebbe funzionare ora in git 2.9.0:git config interactive.diffFilter diff-highlight
Thomas il

^ Questo! Sfortunatamente, diff-highlightnon era sul mio percorso, quindi ho dovuto individuarlo prima. Dettagli nella mia risposta di seguito.
Cory Klein

11

Un'utilità per differenze basate su byte è stata distribuita con Git ufficiale dalla v1.7.8 1 . Devi solo individuare dove è installato sulla tua macchina e abilitarlo.

Trova dove è installato Git

  • MacOS con Git installato tramite Homebrew : è/usr/local/opt/git
  • Windows con Git per Windows : esegui cd / && pwd -Wper trovare la directory di installazione.
  • Linux: Nerd. Se non sai già dove è installato Git, allora ll $(which git)o locate gitdovresti aiutare.

Collegati diff-highlightalla tua directory bin in modo che il tuo PATH possa trovarlo

GIT_HOME='/usr/local/opt/git/'  # Use the value from the first step.
ln -s "${GIT_HOME}/share/git-core/contrib/diff-highlight/diff-highlight" \
      '/usr/local/bin/diff-highlight'

Abilitalo nella tua configurazione Git

git config --global interactive.diffFilter diff-highlight # Use on interactive prompts
git config --global pager.diff "diff-highlight | less"    # Use on git diff
git config --global pager.log  "diff-highlight | less"    # Use on git log
git config --global pager.show "diff-highlight | less"    # Use on git show

1 Ecco la versione v1.7.8 , ma da allora sono state apportate molte modifiche .


1
Sarebbe bene specificare in quale versione ha iniziato a essere distribuito con git. Inoltre immagino che le distribuzioni lo inseriranno in PATH per impostazione predefinita, quindi il passaggio del collegamento simbolico non sarà necessario? E which gitrichiede che sia nel PERCORSO in primo luogo, quindi non funzionerà se non lo è :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

2
Sarebbe buono! Sentiti libero di aggiungere queste informazioni. E sebbene Git faccia il bundle diff-highlight, in realtà non lo installa , quindi il passaggio del collegamento simbolico è effettivamente necessario (almeno su macOS). Se ritieni che non sia necessario per la tua piattaforma, sentiti di nuovo libero di aggiornare la risposta. Nel frattempo, which gitdi solito funziona, perché Git fa installare il gitqualche binario sul percorso.
Cory Klein

Notare che in debian unstable avevo bisogno di "compilare" questo file, perché avevo appena un .perl. La compilazione è banale: basta eseguire sudo makenella diff-highlightdirectory.
tobiasBora

10

Uso l' --color-wordsopzione e funziona bene per me:

$ git diff --color-words | less -RS

5
No, questo mostra solo la differenza di parole. Quello che l'OP (e io) vogliamo è un normale diff riga per riga, con le differenze di parole evidenziate (quindi, diciamo che righe diverse sono testo colorato, e le differenze di parole all'interno di quelle righe sono normali testo colorato, con evidenziazione colorata o qualcosa). Vedi i link di esempio ora nella domanda.
nought101

1
pastebin.com/1JrhYHRt In realtà uso vimdiff come difftool e vimdiff con molokai colorscheme per ottenere una bella evidenziazione come descrivi nella tua domanda. 1- git config --global diff.tool vimdiff 2- in vim ": colo molokai" * Molokai @ github.com/tomasr/molokai * Possibile schema colori automatico con ~ / .vimrc: if & diff set background = dark colorscheme molokai endif
modificato il

4

come dice @dshepherd :

Il comportamento che desideri è ora disponibile in git stesso

Ma diff-highlightsi trova in DOC e non è disponibile dalla shell.
Per installare diff-highlightnella tua ~/bindirectory segui i passaggi successivi (questo salverà la tua digitazione):

$ locate diff-highlight
$ cd /usr/share/doc/git/contrib/diff-highlight  #or path you locate
$ sudo make
$ mv diff-highlight ~/bin

Quindi configura il tuo .gitconfigdocumento ufficiale come dice:

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

UPD
Inoltre puoi provare il prossimo all'ultimo gitsenza alcuna installazione:

git diff --color-words=.

Più complesso:

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

1

Emacs ha la funzione ediff-patch-buffer che dovrebbe soddisfare le tue esigenze.

Apri il file senza patch in emacs tipo ESC-x, ediff-patch-buffer.

Segui le istruzioni e dovresti vedere un confronto evidenziato tra le versioni patchate e originali del tuo file.

Secondo il tuo commento, quanto segue ti darà una soluzione bash che richiede solo dwdiff:

#!/bin/bash
paste -d'\n' <(dwdiff -2 -L -c <(cat $2) <(patch $2 -i $1 -o -)) <(dwdiff -1 -L -c <(cat $2) <(patch $2 -i $1 -o -))| uniq

scusa, non voglio usare emacs, solo bash, git o vim
Nikolay Frantsev

È comprensibile. L'unica altra cosa a cui posso pensare è usare colordiff con lo stdout della patch: colordiff -u <(patch original_file -i patch_file -o -) <(cat original_file) ma questo evidenzierà solo le linee modificate non i morsi ...
Finbar Crago

Ho riflettuto un po 'di più sul tuo problema e ho aggiunto una seconda soluzione che richiede solo dwdiff.
Finbar Crago

1
per favore leggi attentamente la mia domanda, non voglio confrontare i file
Nikolay Frantsev

1
scusa per la confusione, quindi stai solo cercando un modo per evidenziare i byte modificati sulle righe modificate di un file diff? se è così provadwdiff -c --diff-input diff_file
Finbar Crago

1

Diffy

GitLab utilizza Diffy https://github.com/samg/diffy (Ruby) per ottenere un output simile a GitHub e diff-highlight:

inserisci qui la descrizione dell'immagine

Diffy crea il diff stesso utilizzando lo stesso algoritmo ad Git e supporta diversi tipi di output, incluso l'output HTML che GitLab utilizza:

gem install diffy
echo '
  require "diffy"    
  puts Diffy::Diff.new("a b c\n", "a B c\n").to_s(:html)
' | ruby

Produzione:

<div class="diff">
  <ul>
    <li class="del"><del>a <strong>b</strong> c</del></li>
    <li class="ins"><ins>a <strong>B</strong> c</ins></li>
  </ul>
</div>

Nota come è strongstato aggiunto ai byte modificati.


0

Sì, Vim lo fa includendo l'evidenziazione del testo modificato all'interno di una riga.
Vedi :h diffe :h 08.7per maggiori dettagli su come diff file.

Vim utilizza un algoritmo abbastanza semplice per evidenziare. Cerca nella riga il primo carattere modificato, quindi l'ultimo carattere modificato e evidenzia semplicemente tutti i caratteri tra di loro.
Ciò significa che non è possibile avere più punti salienti per riga: molte decisioni di progettazione in Vim danno la priorità all'efficienza.


sfortunatamente, non evidenzia i byte modificati sull'output diff (set filetype = diff)
Nikolay Frantsev

1
Penso di aver capito la tua domanda ora: vuoi evidenziare la sintassi dell'output testuale del comando diff in modo che evidenzi le modifiche apportate all'interno di una riga. La modifica di questo testo in Vim evidenzia le differenze di riga, ma non le modifiche apportate all'interno di una riga.
PDug

Potresti usare il comando: patchfile di Vim per caricare il file originale e poi confrontarlo con la versione patchata?
PDug

purtroppo no, voglio usare l'output diff ricorsivo per più file
Nikolay Frantsev

0

vimdiff file1 file2 mostrerà la differenza in termini di carattere tra due file.

vimdiff è uno strumento diff incluso in vim. (Vim avrebbe dovuto essere compilato con l'opzione + diff, per essere sicuri di poter controllare con :version)

Puoi anche avviarlo dall'interno di vim. Vedere :help diffper ulteriori informazioni e comandi.


Non voglio confrontare i file, voglio evidenziare il file diff (patch).
Nikolay Frantsev

@Nikolay Frantsev Se non ti interessa la performance, puoi installare il mio plugin format.vim e farlo vimdiff file.old file.new -c 'FormatCommand diffformat' -c 'w! file.diff.html' -c 'qa!'.
ZyX

Farà un diff in modalità batch (anteponi screen -D -mo accoda &>/dev/null(la variante / dev / null a volte produce strani bug) se non vuoi vedere il terminale lampeggiante) ed esce da vim dopo che la formattazione è terminata, ma è puro vimscript e anche con le mie ottimizzazioni è molto lento per file di grandi dimensioni.
ZyX

0

Nota : questo è un duplicato di ciò che si trova qui: Come migliorare l'evidenziazione delle differenze di git? . Pubblicando anche la mia risposta qui, in quanto potrebbe essere utile ad alcune persone che trovano direttamente questo thread :)

Come detto in alcune risposte precedenti, questo è possibile solo con git. Lo posto perché le istruzioni potrebbero essere un po 'più facili da seguire a seconda del sistema, ma è simile a molte altre risposte.

Una soluzione che si basa esclusivamente su git e sui suoi contributi. Ciò non richiede file aggiuntivi rispetto a quelli forniti con git . Tutte le spiegazioni sono per Ubuntu (testato su 18.04LTS), dovrebbe funzionare in modo simile su altri sistemi Linux:

  • Individua lo snippet git del contributo di evidenziazione delle differenze:
find -L /usr -name diff-highlight -type f

sul mio sistema l'unica risposta valida è:

/usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Rendi eseguibile lo script perl corrispondente. Nel mio caso dovevo fare:
sudo chmod +x /usr/share/doc/git/contrib/diff-highlight/diff-highlight
  • Aggiorna il tuo ~/.gitconfigper ottenere il risultato desiderato, aggiungendo (nota che queste sono TABELLE, non 4 spazi):
[color "diff-highlight"]
    oldNormal = red
    oldHighlight = red 52
    newNormal = green
    newHighlight = green 22
  • Goditi il ​​risultato (nota: questo è solo per la colorazione diff + l'evidenziazione, ho anche altre cose in gioco qui per il prompt ovviamente :)).

diff-highligh

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.