Comment différencier un fichier en une version arbitraire dans Git?

324

Comment puis-je différencier un fichier, disons pom.xml, de la branche principale vers une ancienne version arbitraire dans Git?

Chris K
la source

Réponses:

347

Tu peux faire:

git diff master~20:pom.xml pom.xml

... pour comparer votre courant pom.xmlà celui d'il y a master20 révisions par le premier parent. Vous pouvez master~20, bien sûr, remplacer le nom d'objet (SHA1sum) d'une validation ou l'une des nombreuses autres façons de spécifier une révision .

Notez qu'il s'agit en fait de comparer l'ancienne pom.xmlà la version de votre arborescence de travail, et non la version validée dans master. Si vous le souhaitez, vous pouvez effectuer les opérations suivantes à la place:

git diff master~20:pom.xml master:pom.xml
Mark Longair
la source
12
Notez que cela ne fonctionne pas uniquement pour les fichiers, il fonctionne également pour les (sous-) répertoires, par exemple git diff <revision>:foo/ HEAD:foo/.
2
Notez également que sur les fenêtres, vous devez utiliser des barres obliques pour les répertoires si vous utilisez un spécificateur de révision ou git vous donnera une erreur sur le fichier / répertoire qui n'existe pas dans cette révision.
Dylan Nissley
1
@DylanNissley ou il ne vous donnera aucune erreur et aucun diff. C'est ce que je vois. Dans tous les cas, merci pour l'indication sur l'utilisation des barres obliques au lieu des barres obliques inverses.
Gary S.
Avec les fichiers Windows, j'ai trouvé plus facile de changer de répertoire, puis d'appeler git diff master ~ 20: ./ pom.xml ./pom.xml
lloyd
Certaines versions de git nécessitent "-" entre le <revision> & <path>
Josh
140
git diff <revision> <path>

Par exemple:

git diff b0d14a4 foobar.txt
Benjamin Pollack
la source
ne fonctionne pas pour la version 1.7.11 si le fichier ne se trouve pas dans le répertoire courant. Exemple: 'git diff f76d078 test / Config' renvoie "erreur: Impossible d'accéder à 'test / f76d078'"
simpleuser
1
@ user1663987 passer juste un chemin complet par rapport à la racine du projet: git diff <revision> root/path/file.
1
test / Config est relatif à la racine (comme dans test est un sous-répertoire de la racine). mais alors votre exemple racine / chemin / fichier semble INCLURE la racine?
simpleuser
41

Si vous voulez voir la différence entre le dernier commit d'un seul fichier, vous pouvez le faire:

git log -p -1 filename

Cela vous donnera la différence du fichier dans git, ne compare pas votre fichier local.

Gerardo
la source
2
cela ne retourne rien
Andrei Cristian Prodan
@AndreiCristianProdan Ensuite, vous n'avez aucun changement. Vous pouvez incrémenter l' -1étape par étape jusqu'à ce que vous obteniez les modifications.
kaiser du
C'est très gentil. J'ai créé une fonction bash qui pourrait être utile: gitlog () { git log -${3:-p} -${2:-1} $1; } utilisée comme: gitlog Rakefileou gitlog Rakefile 5et gitlog Rakefile 10 s. Le premier montre un diff; le second montre cinq diffs; le troisième en montre dix --no-patch.
auxbuss
18

Pour voir ce qui a été changé dans un fichier lors du dernier commit:

git diff HEAD~1 path/to/file.

Vous pouvez changer le nombre (~ 1) au n-ème commit avec lequel vous souhaitez faire la différence.

Juampy NR
la source
Cette réponse n'est vraiment qu'un cas spécifique de cette réponse plus générale , où HEAD~1est substitué <revision>, ce qui fait de cette réponse un doublon.
1
cela ne fonctionne pas! fatal: argument ambigu 'HEAD ~ 1': révision inconnue ou chemin d'accès absent de l'arborescence de travail. Utilisez '-' pour séparer les chemins des révisions
Andrei Cristian Prodan
Cette réponse est simple et fonctionnelle pour moi.
Douglas Frari
6

Syntaxe générique:

$git diff oldCommit..newCommit -- **FileName.xml > ~/diff.txt

pour tous les fichiers nommés "FileName.xml" n'importe où dans votre référentiel.

Notez l'espace entre "-" et "**"

Répondez à votre question:

$git checkout master
$git diff oldCommit..HEAD -- **pom.xml 
or
$git diff oldCommit..HEAD -- relative/path/to/pom.xml 

comme toujours avec git, vous pouvez utiliser une balise / sha1 / "HEAD ^" pour identifier un commit.

Testé avec git 1.9.1 sur Ubuntu.

sonslikeodd
la source
6

Si aucun commit n'est votre HEAD, l' expansion de l'accolade de bash s'avère vraiment utile, surtout si vos noms de fichiers sont longs, l'exemple ci-dessus:

git diff master~20:pom.xml master:pom.xml

Deviendrait

git diff {master~20,master}:pom.xml

En savoir plus sur l' expansion de Brace avec bash.

robstarbuck
la source
6

Pour comparer à 5, validez avec l'actuel, les deux activés master, faites simplement:

git diff master~5:pom.xml master:pom.xml

Vous pouvez également vous référer au numéro de hachage de validation, par exemple si le numéro de hachage est x110bd64, vous pouvez faire quelque chose comme ça pour voir la différence:

git diff x110bd64 pom.xml
Alireza
la source
4

git diff -w HEAD origin / master path / to / file

CatalinBerta
la source
2
git diff master~20 -- pom.xml

Fonctionne si vous n'êtes pas trop dans la branche principale.

Gunar Gessner
la source
2

Si vous êtes d'accord avec un outil graphique (ou même le préférez), vous pouvez:

gitk pom.xml

Dans gitk, vous pouvez ensuite cliquer sur n'importe quel commit (pour le "sélectionner") et cliquer avec le bouton droit sur n'importe quel autre commit pour sélectionner "Diff this -> selected" ou "Diff selected -> this" dans le menu contextuel, selon l'ordre que vous préférez.

Martin G
la source
0

Si vous avez besoin de diff sur un seul fichier dans une cachette par exemple, vous pouvez le faire

git diff stash@{0} -- path/to/file
lacostenycoder
la source
-1

Si vous recherchez le diff sur un commit spécifique et que vous souhaitez utiliser l'interface utilisateur de github au lieu de la ligne de commande (par exemple, vous voulez le lier à d'autres personnes), vous pouvez faire:

https://github.com/<org>/<repo>/commit/<commit-sha>/<path-to-file>

Par exemple:

https://github.com/grails/grails-core/commit/02942c5b4d832b856fbc04c186f1d02416895a7e/grails-test-suite-uber/build.gradle

Notez les liens Précédent et Suivant en haut à droite qui vous permettent de parcourir tous les fichiers du commit.

Cela ne fonctionne que pour un commit spécifique, pas pour comparer entre deux versions arbitraires.

Schmick
la source