Conséquences de l'utilisation du greffon dans Mercurial

98

Récemment, plusieurs questions ont été posées sur l'omission des modifications lors de la maintenance des branches de version dans Mercurial. Par exemple:

Depuis son introduction en 2.0, je me suis demandé comment l'utiliser graftpour éviter ce problème. Étant donné un arbre de révision comme celui-ci:

A---B---C---D---E---F---G---H---I---J

Supposons que nous ayons besoin de créer une branche de publication qui ignore le changement Evil E.

hg update -r D
hg graft "F::J"

Nous donnant:

A---B---C---D---E---F---G---H---I---J
             \
              --F'--G'--H'--I'--J'
  • Q1: Que vient de se passer ici? Je peux comprendre que transplantcela aurait généré des correctifs à partir de F::J, puis les aurait appliqués D, mais grafton dit qu'il utilise la fusion à 3 voies plutôt que des correctifs. Alors ... comment ça marche? Pourquoi est-ce mieux?

Disons que je corrige maintenant Eet fusionne cela dans ma branche de publication.

                  --E2-----------------
                 /                     \
A---B---C---D---E---F---G---H---I---J---M1
             \                            \
              --F'--G'--H'--I'--J'---------M2--

M1 est une fusion directe; rien de spécial là-bas. M2 fusionne des branches qui ont "les mêmes" changements (ou au moins équivalents).

  • Q2: Cette fusion est-elle simplement une fusion à trois voies normale utilisant D, J'et M1?
  • Q3: Mercurial a-t-il stocké / utilisé des informations supplémentaires sur l'opération de greffe pour l'aider dans la fusion?

Et enfin...

  • Q4: Quels sont les problèmes potentiels avec un flux comme celui-ci?
Paul S
la source

Réponses:

119

Lorsque vous effectuez une mise à jour Det une greffe F::J, Mercurial exécute un certain nombre de fusions. Cela commencera par cette fusion:

M = three_way_merge(local=D, other=F, base=E)

Si nous écrivons +dpour le delta entre les états Cet D, alors nous commençons par:

        +d     +e     +f
---- C ---- D ---- E ---- F ----

Tournez le graphique de 90 degrés dans le sens des aiguilles d'une montre et la fusion à trois voies ci-dessus ressemble à ceci:

    -e  
  .---- D
 /
E
 \
  '---- F
    +f

Autrement dit, nous prétendons que nous avons commencé avec Eet appliqué le contraire de -epour arriver à D. Je pense que c'est le patch inverse de +e. À partir de Enous, nous sommes également passés à l'état Favec le delta normal +f. Il n'y a rien d' étrange - nous avons tous les états ( D, Eet F) dans le référentiel déjà. Alors vu comme ça, il est clair que nous pouvons fusionner Det F.

La fusion est une question de «compléter le diamant». Nous trouvons donc un nouvel état Mqui est un mélange de Det Fet où la différence de Dà Mest similaire à +fet la différence de Fà Mest similaire à -e. Cela ressemble à ceci:

    -e     +f'
  .---- D ----.
 /             \
E               M
 \             /
  '---- F ----'
    +f     -e'

Le +fdelta est devenu +f'et le -edelta est devenu -e'. C'est juste une fusion à trois voies normale, mais l'effet est intéressant: nous avons appliqué Fsur Dau lieu de E!

Après la fusion, le deuxième parent de Mto Fest supprimé:

    -e     +f'
  .---- D ----.
 /             \
E               M
 \
  '---- F
    +f

Pour réitérer: nous avons copié l '«effet» de Fsur D, c'est-à-dire que nous avons trouvé un delta ( +f') qui s'appliquait pour Ddonner le même effet que lorsque +fétait appliqué à E. Nous pouvons redresser un peu le graphique pour obtenir:

       +f'
--- D ---- M
     \
      '---- E ---- F
        +e     +f

Le résultat est qu'il Fest greffé sur l' Dutilisation de la machine à trois voies complète.

  • Q1: Que vient de se passer ici? Alors ... comment ça marche? Pourquoi est-ce mieux?

    A1: L' utilisation des fusions est meilleure que des correctifs car la machine de fusion prend en compte des éléments tels que les renommages.

  • Q2: Cette fusion est-elle juste une fusion à 3 voies normale utilisant D, J 'et M1?

    A2: Oui, la greffe ne modifie pas la topologie du graphe.

  • Q3: Mercurial a-t-il stocké / utilisé des informations supplémentaires sur l'opération de greffe pour l'aider dans la fusion?

    A3: Non.

  • Q4: Quels sont les problèmes potentiels avec un flux comme celui-ci?

    R4: Du point de vue de la fusion, cela devrait fonctionner correctement. Cela reproduira une histoire qui pourrait être déroutante pour les gens.

Martin Geisler
la source
4
Excellente question, excellente réponse :). +1 aux deux!
Laurens Holst
Merci Martin. C'est une réflexion assez funky de la part de celui qui a proposé cela. J'ai l'idée, mais j'ai besoin de travailler sur le cas général. J'imagine que cela tient quel que soit le chemin entre les nœuds vers / depuis lesquels vous greffez?
Paul S
3
@PaulS: Je pense que tout ce que vous devez savoir, c'est que la greffe peut copier des ensembles de modifications d'une manière plus robuste que la greffe. Robuste dans le sens où les renommés sont gérés et que vous pouvez résoudre les conflits dans un outil de fusion. Les détails sont dans les étranges fusions qu'il fait, mais ce n'est, espérons-le, pas essentiel à comprendre pour une utilisation quotidienne de la greffe! :-)
Martin Geisler
3
Non, mais j'aime essayer de comprendre des choses dont je n'ai pas besoin ;-) J'ai travaillé sur un exemple plus général en utilisant le vôtre comme base de toute façon.
Paul S
@PaulS Si c'est le cas, j'ai presque peur de vous en parler ... mais vous pouvez consulter Darcs et sa théorie des correctifs. L'astuce ci-dessus concernant la rotation du graphique de 90 degrés me rappelle beaucoup comment ils parlent de permutation des patchs lors de la fusion. Trucs assez poilus :-)
Martin Geisler
6

Q1: Cela aide quand il y a des conflits. Vous pouvez alors utiliser votre outil de fusion habituel (pour moi, ce sont des marqueurs de conflit en ligne, que j'édite avec le mode smerge d'Emacs).

Q2: C'est une fusion normale.

Q3: Non.

Q4: Je pense que c'est moche d'avoir deux branches presque identiques.

Sonnerie
la source