git: Comment faire la différence entre les fichiers modifiés et les versions précédentes après une extraction?

117

Quand j'exécute "git pull", je veux souvent savoir ce qui a changé entre la dernière version d'un fichier et la nouvelle. Disons que je veux savoir ce que quelqu'un d'autre a engagé dans un dossier particulier.

Comment cela se fait-il?

Je suppose que c'est "git diff" avec quelques paramètres pour commit x versus commit y mais je n'arrive pas à obtenir la syntaxe. Je trouve également "git log" un peu déroutant et je ne sais pas où trouver l'ID de validation de ma dernière version du fichier par rapport à la nouvelle.

doug
la source
1
Vous trouverez peut-être l'outil graphique gitk plus adapté à vos goûts.
crazyscot
stackoverflow.com/questions/61002/… pourrait être similaire à celui-ci
VonC

Réponses:

158

Il existe toutes sortes de façons merveilleuses de spécifier des commits - voir la section Spécification des révisions de man git-rev-parsepour plus de détails. Dans ce cas, vous souhaitez probablement:

git diff HEAD@{1}

Le @{1}signifie "la position précédente de la référence que j'ai spécifiée", ce qui évalue ce que vous aviez extrait précédemment - juste avant le pull. Vous pouvez clouer HEADà la fin si vous avez également des changements dans votre arbre de travail et que vous ne voulez pas voir les différences pour eux.

Je ne suis pas sûr de ce que vous demandez avec "l'ID de validation de ma dernière version du fichier" - l'ID de validation (hachage SHA1) est cet hexadécimal de 40 caractères situé juste en haut de chaque entrée dans la sortie de git log. C'est le hachage pour l'ensemble du commit, pas pour un fichier donné. Vous n’avez jamais vraiment besoin de plus - si vous voulez différencier un seul fichier à travers le pull, faites

git diff HEAD@{1} filename

C'est une chose générale - si vous voulez connaître l'état d'un fichier dans un commit donné, vous spécifiez le commit et le fichier, pas un ID / hachage spécifique au fichier.

Cascabel
la source
Le précédent post lié à VonC dit essentiellement la même chose que celui-ci, mais l'explication est un peu différente, je vais donc laisser cela pour le moment. (Il utilise également @{1}comme raccourci pour HEAD@{1})
Cascabel
vrai, mais j'aime aussi l'explication. +1
VonC
C'est exactement ce que je cherchais. Merci pour votre explication.
lucapette
+1 pour ce que je recherchais sur Google. Ce serait génial si cela était sélectionné comme réponse et poussé au sommet ... :)
longda
@longda Si vous triez par votes (ce que je pensais être par défaut), il devrait déjà être en haut.
Cascabel
57

J'aime utiliser:

git diff HEAD^

Ou si je veux seulement diffèrent un fichier spécifique:

git diff HEAD^ -- /foo/bar/baz.txt
cadizm
la source
5
-1: HEAD^est le commit parent, pas le commit avantpull
CharlesB
1
Si HEADest un commit de fusion, HEAD^est le premier commit parent, donc oui, ça peut être le commit avant le pull. Pour obtenir l'autre parent (pour une fusion bidirectionnelle), utilisez HEAD^2. Mais alors, la réponse ci-dessus ne répond pas vraiment à la question en premier lieu, alors laissant le -1 ;-)
Michael Wild
Merci pour la clarification. Je n'ai pas lu la question très attentivement, car je cherchais autre chose sur Google et ce lien est apparu en haut de la page de résultats. Je pensais que j'interviendrais puisque je suis un nouvel utilisateur et que je n'ai pas de karma (si c'est ce qu'on appelle SO). Ma faute =)
cadizm
3
@MichaelWild, ce n'est peut-être pas ce que le demandeur demandait, mais c'était ce que je cherchais quand j'ai trouvé ça. Cela m'a été utile. Vote positif.
John Dvorak
Celui-ci est ce que fait TortoiseGit "Diff avec la version précédente". Et c'est ce que je cherchais.
Fabien Haddadi
15

Si vous faites une suite, git pullvous serez soit en avance rapide, soit fusionnerez un nombre inconnu de validations du référentiel distant. Cela se produit comme une seule action, donc le dernier commit auquel vous étiez juste avant le pull sera la dernière entrée dans le reflog et sera accessible en tant que HEAD@{1}. Cela signifie que vous pouvez faire:

git diff HEAD@{1}

Cependant, je recommanderais fortement que si c'est quelque chose que vous faites beaucoup, vous devriez simplement envisager de faire un git fetchet d'examiner la branche récupérée avant de la fusionner ou de la rebaser manuellement. Par exemple, si vous êtes sur master et que vous allez extraire origin / master:

git fetch

git log HEAD..origin/master

 # looks good, lets merge

git merge origin/master
CB Bailey
la source
Belle utilisation de git logau lieu d' git diffici (même si la syntaxe est un peu incohérente entre le '..' pourgit log et le '...' pour git diff;) +1 Voir stackoverflow.com/questions/53569/... et stackoverflow.com/questions / 850607 /…
VonC
Heureusement si vous utilisez la syntaxe '..' dans une commande git diff, git "fait ce qu'il faut".
CB Bailey