Quando scrivo "git diff", mi piacerebbe vedere un diff side-by-side, come con "diff -y", o mi piacerebbe visualizzare il diff in uno strumento interattivo come "kdiff3". Come si può fare?
Quando scrivo "git diff", mi piacerebbe vedere un diff side-by-side, come con "diff -y", o mi piacerebbe visualizzare il diff in uno strumento interattivo come "kdiff3". Come si può fare?
Risposte:
Sebbene Git abbia un'implementazione interna di diff, puoi invece impostare uno strumento esterno.
Esistono due modi diversi per specificare uno strumento diff esterno:
GIT_EXTERNAL_DIFF
e ilGIT_DIFF_OPTS
ambiente variabili.git config
Guarda anche:
git diff --help
Quando si esegue un git diff
, Git controlla sia le impostazioni delle variabili di ambiente sopra che le sue.gitconfig
file.
Per impostazione predefinita, Git passa i seguenti sette argomenti al programma diff:
path old-file old-hex old-mode new-file new-hex new-mode
In genere sono necessari solo i parametri old-file e new-file. Naturalmente la maggior parte degli strumenti diff prende solo due nomi di file come argomento. Questo significa che devi scrivere un piccolo script wrapper, che prende gli argomenti che Git fornisce allo script e li passa al programma git esterno di tua scelta.
Diciamo che hai messo il tuo script wrapper sotto ~/scripts/my_diff.sh
:
#!/bin/bash
# un-comment one diff tool you'd like to use
# side-by-side diff with custom options:
# /usr/bin/sdiff -w200 -l "$2" "$5"
# using kdiff3 as the side-by-side diff:
# /usr/bin/kdiff3 "$2" "$5"
# using Meld
/usr/bin/meld "$2" "$5"
# using VIM
# /usr/bin/vim -d "$2" "$5"
devi quindi rendere eseguibile quello script:
chmod a+x ~/scripts/my_diff.sh
devi quindi dire a Git come e dove trovare il tuo script wrapper diff personalizzato. Hai tre scelte su come farlo: (Preferisco modificare il file .gitconfig)
Utilizzando GIT_EXTERNAL_DIFF
,GIT_DIFF_OPTS
ad es. nel tuo file .bashrc o .bash_profile puoi impostare:
GIT_EXTERNAL_DIFF=$HOME/scripts/my_diff.sh
export GIT_EXTERNAL_DIFF
utilizzando git config
usa "git config" per definire dove trovare lo script wrapper:
git config --global diff.external ~/scripts/my_diff.sh
Modifica il tuo ~/.gitconfig
file
puoi modificare il tuo ~/.gitconfig
file per aggiungere queste righe:
[diff]
external = ~/scripts/my_diff.sh
Nota:
Analogamente all'installazione del tuo strumento diff personalizzato, puoi anche installare uno strumento di unione personalizzato, che potrebbe essere uno strumento di fusione visiva per aiutare a visualizzare meglio l'unione. (vedi la pagina progit.org)
Vedi: http://fredpalma.com/518/visual-diff-and-merge-tool/ e https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration
meld
?
meld
versione può essere configurata per fare una directory diff, dove posso scegliere per quale / i file voglio vedere il diff? Attualmente esegue un meld
comando separato per ogni file e devo chiudere meld
per vedere il file successivo. Preferirei meld
mostrarmi un elenco di directory di file modificati come si comporta quando meld
viene utilizzato da Mercurial.
Usa git difftool
invece di git diff
. Non tornerai mai indietro.
Ecco un link ad un altro stackoverflow che parla di git difftool
: Come posso visualizzare l'output 'git diff' con il mio strumento / visualizzatore diff preferito?
Per le versioni più recenti di git
, il difftool
comando supporta immediatamente molti strumenti diff esterni. Ad esempio, vimdiff
è supportato automaticamente e può essere aperto dalla riga di comando:
cd /path/to/git/repo
git difftool --tool=vimdiff
Altri strumenti di diff esterni supportati sono elencati tramite git difftool --tool-help
qui è un esempio di output:
'git difftool --tool=<tool>' may be set to one of the following:
araxis
kompare
vimdiff
vimdiff2
The following tools are valid, but not currently available:
bc3
codecompare
deltawalker
diffuse
ecmerge
emerge
gvimdiff
gvimdiff2
kdiff3
meld
opendiff
tkdiff
xxdiff
This message is displayed because 'diff.tool' is not configured.
. Forse aggiorna la risposta con il minimo come configurare questa cosa, in modo che mostri differenze affiancate nel terminale, qual è ciò che OP ha richiesto? Gli strumenti della GUI sono abbastanza inutili sul server remoto a cui ti connetti usando ssh.
git difftool
con vimdiff
non sempre allineare correttamente i due file / buffer.
git difftool -y
per prevenire il prompt di
git difftool
in Windows e Linux: stackoverflow.com/a/48979939/4561887
Puoi anche provare git diff --word-diff
. Non è esattamente fianco a fianco, ma in qualche modo migliore, quindi potresti preferirlo al tuo reale bisogno fianco a fianco.
git diff --word-diff=color
--word-diff=color
mi dà un errore di opzione non valido. In quale versione è stata introdotta?
git diff --color-words
funziona.
git diff --color-words
è la strada da percorrere nelle moderne versioni di git.
ydiff
Precedentemente chiamato cdiff
, questo strumento può mostrare differenze affiancate , incrementali e colorate .
Invece di fare git diff
, fai:
ydiff -s -w0
Questo si avvierà ydiff
in modalità di visualizzazione affiancata per ciascuno dei file con differenze.
Installa con:
python3 -m pip install --user ydiff
-o-
brew install ydiff
Per git log
, puoi usare:
ydiff -ls -w0
-w0
rileva automaticamente la larghezza del tuo terminale. Vedi la ydiff
pagina del repository GitHub per dettagli e demo.
Testato in Git 2.18.0, ydiff 1.1.
git diff | cdiff -s
con icdiff?
ydiff -s
cd <git repo>
e poi eseguiydiff -ls <path/to/file>
Si può fare un side-by-side diff
con sdiff
il seguente:
$ git difftool -y -x sdiff HEAD^ | less
dov'è HEAD^
un esempio che dovresti sostituire con qualunque cosa tu voglia diff.
Ho trovato questa soluzione qui dove ci sono anche un paio di altri suggerimenti. Tuttavia, questa risposta è la domanda del PO in modo succinto e chiaro.
Vedi l' uomo git-difftool per una spiegazione degli argomenti.
Prendendo in considerazione i commenti, puoi creare un comodo git sdiff
comando scrivendo il seguente script eseguibile:
#!/bin/sh
git difftool -y -x "sdiff -w $(tput cols)" "${@}" | less
Salvalo come /usr/bin/git-sdiff
e chmod -x
. Quindi sarai in grado di fare questo:
$ git sdiff HEAD^
tput cols
, invece, ad esempio: git difftool -x "sdiff -s -w $(tput cols)"
.
export GIT_EXTERNAL_DIFF='meld $2 $5; echo >/dev/null'
quindi semplicemente:
git diff
Se desideri visualizzare le differenze side-by-side in un browser senza coinvolgere GitHub, potresti goderti git webdiff , un sostituto drop-in per git diff
:
$ pip install webdiff
$ git webdiff
Ciò offre una serie di vantaggi rispetto ai difftools della GUI tradizionale, tkdiff
in quanto può darti l'evidenziazione della sintassi e mostrare le differenze dell'immagine.
Leggi di più qui .
Uso colordiff .
Su Mac OS X, installalo con
$ sudo port install colordiff
Su Linux è forse apt get install colordiff
o qualcosa del genere, a seconda della tua distribuzione.
Poi:
$ git difftool --extcmd="colordiff -ydw" HEAD^ HEAD
O crea un alias
$ git alias diffy "difftool --extcmd=\"colordiff -ydw\""
Quindi puoi usarlo
$ git diffy HEAD^ HEAD
L'ho chiamato "diffy" perché diff -y
è la differenza side-by-side in unix. Colordiff aggiunge anche colori, che sono più belli. Nell'opzione -ydw
, y
è per side-by-side, w
è per ignorare gli spazi bianchi e d
è per produrre il minimo diff (di solito si ottiene un risultato migliore come diff)
-y
per saltare il Launch 'colordiff' [Y/n]:
prompt.
git alias diffy "difftool --extcmd=\"colordiff -ydw\""
? Non dovrebbe essere git config --global alias.diffy "difftool --extcmd=\"colordiff -ydw\""
?
Per unix, combinando just git
e il built-in diff
:
git show HEAD:path/to/file | diff -y - path/to/file
Ovviamente, puoi sostituire HEAD con qualsiasi altro riferimento git e probabilmente vorrai aggiungere qualcosa di simile -W 170
al comando diff.
Ciò presuppone che stai solo confrontando i contenuti della tua directory con un commit passato. Il confronto tra due commit è più complesso. Se la tua shell è bash
, puoi usare la "sostituzione del processo":
diff -y -W 170 <(git show REF1:path/to/file) <(git show REF2:path/to/file)
dove REF1
e REF2
sono riferimenti git - tag, rami o hash.
Personalmente mi piace davvero icdiff !
Se siete in Mac OS X
con HomeBrew
, basta fare brew install icdiff
.
Per ottenere correttamente le etichette dei file, oltre ad altre interessanti funzioni, ho nel mio ~/.gitconfig
:
[pager]
difftool = true
[diff]
tool = icdiff
[difftool "icdiff"]
cmd = icdiff --head=5000 --highlight --line-numbers -L \"$BASE\" -L \"$REMOTE\" \"$LOCAL\" \"$REMOTE\"
E lo uso come: git difftool
Questa domanda è emersa quando stavo cercando un modo rapido per usare git builtin in modo da individuare le differenze. I miei criteri di soluzione:
Ho trovato questa risposta per ottenere colore in git.
Per affiancare diff invece che diff line ho modificato l'eccellente risposta di mb14 su questa domanda con i seguenti parametri:
$ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]"
Se non ti piace il extra [- o {+, è --word-diff=color
possibile utilizzare l'opzione .
$ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]" --word-diff=color
Ciò ha contribuito a ottenere un corretto confronto sia con il testo json e xml che con il codice java.
In sintesi, le --word-diff-regex
opzioni hanno una visibilità utile insieme alle impostazioni del colore per ottenere un'esperienza di codice colore affiancata rispetto al diff di linea standard, quando si sfogliano file di grandi dimensioni con piccoli cambiamenti di linea.
Molti altri hanno già menzionato cdiff per git side-by-side diffing, ma nessuno ne ha dato piena attuazione.
Setup cdiff:
git clone https://github.com/ymattw/cdiff.git
cd cdiff
ln -s `pwd`/cdiff ~/bin/cdiff
hash -r # refresh your PATH executable in bash (or 'rehash' if you use tcsh)
# or just create a new terminal
Modifica ~ / .gitconfig inserendo queste righe:
[pager]
diff = false
show = false
[diff]
tool = cdiff
external = "cdiff -s $2 $5 #"
[difftool "cdiff"]
cmd = cdiff -s \"$LOCAL\" \"$REMOTE\"
[alias]
showw = show --ext-dif
Il cercapersone disattivato è necessario affinché cdiff funzioni con Diff, è comunque essenzialmente un cercapersone, quindi va bene. Difftool funzionerà indipendentemente da queste impostazioni.
L'alias show è necessario perché git show supporta solo strumenti diff esterni tramite argomento.
Il '#' alla fine del comando esterno diff è importante. Il comando diff di Git aggiunge $ @ (tutte le variabili diff disponibili) al comando diff, ma vogliamo solo i due nomi di file. Quindi chiamiamo quei due in modo esplicito con $ 2 e $ 5, quindi nascondiamo $ @ dietro un commento che altrimenti confonderebbe sdiff. Il risultato è un errore simile a:
fatal: <FILENAME>: no such path in the working tree
Use 'git <command> -- <path>...' to specify paths that do not exist locally.
Comandi Git che ora producono la differenza side-by-side:
git diff <SHA1> <SHA2>
git difftool <SHA1> <SHA2>
git showw <SHA>
Utilizzo di Cdiff:
'SPACEBAR' - Advances the page of the current file.
'Q' - Quits current file, thus advancing you to the next file.
Ora hai diff side-by-side via git diff e difftool. E hai il codice sorgente cdiff python per la personalizzazione di power user se ne hai bisogno.
Ecco un approccio. Se installi meno, la larghezza xterm è impostata su 80, che non è così caldo. Ma se si procede con il comando, ad esempio COLS = 210, è possibile utilizzare xterm espanso.
gitdiff()
{
local width=${COLS:-$(tput cols)}
GIT_EXTERNAL_DIFF="diff -yW$width \$2 \$5; echo >/dev/null" git diff "$@"
}
Apri Intellij IDEA , seleziona uno o più commit nella finestra dello strumento "Controllo versione", sfoglia i file modificati e fai doppio clic su di essi per controllare le modifiche fianco a fianco per ogni file.
Con il programma di avvio della riga di comando in bundle è possibile portare IDEA ovunque con un semplice idea some/path
Ci sono molte buone risposte su questo thread. La mia soluzione a questo problema era scrivere una sceneggiatura.
Assegna un nome a "git-scriptname" (e rendilo eseguibile e inseriscilo nel tuo PERCORSO, come qualsiasi script), e puoi invocarlo come un normale comando git eseguendo
$ git scriptname
La funzionalità effettiva è solo l'ultima riga. Ecco la fonte:
#!/usr/bin/env zsh
#
# Show a side-by-side diff of a particular file how it currently exists between:
# * the file system
# * in HEAD (latest committed changes)
function usage() {
cat <<-HERE
USAGE
$(basename $1) <file>
Show a side-by-side diff of a particular file between the current versions:
* on the file system (latest edited changes)
* in HEAD (latest committed changes)
HERE
}
if [[ $# = 0 ]]; then
usage $0
exit
fi
file=$1
diff -y =(git show HEAD:$file) $file | pygmentize -g | less -R
Questa potrebbe essere una soluzione un po 'limitata, ma fa il lavoro usando il diff
comando del sistema senza strumenti esterni:
diff -y <(git show from-rev:the/file/path) <(git show to-rev:the/file/path)
--suppress-common-lines
(se ladiff
l'opzione è supportata).diff
pennarelli--width=term-width
; in Bash puoi ottenere la larghezza come $COLUMNS
o tput cols
.Questo può essere racchiuso in un helper git-script anche per una maggiore comodità, ad esempio un utilizzo come questo:
git diffy the/file/path --from rev1 --to rev2