web-dev-qa-db-fra.com

Numéro de parent principal lorsque la fusion de sélection de cerises est validée

Supposons que ce soit mon histoire

 Z 
 /[.______________ A - C - D 
 \/
 B 

Mon HEAD est actuellement à Z. Je veux sélectionner B et C. Si ma compréhension est correcte, je devrais faire cette:

git cherry-pick B
git cherry-pick C -m 1
git commit --allow-empty

Cela a fonctionné dans mon cas parce que C est un no-op (d'où le commit vide par la suite, j'ai eu besoin du commit pour d'autres raisons), mais je me demande quel est le paramètre après -m Est-ce que. Voici ce que j'ai lu de les docs :

- m numéro-parent

- numéro de parent principal

Habituellement, vous ne pouvez pas choisir une fusion car vous ne savez pas quel côté de la fusion doit être considéré comme la ligne principale. Cette option spécifie le numéro du parent (à partir de 1) de la ligne principale et permet à cherry-pick de rejouer la modification par rapport au parent spécifié.

Dans mon cas, C a deux parents, mais comment savoir lequel est 1 et 2, et plus important encore, quand est-ce important quand je choisis 1 ou 2?

18
rink.attendant.6

Ma compréhension basée sur cette réponse est que le parent 1 est la branche en cours de fusion et le parent 2 est la branche en cours de fusion. Dans votre cas, le parent 1 est A et le parent 2 est B. Puisqu'une cerise sur le gâteau applique vraiment la différence entre deux commits, vous utilisez -m 1 pour appliquer uniquement les modifications de B (car le diff entre A et C contient les modifications de B). Dans votre cas, cela n'a probablement pas d'importance, car vous n'avez aucun commit entre A et C.

Donc oui, -m 1 est ce que vous voulez, et cela est vrai même s'il y avait des commits supplémentaires entre A et C.

Si vous souhaitez que la nouvelle histoire ressemble un peu plus à l'histoire d'origine, il existe une autre façon de procéder:

git cherry-pick B
git checkout Z
git merge --no-ff --no-commit B
git commit --author="Some Dev <[email protected]>" --date="<commit C author date>"

(Si nécessaire, vous pouvez créer une nouvelle branche pour B avant la sélection.)

Cela conservera les informations sur l'auteur, devrait vous donner un historique qui ressemble à ceci:

    B'
   /  \
  Z -- C'
 /
A -- C -- D
 \  /      
  B
23
Scott Weldon

J'ai voté positivement réponse de Scott Weldon , ce qui est correct, mais je veux juste ajouter une tentative de ASCII art qui inclut la numérotation des parents. Étant donné un graphique qui ressemble à cette:

       B
      / \
...--A   D--...
      \ /
       C

nous pouvons dire que le nœud D est un commit de fusion, mais nous ne pouvons pas dire si B ou C est le premier parent de D. L'un des deux est nécessairement le premier parent et l'autre est le second. Donc, si nous devons savoir, nous devons étiqueter le dessin, ce qui prend plus de place. Voici une telle tentative.

         B
       /   \²
...--A       D--...
       \   /¹
         C

Nous voyons maintenant que, pour une raison quelconque,1 J'ai dessiné le graphique "à l'envers": cette commit C est en fait le premier parent de D, tandis que commit B est le deuxième parent.

Il est possible de créer des fusions arbitraires en utilisant des commandes de niveau inférieur ("plomberie"). En particulier, git commit-tree Prend juste le nombre d'arguments -p Que vous souhaitez lui donner, dans l'ordre que vous lui donnez, et fait un nouveau commit avec les commits donnés comme parents. Donnez-lui un -p Et il fera un commit ordinaire avec un parent. Ne lui donnez pas d'arguments -p Et il fera un commit root. Donnez-lui 155 arguments -p Distincts (tous doivent bien sûr se résoudre à des ID de validation valides) et il effectue un commit de fusion de poulpe massif.

La commande git merge, Cependant, effectue toujours son nouveau commit avec le premier parent étant le HEAD actuel (d'où la branche courante, si sur une branche). Le deuxième parent, pour une fusion à deux parents standard, provient de .git/MERGE_HEAD, Dans lequel git merge Écrit l'autre ID de validation. Si la fusion est en conflit ou si la validation finale de la fusion est retardée avec --no-commit, Ce fichier MERGE_HEAD Est en fait le uniquement place que l'ID de validation est disponible.

(Lorsque git merge Effectue une fusion de poulpe, en utilisant la stratégie -s octopus - cette stratégie est forcée pour de telles fusions - et plusieurs parents supplémentaires, elle abandonne et ne laisse aucune trace en cas de conflits de fusion , donc le cas de conflit ne se produit jamais. Je n'ai pas essayé de combiner --no-commit avec une fusion de poulpe, mais cela laisserait logiquement les parents du 2ème au N'th dans MERGE_HEAD, si Git le permet du tout.)


1Obstination.

2
torek