Come diff diffondo lo stesso file tra due commit diversi sullo stesso ramo?


Risposte:


1476

Dalla git-diffmanpage:

git diff [--options] <commit> <commit> [--] [<path>...]

Ad esempio, per vedere la differenza per un file "main.c" tra ora e due commit, ecco tre comandi equivalenti:

$ git diff HEAD^^ HEAD main.c
$ git diff HEAD^^..HEAD -- main.c
$ git diff HEAD~2 HEAD -- main.c

43
Non ..è davvero necessario, anche se funzionerà con esso (tranne nelle versioni abbastanza vecchie, forse). Puoi anche usare git logo gitkper trovare SHA1 da usare, nel caso in cui i due commit siano molto distanti. gitkha anche un "diff selezionato -> questo" e "diff this -> selezionato" nel suo menu contestuale.
Cascabel,

17
Funzionerà anche se il nome del file è stato modificato tra i 2 commit?
reubenjohn,

26
Quindi qual è lo scopo del "-"
user64141

29
@ user64141 --È utile, ad esempio, quando si dispone di un file denominato -p. Buono da usare negli script, solo in rari casi necessari in pratica.
Palec,

13
Nota: è necessario utilizzare i percorsi relativi alla radice del repository. I percorsi relativi alla directory di lavoro corrente non funzioneranno.
Kevin Wheeler,

281

Puoi anche confrontare due diversi file in due diverse revisioni, in questo modo:

git diff <revision_1>:<file_1> <revision_2>:<file_2>


25
si noti che sembra che se <file_1>e si <file_2>trovano nella directory corrente, non nella directory gestita git di livello superiore, si deve anteporre ./a Unix:<revision_1>:./filename_1
Andre Holzner,

7
<revisione>: può essere omesso, in modo da poter differire con un file che non è stato ancora eseguito il commit.
Yaroslav Nikitenko il

2
Si noti che su Windows si deve usare '/' per i percorsi dei file, non '\'.
np8,

88

Se hai configurato il "difftool" puoi usare

git difftool revision_1:file_1 revision_2:file_2

Esempio: confronto di un file dall'ultimo commit con il precedente commit sullo stesso ramo: supponendo che se ci si trova nella cartella principale del progetto

$git difftool HEAD:src/main/java/com.xyz.test/MyApp.java HEAD^:src/main/java/com.xyz.test/MyApp.java

Dovresti avere le seguenti voci nel tuo ~ / .gitconfig o nel file project / .git / config. Installa p4merge [Questo è il mio strumento preferito diff e mer]

[merge]
    tool = p4merge
    keepBackup = false
[diff]
    tool = p4merge
    keepBackup = false
[difftool "p4merge"]
    path = C:/Program Files (x86)/Perforce/p4merge.exe
[mergetool]
    keepBackup = false
[difftool]
    keepBackup = false
[mergetool "p4merge"]
    path = C:/Program Files (x86)/Perforce/p4merge.exe
    cmd = p4merge.exe \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"

50

Controllare $ git log, copiare l' ID SHA-1 dei due diversi commit ed eseguire il git diffcomando con tali ID. per esempio:

$ git diff (sha-id-one) (sha-id-two)

18
Se vuoi il diff per un file specifico, aggiungi il percorso ad esso alla fine del comando.
hBrent,

Esegui anche un "git pull" per scaricare tutte le informazioni sull'albero se i due commit si trovano su rami diversi. Altrimenti otterrai un errore "fatal: bad object".
user238607

4
git diff (sha-id-one) (sha-id-two) -- filename.ext senza il nome file elencherà le differenze di tutti i file in questi due commit.
SherylHohman,

40

Se vuoi vedere tutte le modifiche al file tra i due commit su base commit-by-commit, puoi anche farlo

git log -u $start_commit..$end_commit -- path/to/file


Che cos'è "$ start_commit" e "$ end_commit"? Sono letterali o, in caso contrario, puoi fornire un esempio?
Peter Mortensen,

