Comment vérifier le vrai diff git avant de fusionner de la branche distante?

Je veux vérifier le vrai diff entre la branche distante et la branche locale. Comment puis-je le faire?

L'émission de la commande ci-dessous fonctionne partiellement, mais elle montre aussi le diff des nouveaux changements de ma branche locale.

git diff remote/branch
44
demandé sur abhiomkar 2011-02-09 14:42:59

3 réponses

De la documentation :

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

Ce formulaire permet d'afficher les modifications sur la branche contenant et jusqu'à la deuxième <commit>, à partir d'un commun ancêtre des deux <commit>. "git diff A...B" est équivalent à "git diff $(git-fusion-base A B) B". Vous pouvez omettre n'importe lequel de <commit>, qui a le même effet que D'utiliser HEAD à la place.

Avez-vous essayé?

13
répondu Evgen Bodunov 2012-10-26 01:17:14

Comme ce sujet revient fréquemment, et peut être déroutant sans un peu d'arrière-plan sur le fonctionnement de git, j'ai pensé essayer d'expliquer le cas le plus simple possible, mais avec une profondeur suffisante pour que les nouveaux arrivants aient assez de connaissances pour faire des recherches supplémentaires.

Si vous configurez votre dépôt git via un 'clone' normal et que vous avez les refspecs par défaut, ce qui signifie que votre télécommande est nommée 'origin' et que vous tirez / récupérez de la branche 'master' , vous devrez parfois voir ce qui est dans le référentiel distant avant de le tirer vers le bas.

Puisque le "git pull" effectue une fusion automatique (sauf s'il y a des conflits), il peut être agréable de voir ce qui est "entrant" ensuite. Si vous n'êtes pas familier avec le fonctionnement de git, et comment les refspecs en particulier sont gérés, cela peut être un peu non intuitif.

Supposons que quelqu'un effectue un changement dans le référentiel distant (par exemple, en ajoutant une ligne au référentiel distant en validant un changement et en le poussant), et vous tapez:

$ git diff origin/master

Vous ne verrez probablement aucun changement; cependant, si vous faites ce qui suit:

$ git fetch; git diff ..origin/master 

Vous verrez la différence entre ce qui a été validé dans votre référentiel Git local et ce qui se trouve dans le référentiel distant. Vous ne verrez aucun changement dans votre système de fichiers local ou mis en scène dans votre index.

Ok, pourquoi on fait ça? origin / master est un refspec (voir les pages de manuel). En bref, c'est ce à quoi nous nous référons pour comparer contre, tirer ou chercher de, et pousser à. Tous les éléments suivants sont fonctionnellement équivalents:

origin/master
remotes/origin/master
refs/remotes/origin/master

Pour commencer à démêler cela, jetez un coup d'œil à celui de votre dépôt .structure de répertoire git. Une mise en page typique ressemble à ceci:

.git/refs
.git/refs/heads
.git/refs/heads/master
.git/refs/remotes
.git/refs/remotes/origin
.git/refs/remotes/origin/HEAD
.git/refs/remotes/origin/master
.git/refs/tags

Regarde .git / refs / remotes / origin / HEAD; dans le cas par défaut, il pointera vers la branche que vous utilisez pour tirer et pousser vers. Dans mon cas, puisque je suis sur master, le contenu de ce fichier texte ressemble à ceci:

ref: refs/remotes/origin/master

Cela me dit que le chef de ma télécommande est identifiée par le refspec 'refs / remotes / origin / master'(qui a les alias mentionnés ci-dessus).

Cela ne nous dit pas grand-chose; Quel est l'état du référentiel distant? Regardez l'état du maître distant:

$ cat .git/refs/heads/master     
6d0fb0adfdfa5af861931bb06d34100b349f1d63

Ok, c'est un hachage SHA1; probablement un commit. Comment veut-on mettre dans ce fichier? Eh bien, chaque fois que vous faites un pull ou un fetch, ce fichier est mis à jour avec la validation la plus récente de la télécommande qui a été tirée ou récupérée. C'est ce qui explique pourquoi nous doivent git fetch avant d'effectuer le diff. Rappelez-vous, git fetch met à jour simplement votre copie locale d'une branche distante, mais ne la fusionne pas avec votre copie de travail. Il est complètement sûr. Un git fetch; git merge est équivalent à git pull.

Une fois que vous faites l'extraction, git pourra voir le commit le plus récent dans la télécommande dépôt au moment de l'extraction.

Vous pouvez utiliser différentes combinaisons de spécificateurs pour git pour voir vos diffs comme vous le souhaitez (les exemples suivants utilisent le travail local copier comme premier commit implicite):

$ git diff remote/origin   
This shows the incoming remote additions as deletions; any additions in your local 
repository are shown as additions.

$ git diff ...remote/origin
Shows incoming remote additions as additions; the triple-dot excludes changes
committed to your local repository.

$ git diff ..remote/origin
Shows incoming remote additions as additions; the double-dot includes changes
committed to your local repository as deletions (since they are not yet pushed).

Pour plus d'informations sur ".." vs "..."voir git help diff ainsi que l'excellente documentation à git-scm revision selection: commit ranges brièvement, pour les exemples ci-dessus, la syntaxe à double point montre tous les commits accessibles depuis origin/master mais pas votre copie de travail. De même, la syntaxe à trois points montre tous les commits accessibles depuis l'un ou l'autre commit (copie de travail implicite, remote/origin) mais pas depuis les deux.

Je passe par cette étape par étape parce que je suis assez nouveau à git et c'est exactement le genre de chose qui m'avait confus... Je suis sûr que les experts git peuvent trouver des défauts avec les détails... J'espère juste que cette réponse comble le fossé pour certaines personnes qui trouvent tous les différents messages un peu laconique.

107
répondu rholmes 2015-07-22 00:19:32

Ce que vous voulez faire est, comme suggéré par Evgen Bodunov:

git diff ...remote/branch

Cela differa les changements de remote / branch et ignorera les changements de votre HEAD actuel.

7
répondu Antoine Pelisse 2011-02-09 12:10:39