Consecuencias de usar injerto en Mercurial

98

Recientemente, ha habido varias preguntas sobre cómo omitir cambios al mantener las ramas de lanzamiento en Mercurial. Por ejemplo:

Desde que se introdujo en 2.0, me he preguntado cómo usarlo graftpara evitar este problema. Dado un árbol de revisión como este:

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

Supongamos que necesitamos crear una rama de lanzamiento que omita el cambio Evil E.

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

dándonos:

A---B---C---D---E---F---G---H---I---J
             \
              --F'--G'--H'--I'--J'
  • P1: ¿Qué acaba de pasar aquí? Puedo entender que transplanthubiera generado parches F::Jy luego los hubiera aplicado D, pero graftse dice que usa la combinación de 3 vías en lugar de parches. Entonces ... ¿cómo funciona eso? ¿Por qué es mejor?

Digamos que ahora lo arreglo Ey lo fusiono en mi rama de lanzamiento.

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

M1 es una combinación directa; nada especial allí. M2 está fusionando ramas que tienen "los mismos" cambios (o al menos equivalentes).

  • P2: ¿Es esta fusión sólo una combinación normal de 3 vías usando D, J'y M1?
  • P3: ¿Mercurial ha almacenado / utilizado información adicional sobre la operación de injerto para ayudarlo con la fusión?

Y finalmente...

  • P4: ¿Cuáles son los problemas potenciales con un flujo como este?
Paul S
fuente

Respuestas:

119

Cuando se actualiza De injerta F::J, Mercurial ejecuta una serie de fusiones. Comenzará con esta fusión:

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

Si escribimos +dpara el delta entre los estados Cy D, entonces comenzamos con:

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

Gire el gráfico 90 grados en el sentido de las agujas del reloj y la combinación de tres direcciones anterior se verá así:

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

Es decir, pretendemos que empezamos con Ey aplicamos lo contrario de -epara llegar a D. Pienso en el parche inverso de +e. Comenzando en Etambién fuimos al estado Fcon el delta normal +f. No hay nada extraño aquí - tenemos todos los estados ( D, Ey F) en el repositorio ya. Visto así, está claro que podemos fusionar Dy F.

La fusión es una cuestión de "completar el diamante". Entonces encontramos un nuevo estado Mque es una mezcla de Dy Fy donde la diferencia de Da Mes similar a +fy la diferencia de Fa Mes similar a -e. Se parece a esto:

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

El +fdelta se convirtió en +f'y el -edelta se convirtió en -e'. Esta es solo una combinación normal de tres vías, pero el efecto es interesante: ¡lo hemos aplicado Fen Dlugar de E!

Después de la fusión, se elimina el segundo padre de Mto F:

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

Para reiterar: hemos copiado el "efecto" de Fsobre D, es decir, hemos encontrado un delta ( +f') que se aplicó para Ddar el mismo efecto que cuando +fse aplicó a E. Podemos enderezar un poco el gráfico para obtener:

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

El resultado es que Fse injerta Dutilizando la maquinaria completa de tres vías.

  • P1: ¿Qué acaba de pasar aquí? Entonces ... ¿cómo funciona eso? ¿Por qué es mejor?

    R1: Usar fusiones es mejor que parches, ya que la maquinaria de fusión tiene en cuenta cosas como los cambios de nombre.

  • P2: ¿Es esta fusión solo una fusión normal de 3 vías usando D, J 'y M1?

    A2: Sí, el injerto no altera la topología del gráfico.

  • P3: ¿Mercurial ha almacenado / utilizado información adicional sobre la operación de injerto para ayudarlo con la fusión?

    A3: No.

  • P4: ¿Cuáles son los problemas potenciales con un flujo como este?

    A4: Desde una perspectiva de fusión, debería funcionar bien. Duplicará algunos antecedentes que pueden resultar confusos para las personas.

Martin Geisler
fuente
4
Gran pregunta, gran respuesta :). +1 a ambos!
Laurens Holst
Gracias Martin. Ese es un pensamiento bastante extraño de quien se le ocurrió eso. Tengo la idea, pero necesito resolver el caso general. Supongo que se mantiene sin importar la ruta entre los nodos que está injertando.
Paul S
3
@PaulS: Creo que todo lo que necesitas saber es que el injerto puede copiar conjuntos de cambios de una manera más sólida que el trasplante. Robusto en el sentido de que se manejan los cambios de nombre y que puede resolver conflictos en una herramienta de combinación. Los detalles están en las extrañas fusiones que hace, ¡pero es de esperar que eso no sea esencial de entender para el uso diario de injerto! :-)
Martin Geisler
3
No, pero soy un tonto por tratar de entender cosas que no necesito ;-) Trabajé en un ejemplo más general usando el tuyo como base de todos modos.
Paul S
@PaulS Si es así, casi me da miedo mencionarle esto ... pero puede buscar Darcs y su teoría de parches. El truco anterior sobre rotar el gráfico 90 grados me recuerda mucho a cómo hablan sobre los parches de conmutación al fusionarse. Cosas bastante peludas :-)
Martin Geisler
6

P1: Ayuda cuando hay conflictos. Entonces puede usar su herramienta de fusión habitual (para mí son marcadores de conflicto en línea, que edito con el modo smerge de Emacs).

P2: Es una fusión normal.

Q3: No.

P4: Creo que es feo tener dos ramas casi idénticas.

Ringding
fuente