Come diff un commit con il suo genitore?


460

Oltre a scrivere un alias o uno script, esiste un comando più breve per ottenere il diff per un determinato commit?

git diff 15dc8^..15dc8

Se si assegna un solo ID di commit git diff 15dc8, si differenzia tale commit rispetto a HEAD.


La cosa più bella di questo sarebbe che funzionerebbe con "git difftool", usando gli strumenti per mostrare il diff.
Orip,

Per riferimento, la risposta a questa altra domanda illustra come è possibile impostare un alias basato su bash per semplificare quanto sopra: stackoverflow.com/questions/3321492/…
Nick,

Risposte:


641

Usa git show $COMMIT. Ti mostrerà il messaggio di registro per il commit e la differenza di quel particolare commit.


45
Peccato che non possa usare difftool :(
orip

1
@orip puoi sempre impostare GIT_EXTERNAL_DIFF su uno script che fa la stessa cosa del tuo difftool.
slacy

7
Io preferisco la risposta di JakubNarebski, come l'espressione data commit ci saranno lavorare in molti contesti: stackoverflow.com/a/449128/992887
RichVel

1
Se non viene mostrato diff, probabilmente non ci sono cambiamenti effettivi, come per un commit di merge
Devin G Rhode,

6
@PTWithy: La domanda era: "Esiste un comando più breve per ottenere il diff per un determinato commit?", A cui risponde questa domanda.
mipadi,

439

Uso:

git diff 15dc8^!

come descritto nel seguente frammento della manpage git-rev-parse (1) (o nella moderna manpage git gitrevisions (7) ):

Esistono altri due shorthands per la denominazione di un set formato da un commit e dei suoi parent parent. La notazione r1 ^ @ indica tutti i genitori di r1. r1 ^! include commit r1 ma esclude tutti i suoi genitori.

Ciò significa che è possibile utilizzare 15dc8^!come scorciatoia 15dc8^..15dc8ovunque in git dove sono necessarie revisioni. Per comando diffgit diff 15dc8^..15dc8 si intende come git diff 15dc8^ 15dc8, il che significa la differenza tra parent di commit ( 15dc8^) e commit ( 15dc8).

Nota : la descrizione nella git-rev-parse(1)manpage parla degli intervalli di revisione , dove deve funzionare anche per i merge commit, con più di un genitore. Quindi r1^!è " r1 --not r1^@" ie " r1 ^r1^1 ^r1^2 ..."


Inoltre, è possibile utilizzare git show COMMITper ottenere la descrizione del commit e la differenza per un commit. Se vuoi solo diff, puoi usaregit diff-tree -p COMMIT


7
Questa dovrebbe essere la risposta accettata, è molto più ordinata. Tuttavia, l'ultima frase dell'estratto di git-rev-parse è piuttosto confusa - sembra che significhi "andare dal genitore di questo commit a questo commit".
RichVel

1
@RichVel: è un po 'confuso perché cerca di descrivere anche la situazione in cui il commit ha più di un genitore (è un commit di unione). r1 ^! funziona come previsto anche allora.
Jakub Narębski,

@ JakubNarębski: buon punto, forse potresti modificare la tua risposta per riassumere la tua comprensione dei casi con genitori monoparentali e genitori multipli - dichiarazioni separate su ciascuno di essi potrebbero essere più facili da capire.
RichVel

1
@ JakubNarębski: sì, molto meglio! Ora uso sempre questa scorciatoia, grazie.
RichVel

1
La ^!notazione abbreviata principale funziona correttamente con difftool per i commit normali, ma il diff è invertito per i commit di merge. Perchè così?
hIpPy

56

Se sai quanto lontano, puoi provare qualcosa del tipo:

# Current branch vs. parent
git diff HEAD^ HEAD

# Current branch, diff between commits 2 and 3 times back
git diff HEAD~3 HEAD~2

I commit precedenti funzionano in questo modo:

# Parent of HEAD
git show HEAD^1

# Grandparent
git show HEAD^2

Esistono molti modi per specificare i commit:

# Great grandparent
git show HEAD~3

Vedi questa pagina per i dettagli .


2
HEAD ^ 2 non è il nonno, se HEAD ^ 1 è papà, HEAD ^ 2 è mamma. Usa HEAD ~ 2 per il papà di papà.
Binarian,

11

Come sottolinea @mipadi, puoi usare git show $COMMIT, ma questo mostra anche alcune intestazioni e il messaggio di commit. Se vuoi una differenza diretta, usa git show --pretty=format:%b $COMMIT.

Questa, ovviamente, non è una mano molto breve, quindi tengo questo alias nel mio .gitconfig

    [alias]
      sd = show --pretty=format:%b

Questo mi permette di usare git sd $COMMITper mostrare diff .


1
Questo alias può includere --color che semplifica la lettura: sd = show --color --pretty = format:% b
RichVel

@RichVel Indeed! Ottimo punto Se hai i colori abilitati di default in git, non avrai bisogno di questo interruttore. Questo è quello che faccio normalmente.
Øystein Steimler,

5

Molti degli esempi citati (ad es git diff 15dc8^!. O git diff 15dc8^..15dc8) non funzionano se si utilizza zsh e si ha extendedglobimpostato un'opzione. Puoi risolverlo in uno dei tre modi seguenti:

  1. unsetopt extendedglob (e / o rimuoverlo da .zshrc)

  2. setopt NO_NOMATCH (e / o impostarlo in .zshrc)

  3. sfuggire al cursore e battere ogni volta con una barra rovesciata, ad es git diff 15dc8\^\!



2

La soluzione di Paul sopra ha fatto quello che speravo potesse fare.

$ git diff HEAD^1

Inoltre, è utile aggiungere alias come i piani di cottura menzionati, se inserisci quanto segue nella sezione [alias] del tuo file ~ / .gitconfig, puoi usare la scorciatoia per visualizzare diff tra head e precedente.

[alias]
    diff-last = diff HEAD^1

Quindi eseguendo $ git diff-last otterrai il tuo risultato. Tieni presente che ciò includerà anche tutte le modifiche che non hai ancora eseguito, nonché la differenza tra commit. Se vuoi ignorare le modifiche che non hai ancora eseguito, puoi usare diff per confrontare direttamente HEAD con il suo genitore:

$ git diff HEAD^1 HEAD

0

Utilizza gli alias, quindi non risponde esattamente alla tua domanda, ma li trovo utili per fare ciò che intendi ...

alias gitdiff-1="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 2|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"
alias gitdiff-2="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 3|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"
alias gitdiff-3="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 4|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"

alias gitlog-1="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 2|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
alias gitlog-2="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 3|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
alias gitlog-3="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 4|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
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.