mercurial merge dvcs merge-conflict-resolution .hgtags

¿Cómo fusionar automáticamente.hgtags en Mercurial?



merge dvcs (5)

Deberías probar la diffmerge , ¡es increíble!

Tengo un script que ejecuta algunos comandos de Mercurial en modo no interactivo en un servidor de compilación. Uno de los comandos combina dos ramas y siempre hay un conflicto en el archivo .hgtags durante la fusión debido a la forma en que se configuran los scripts de construcción.

¿Cómo puedo obligar a Mercurial a fusionar siempre el archivo .hgtags utilizando los cambios de ambos archivos, primero de uno y luego del otro?

Por ejemplo, si los archivos a fusionar fueran

A B C

y

A B D

Me gustaría que el resultado fuera

A B C D

Supongo que necesitaré una herramienta de combinación personalizada. ¿Qué herramienta proporciona esta funcionalidad?


En realidad, no es necesario fusionar el archivo .hgtags. Puede ser diferente en diferentes ramas y Mercurial listará correctamente todas las etiquetas en todas las ramas.

Usamos la opción de configuración de merge-patterns para decirle a Mercurial que use la rama local cuando haga combinaciones de .hgtags. Agregue lo siguiente al archivo hgrc de su repositorio:

[merge-patterns] .hgtags = internal:local

Cuando se realiza una combinación que involucra el archivo .hgtags, .hgtags se mostrará como modificado, pero no se cambiará.


Mercurial 3.1 (2014-08-01) introdujo interno: tagmerge . Está marcado como experimental, así que ten cuidado. Aquí está el preámbulo del changeset de changeset (puede encontrar más detalles sobre el algoritmo si sigue el enlace):

Agregue una nueva herramienta de combinación interna: tagmerge que implementa un algoritmo de fusión automática para los archivos de etiquetas de mercurial

El algoritmo de etiquetado es capaz de resolver la mayoría de los conflictos de combinación que actualmente desencadenan un conflicto de combinación .hgtags. El único caso que no (y no puede) manejar es que dos etiquetas apuntan a diferentes revisiones en cada padre de combinación y sus historiales de etiquetas correspondientes tienen el mismo rango (es decir, la misma longitud). En todos los demás casos, el algoritmo de fusión elegirá la revisión que pertenece al padre con el historial de etiquetas mejor calificado. El historial de etiquetas fusionadas es la combinación de ambos historiales de etiquetas (se tiene especial cuidado para tratar de combinar los historiales de etiquetas comunes cuando sea posible).

El algoritmo también maneja casos en los que las etiquetas se han eliminado manualmente del archivo .hgtags y otros casos de esquina similares.

Además de fusionar realmente las etiquetas de dos padres, teniendo en cuenta la base, el algoritmo también intenta minimizar la diferencia entre el archivo de etiquetas fusionadas y el archivo de etiquetas del primer padre (es decir, trata de hacer que el orden de las etiquetas fusionadas sea tan similar como posible para el primer archivo de etiqueta de los padres).

tagmerge solo funciona con archivos de etiquetas, por lo que para usarlo deberías establecer patrones de combinación . Para hacer esto en base a cada comando use la opción --config :

hg merge -r REV --config merge-patterns..hgtags=internal:tagmerge

O para hacer esto en base a cada repositorio, agregue a su configuración de repos .hg/hgrc esto:

[merge-patterns] .hgtags=internal:tagmerge


Consulte la respuesta a continuación por Magras de La Mancha para una mejor solución con Mercurial 3.1. La siguiente es una solución más simple e ingenua para versiones anteriores de Mercurial.

Sí, debe configurar una herramienta de combinación personalizada para su archivo .hgtags . Mercurial no proporciona ninguna herramienta de combinación especial para .hgtags , se espera que la .hgtags manualmente utilizando su herramienta de combinación de tres vías normal.

