Comment différencier un commit avec son parent?

460

Mis à part l'écriture d'un alias ou d'un script, existe-t-il une commande plus courte pour obtenir le diff pour un commit particulier?

git diff 15dc8^..15dc8

Si vous ne donnez qu'un seul ID de validation git diff 15dc8, il diffère cette validation contre HEAD.

Brian L
la source
La chose la plus cool à ce sujet serait que cela fonctionnerait avec "git difftool", en utilisant les outils pour montrer le diff.
orip
Pour référence, la réponse à cette autre question illustre comment vous pouvez configurer un alias alimenté par bash pour simplifier ce qui précède: stackoverflow.com/questions/3321492/…
Nick

Réponses:

641

Utilisez git show $COMMIT. Il vous montrera le message du journal de la validation et la différence de cette validation particulière.

mipadi
la source
45
Dommage qu'il ne puisse pas utiliser difftool :(
orip
1
@orip vous pouvez toujours définir GIT_EXTERNAL_DIFF sur un script qui fait la même chose que votre difftool.
slacy
7
Je préfère la réponse de JakubNarebski, car l'expression de validation qui y est donnée fonctionnera dans de nombreux contextes: stackoverflow.com/a/449128/992887
RichVel
1
S'il n'y a pas de différence affichée, il n'y a probablement pas de changements réels, comme pour un commit de fusion
Devin G Rhode
6
@PTWithy: La question était: "Existe-t-il une commande plus courte pour obtenir le diff pour un commit particulier?", À laquelle cette question répond.
mipadi
439

Utilisation:

git diff 15dc8^!

comme décrit dans le fragment de page de manuel git-rev-parse (1) suivant (ou dans la page de manuel git gitrevisions (7) moderne ):

Il existe deux autres raccourcis pour nommer un ensemble formé par une validation et ses validations parentes. La notation r1 ^ @ signifie tous les parents de r1. r1 ^! inclut commit r1 mais exclut tous ses parents.

Cela signifie que vous pouvez utiliser 15dc8^!comme raccourci pour 15dc8^..15dc8n'importe où dans git où des révisions sont nécessaires. Pour la commande diff, la git diff 15dc8^..15dc8est comprise comme git diff 15dc8^ 15dc8, ce qui signifie la différence entre le parent de commit ( 15dc8^) et commit ( 15dc8).

Remarque : la description dans la git-rev-parse(1)page de manuel parle des plages de révision , où elle doit également fonctionner pour les validations de fusion, avec plus d'un parent. Ensuite r1^!est « r1 --not r1^@» ie « r1 ^r1^1 ^r1^2 ...»


En outre, vous pouvez utiliser git show COMMITpour obtenir la description du commit et le diff pour un commit. Si vous ne voulez que diff, vous pouvez utilisergit diff-tree -p COMMIT

Jakub Narębski
la source
7
Cela devrait être la réponse acceptée, c'est beaucoup plus net. Cependant, la dernière phrase de l'extrait git-rev-parse est assez déroutante - semble vouloir dire «va du parent de ce commit à ce commit».
RichVel
1
@RichVel: c'est un peu déroutant car il essaie de décrire également la situation où commit a plus d'un parent (est un commit de fusion). r1 ^! fonctionne comme prévu également alors.
Jakub Narębski
@ JakubNarębski: bon point, peut-être pourriez-vous modifier votre réponse pour résumer votre compréhension des cas monoparentaux et multiparentaux - des déclarations séparées sur chaque cas pourraient être plus faciles à comprendre.
RichVel
1
@ JakubNarębski: oui, beaucoup mieux! J'utilise maintenant ce raccourci tout le temps - merci.
RichVel
1
La ^!notation abrégée parent fonctionne correctement avec difftool pour les validations normales, mais la différence est inversée pour les validations de fusion. Pourquoi
hIpPy
56

Si vous savez à quelle distance, vous pouvez essayer quelque chose comme:

# Current branch vs. parent
git diff HEAD^ HEAD

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

Les validations antérieures fonctionnent comme ceci:

# Parent of HEAD
git show HEAD^1

# Grandparent
git show HEAD^2

Il existe de nombreuses façons de spécifier des validations:

# Great grandparent
git show HEAD~3

Voir cette page pour plus de détails .

Paul Vincent Craven
la source
2
HEAD ^ 2 n'est pas le grand-parent, si HEAD ^ 1 est papa, alors HEAD ^ 2 est maman. Utilisez HEAD ~ 2 pour le papa de papa.
Binarian
11

Comme le souligne @mipadi, vous pouvez l'utiliser git show $COMMIT, mais cela montre également certains en-têtes et le message de validation. Si vous voulez un diff droit, utilisez git show --pretty=format:%b $COMMIT.

Ce n'est évidemment pas une main très courte, donc je garde cet alias dans mon .gitconfig

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

Cela me permet d'utiliser git sd $COMMITpour afficher diff .

Øystein Steimler
la source
1
Cet alias peut inclure --color qui facilite la lecture: sd = show --color --pretty = format:% b
RichVel
@RichVel Effectivement! Très bon point. Si vous avez activé les couleurs par défaut dans git, vous n'aurez cependant pas besoin de ce commutateur. C'est ce que je fais normalement.
Øystein Steimler
5

La plupart des exemples mentionnés (par exemple git diff 15dc8^!, ou git diff 15dc8^..15dc8) ne fonctionnent pas si vous utilisez zsh et que l' extendedgloboption est définie. Vous pouvez le corriger de l'une des trois manières suivantes:

  1. unsetopt extendedglob (et / ou supprimez-le de .zshrc)

  2. setopt NO_NOMATCH (et / ou définissez-le dans .zshrc)

  3. échapper au curseur et frapper à chaque fois avec une barre oblique inverse, par exemple git diff 15dc8\^\!

Ville
la source
3
git diff 15dc8 15dce~1

~ 1 signifie «parent», ~ 2 «grand-parent, etc.

John Lawrence Aspden
la source
2

La solution de Paul ci-dessus a fait ce que j'espérais.

$ git diff HEAD^1

En outre, il est utile d'ajouter des alias comme les tables de cuisson mentionnées, si vous mettez ce qui suit dans la section [alias] de votre fichier ~ / .gitconfig, vous pouvez utiliser une raccourci pour afficher les différences entre la tête et la précédente.

[alias]
    diff-last = diff HEAD^1

Ensuite, exécuter $ git diff-last vous donnera votre résultat. Notez que cela aussi inclure les modifications que vous ne l' avez pas encore engagés, ainsi que la diff entre commits. Si vous souhaitez ignorer les modifications que vous n'avez pas encore validées, vous pouvez utiliser diff pour comparer directement le HEAD avec son parent:

$ git diff HEAD^1 HEAD
Graham R. Armstrong
la source
0

Utilise des alias, donc ne répond pas exactement à votre question mais je les trouve utiles pour faire ce que vous avez l'intention ...

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"
plaques de cuisson
la source