Queste sono variabili della shell che contengono la revisione iniziale e finale, che possono invece essere letterali o ref sha1
cxreg

21

Ecco uno script Perl che stampa i comandi Git diff per un dato file come si trova in un comando Git log.

Per esempio

git log pom.xml | perl gldiff.pl 3 pom.xml

I rendimenti:

git diff 5cc287:pom.xml e8e420:pom.xml
git diff 3aa914:pom.xml 7476e1:pom.xml
git diff 422bfd:pom.xml f92ad8:pom.xml

che potrebbe quindi essere tagliato e incollato in una sessione della finestra shell o reindirizzato a /bin/sh.

Appunti:

  1. il numero (3 in questo caso) specifica quante righe stampare
  2. il file (pom.xml in questo caso) deve concordare in entrambe le posizioni (è possibile inserirlo in una funzione di shell per fornire lo stesso file in entrambe le posizioni) o inserirlo in una directory binaria come script di shell

Codice:

# gldiff.pl
use strict;

my $max  = shift;
my $file = shift;

die "not a number" unless $max =~ m/\d+/;
die "not a file"   unless -f $file;

my $count;
my @lines;

while (<>) {
    chomp;
    next unless s/^commit\s+(.*)//;
    my $commit = $1;
    push @lines, sprintf "%s:%s", substr($commit,0,6),$file;
    if (@lines == 2) {
        printf "git diff %s %s\n", @lines;
        @lines = ();
    }
    last if ++$count >= $max *2;
}

14

Se vuoi fare una diff con più di un file, con il metodo specificato da @mipadi:

Ad esempio diff tra HEADe your master, per trovare tutti i .coffeefile:

git diff master..HEAD -- `find your_search_folder/ -name '*.coffee'`

In questo modo ricorsivo cercare il vostro your_search_folder/per tutti .coffeei file e fare un diff tra loro e le loro masterversioni.


13

Se hai diversi file o directory e desideri confrontare commit non continui, puoi farlo:

Crea un ramo temporaneo ( "revisione" in questo esempio)

git checkout -b revision

Riavvolgi al primo target di commit

git reset --hard <commit_target>

La ciliegina su coloro che si impegnano interessati

git cherry-pick <commit_interested> ...

Applica diff

git diff <commit-target>^

Quando hai finito

git branch -D revision

2
Grazie per questa soluzione Ha funzionato bene per il mio caso d'uso. L'unica cosa che vorrei aggiornare è che quando hai finito non puoi eliminare il ramo fino a quando non lo spegni.
Steven Dix,

9

Solo un altro modo di usare la bellezza di Git ...

git difftool HEAD HEAD@{N} /PATH/FILE.ext

Ho definito un alias da questa risposta che funziona con bash:difftool-file = "!git difftool HEAD@{\"$2\"} HEAD \"$1\" #"
blueogive

2

Se si desidera un semplice confronto visivo su Windows come è possibile ottenere in Visual SourceSafe o Team Foundation Server (TFS), provare questo:

  • fare clic con il tasto destro sul file in Esplora file
  • seleziona "Cronologia Git"

Nota: dopo l'aggiornamento a Windows 10 ho perso le opzioni del menu di scelta rapida di Git. Tuttavia, puoi ottenere la stessa cosa usando 'gitk' o 'gitk nomefile' in una finestra di comando.

Dopo aver chiamato "Cronologia Git", verrà avviato lo strumento Git GUI, con una cronologia del file nel riquadro in alto a sinistra. Seleziona una delle versioni che desideri confrontare. Quindi fai clic con il pulsante destro del mouse sulla seconda versione e scegli uno dei due

Diff questo -> selezionato

o

Diff selezionato -> questo

Le differenze con codice colore appariranno nel riquadro in basso a sinistra.


Nota per i downvoter: questa è una soluzione semplice, facile da implementare e risolve il problema del PO. Funziona su Windows che l'OP sta chiaramente usando (vedi riferimenti a TFS e VSS nella domanda).
Risorsa
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.