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?
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
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.