Los conflictos en el archivo .hgtags pueden tener dos tipos:

  • Conflictos tontos: esta es la situación que tiene y realmente no hay conflicto aquí. Lo que pasa es que una rama tiene

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 12e0fdbc57a0be78f0e817fd1d170a3615cd35da C

    y la otra rama tiene

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 979c049974485125e1f9357f6bbe9c1b548a64c3 D

    Cada etiqueta se refiere exactamente a un conjunto de cambios, por lo que no hay conflicto aquí. La fusión debe ser, por supuesto, la unión de los dos archivos:

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 12e0fdbc57a0be78f0e817fd1d170a3615cd35da C 979c049974485125e1f9357f6bbe9c1b548a64c3 D

  • Conflictos reales: hay una rama que tiene

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 12e0fdbc57a0be78f0e817fd1d170a3615cd35da C

    y la otra rama tiene

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 979c049974485125e1f9357f6bbe9c1b548a64c3 C

    Aquí hay un conflicto real: la hg tag C se realizó en ambas ramas, pero las etiquetas se refieren a diferentes conjuntos de cambios. Resolver esto es una tarea manual.

Si puede garantizar que solo tendrá conflictos tontos y que solo tiene una etiqueta por conjunto de cambios, entonces puede usar

hg log -r "tagged()" --template "{node} {tags}/n" > .hgtags

para generar un nuevo archivo .hgtags . La idea clave es que Mercurial sabe cómo combinar etiquetas internamente. Hace esto todo el tiempo cuando tienes dos cabezas con diferentes archivos .hgtags . La plantilla anterior simplemente genera un nuevo archivo .hgtags basado en esta combinación interna.

Si puede tener más de una etiqueta por conjunto de cambios, entonces lo anterior no funcionará: todas las etiquetas se imprimen en una línea, por lo que obtiene una etiqueta foo bar lugar de dos etiquetas foo y bar . A continuación, puede utilizar este archivo de estilo en su lugar:

changeset = "{tags}" tag = "{node} {tag}/n"

Da salida a una línea por etiqueta , no a un conjunto de cambios. Guarda este estilo en algún lugar y configura una herramienta de combinación:

[merge-tools] hgtags.executable = hg hgtags.args = log -r "tagged()" --style ~/tmp/tags-style > $output hgtags.premerge = False hgtags.priority = -1000 [merge-patterns] .hgtags = hgtags

Ahora tiene combinaciones de etiquetas automáticas. Hay algunas advertencias:

  1. Tres o más cabezas: la técnica solo funciona si tiene dos cabezas en el momento de la fusión. Si tiene tres cabezas o más, es posible que una etiqueta eliminada vuelva a aparecer. Si tiene los encabezados X, Y y Z, y la etiqueta A se elimina en X, entonces Mercurial normalmente puede darse cuenta de que A se elimina en general. Esto se basa en una línea 000...0 A en el archivo .hgtags en X. Sin embargo, si .hgtags X e Y para obtener W, entonces el enfoque sugerido no contendrá ninguna línea 000...0 A La definición de A de Z ahora tendrá efecto repentinamente y reintroducirá A

  2. Conflictos reales: si tiene conflictos reales en .hgtags , entonces el método anterior elegirá silenciosamente la etiqueta de la cabecera más reciente para usted. La herramienta de combinación básicamente guarda las hg tags en .hgtags , y el comportamiento de las hg tags con varias cabezas se explica en la wiki . Dado que hg tags incondicionalmente lee y combina silenciosamente el archivo .hgtags de todas las cabezas, no hay nada que podamos hacer al respecto con este enfoque simple. Tratar con esto requeriría un script más grande que lea los dos archivos .hgtags y detecte el conflicto.


No puede resolver automáticamente los conflictos de combinación realizando una fusión desatendida. Sin la combinación (es decir, seleccionar "solo mi" o "solo otro") funcionará.

Me temo que tiene un flujo de trabajo mal planificado: el servidor de compilación no debe realizar ninguna acción que modifique las fuentes. Es tarea para la elección humana y humana.

Pero supongo que los datos exactos dentro de .hgtags tienen que ser valiosos para el servidor de compilación (usa su propio clon, no está poblado por nadie, ¡espero!), Por lo tanto, puede definir cualquier política de combinación en el comando y tener (mala, con datos). -loss) .hgtags fusionados

Por cierto, "primero de uno, luego de otro" en cualquier idioma, usando solo lógica formal, para pares

A B C

y

A B D

significa ABCABD resultado