Commits de fusion de liste affectant un fichier

Je veux trouver tous les commits de fusion qui affectent ou impliquent un fichier donné.

Pour l'arrière - plan, quelqu'un a mal résolu un conflit lors de la fusion, et il n'a pas été remarqué par l'équipe pendant quelques jours. À ce stade, beaucoup d'autres fusions non liées avaient été commises (certains d'entre nous préféraient ne pas utiliser rebase, ou les choses seraient plus simples). J'ai besoin de localiser le" mauvais " commit de fusion, afin qu'il puisse être vérifié pour identifier ce qui aurait pu être reverté (et, bien sûr, pour identifier et de punir les coupables).

, Le scénario est comme ceci:

$ echo First > a.txt && git add a.txt && git commit -m 'First commit'
$ git branch branch1
$ echo "Second: main-branch" >> a.txt && git commit -a -m 'Commit on master'
$ git tag a1
$ echo "Third: main" >> a.txt && git commit -a -m 'Other commit on master'
$ git checkout branch1
$ echo "Second: on branch1" >> a.txt && git commit -a -m 'Commit on branch'
$ git tag b1

... Alors maintenant, il y a des changements contradictoires à a.txt dans master et branch1.

$ git checkout master
$ git merge branch1 
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Automatic merge failed; fix conflicts and then commit the result.
$ cat a.txt 
First
<<<<<<< HEAD:a.txt
Second: main-branch
Third: main
=======
Second: on branch1
>>>>>>> branch1:a.txt
$ vi a.txt
# ...
$ cat a.txt 
First
Second: on branch1
$ git add a.txt
$ git commit -m 'Merge commit'

... en d'autres termes, la résolution est "Prenez la leur". Le graphique ressemble maintenant à ceci:

$ git log --graph --branches --format='%h %s %d' 
*   fefb623 Merge commit  (refs/heads/master)
|  
| * 93e065e Commit on branch  (refs/tags/b1, refs/heads/branch1)
* | cf4d12b Other commit on master 
* | 6fade67 Commit on master  (refs/tags/a1)
|/  
* 07545ea First commit 

À ce stade mauvaise version de a.txt est sur Maître. La version dans a1 est ce que nous voulons, mais la version b1 a été validée. Jusqu'à présent, j'ai essayé:

$ git log --decorate --oneline a.txt
93e065e (refs/tags/b1, refs/heads/branch1) Commit on branch
07545ea First commit

Ok, donc ni a1 ni le commit de fusion apparaître.

$ git log --decorate --oneline --follow a.txt
...

Cela me montre tout sur les deux branches, mais omet toujours les commits de fusion.

$ git log --oneline --graph --decorate a1..master
...

C'est bien sûr "tout en maître pas en a1", qui fonctionne dans cet exemple de jouet mais dans mon cas réel me donne toutes les fusions effectuées récemment (et aucune indication de laquelle on a touché a.txt).

Je peux rationaliser la disparition de a1 de l'historique du fichier, puisque la fusion a choisi d'omettre ce changement (au moins dans le sens où git se soucie, je pense). Mais comment faire Je localise tous les commits de fusion affectant a.txt? Est-ce même possible sans inspecter manuellement tous les commits de fusion candiate?

21
demandé sur Greg Fast 2012-04-16 23:57:04

2 réponses

Le problème dans votre cas est que les commits de fusion sont vides, car vous ne prenez des choses qu'à partir d'une branche, donc git simplifie l'historique en supprimant ces commits "vides".

Donc, pour que vos commits de fusion soient affichés dans le journal, vous devez dire à git de changer la simplification de l'historique, en disant --simplify-merges. Si vous voulez comprendre pourquoi vous devez utiliser ceci, allez-y dans la page de manuel git log, mais je n'en ai plus:) de toute façon, dans ce cas, le commit de fusion est correctement affiché avec a.txt filtrage, donc qu'est ce que vous voulez.

Enfin, vous voulez montrer diff deux fois, avec chaque parent, avec -m.

Donc cela donne

git log -U -m --simplify-merges --merges -- a.txt

Avec sortie

commit a7340d6e91deedff6f52c8ec8da932245f73e5f6 (from d577e6c4dcbff5485ded666c89f38
Merge: d577e6c fe3c4d2

    merge commit

diff --git a/a.txt b/a.txt
index 319137b..1aa6dc4 100644
--- a/a.txt
+++ b/a.txt
@@ -1,3 +1,2 @@
 First
-Second: main-branch
-Third: main
+Second: on branch1
22
répondu CharlesB 2012-04-16 21:24:22

Vous pouvez ajouter le --merges à la commande log. Cela ne listera que les commits de fusion. De plus, vous pouvez spécifier --first-parent afin de ne suivre que l'historique des branches et de ne pas considérer l'historique des branches fusionnées.

2
répondu Adam Dymitruk 2012-04-16 20:08:31