¿Cuándo utilizarías las diferentes estrategias de fusión de git?

430

Desde la página de manual de git-merge, hay una serie de estrategias de combinación que puede usar.

  • resolver : esto solo puede resolver dos cabezas (es decir, la rama actual y otra rama de la que extrajo) utilizando el algoritmo de combinación de 3 vías. Intenta detectar cuidadosamente las ambigüedades de fusión entrecruzadas y se considera generalmente seguro y rápido.

  • recursivo : esto solo puede resolver dos cabezas utilizando el algoritmo de fusión de 3 vías. Cuando hay más de un ancestro común que se puede usar para la fusión de 3 vías, crea un árbol fusionado de los ancestros comunes y lo utiliza como árbol de referencia para la fusión de 3 vías. Se ha informado que esto da como resultado menos conflictos de fusión sin causar fusiones erróneas mediante pruebas realizadas en confirmaciones de fusión reales tomadas del historial de desarrollo del kernel de Linux 2.6. Además, esto puede detectar y manejar fusiones que involucran cambios de nombre. Esta es la estrategia de fusión predeterminada al extraer o fusionar una rama.

  • pulpo : esto resuelve el caso de más de dos cabezas, pero se niega a hacer una fusión compleja que necesita resolución manual. Está destinado principalmente a usarse para agrupar cabezas de rama de tema juntas. Esta es la estrategia de fusión predeterminada al extraer o fusionar más de una rama.

  • la nuestra - Esto resuelve cualquier número de cabezas, pero el resultado de la fusión es siempre la cabeza de la rama actual. Está destinado a ser utilizado para reemplazar el antiguo historial de desarrollo de las ramas laterales.

  • subárbol : esta es una estrategia recursiva modificada. Al fusionar los árboles A y B, si B corresponde a un subárbol de A, B primero se ajusta para que coincida con la estructura de árbol de A, en lugar de leer los árboles al mismo nivel. Este ajuste también se realiza al árbol ancestro común.

¿Cuándo debo especificar algo diferente al predeterminado? ¿Para qué escenarios son los mejores?

Otto
fuente

Respuestas:

305

No estoy familiarizado con la resolución, pero he usado los otros:

Recursivo

Recursivo es el valor predeterminado para las fusiones sin avance rápido. Todos estamos familiarizados con eso.

Pulpo

Usé pulpo cuando tuve varios árboles que debían fusionarse. Ves esto en proyectos más grandes donde muchas sucursales han tenido un desarrollo independiente y todo está listo para unirse en una sola cabeza.

Una rama de pulpo combina varias cabezas en una confirmación siempre que pueda hacerlo limpiamente.

Por ejemplo, imagine que tiene un proyecto que tiene un maestro, y luego tres ramas para fusionar (llámelas a, byc).

Una serie de fusiones recursivas se vería así (tenga en cuenta que la primera fusión fue un avance rápido, ya que no forcé la recursividad):

serie de fusiones recursivas

Sin embargo, una sola combinación de pulpo se vería así:

commit ae632e99ba0ccd0e9e06d09e8647659220d043b9
Merge: f51262e... c9ce629... aa0f25d...

combinación de pulpo

La nuestra

Nuestro == Quiero atraer otra cabeza, pero descartar todos los cambios que introduce la cabeza.

Esto mantiene el historial de una rama sin ninguno de los efectos de la rama.

(Lea: ni siquiera se observan los cambios entre esas ramas. Las ramas se fusionan y no se hace nada en los archivos. Si desea fusionarse en la otra rama y cada vez que está la pregunta "nuestra versión del archivo o su versión "que puedes usar git merge -X ours)

Subárbol

Subtree es útil cuando desea fusionar en otro proyecto en un subdirectorio de su proyecto actual. Útil cuando tiene una biblioteca que no desea incluir como submódulo.

Dustin
fuente
1
Entonces, ¿la única ventaja real de Ocotopus es reducir el número de confirmaciones de fusión en el árbol?
Otto
6060
No necesita especificar la estrategia de combinación de pulpo : se usa automáticamente si combina más de dos ramas ( git merge A B ...).
Jakub Narębski
Perdón por salir del tema, pero ¿cuál es la herramienta de la que hiciste esas capturas de pantalla? Parece una visualización realmente genial / bonita de la historia de la sucursal ...
Bernd Haug
44
Gitg para aquellos en el entorno de Linux.
Akash Agrawal
2
Esta pista -X ourses increíble, me ahorró una hora de trabajo.
Michael
49

En realidad, las dos únicas estrategias que desearía elegir son las nuestras si desea abandonar los cambios generados por la rama, pero mantener la rama en el historial y el subárbol si está fusionando un proyecto independiente en el subdirectorio del superproyecto (como 'git-gui' en ' repositorio de git).

La combinación de pulpo se usa automáticamente cuando se fusionan más de dos ramas. la resolución está aquí principalmente por razones históricas y para cuando te golpean casos de esquina de estrategia de fusión recursiva .

Jakub Narębski
fuente
Tuve que elegir 'resolver' en lugar del 'recursivo' predeterminado para una fusión de dos cabezas que tenía errores fatales de git-write-tree. La estrategia 'Resolver' se fusionó limpiamente. Puede haber tenido que ver con mover muchos archivos en la rama que se está fusionando.
thaddeusmt
@thaddeusmt: Interesante. ¿Podría, si es posible, publicar un informe de error sobre esta falla de la estrategia de fusión "recursiva" en la lista de correo de git? Gracias por adelantado.
Jakub Narębski
@ JakubNarębski No estoy seguro de cómo reuniría suficiente información para presentar un informe de error significativo, soy un n00b con Git, lo siento. Como mencioné en mi respuesta aquí ( stackoverflow.com/a/10636464/164439 ), creo que tuvo que ver conmigo duplicando los cambios en ambas ramas, y "resolver" hace un mejor trabajo al omitir los cambios duplicados.
thaddeusmt
@ JakubNarębski ahora también puedes elegir el suyo , que está de acuerdo con el manual "el opuesto al nuestro . El suyo no se elige automáticamente para ti. Puede actualizar ligeramente tu respuesta, agregando la opción de ellos
SebNag
3
@SebTu: no hay una theirsestrategia de fusión (es decir --strategy=theirs), pero hay una theirsopción para la recursiveestrategia de fusión predeterminada (es decir --strategy=recursive --strategy-option=theirs, o simplemente -Xtheirs).
Jakub Narębski
23

Estrategia de fusión "Resolver" vs "Recursiva"

Recursivo es la estrategia de dos cabezas predeterminada actual, pero después de algunas búsquedas finalmente encontré información sobre la estrategia de fusión "resolver".

Tomado del libro O'Reilly Version Control con Git ( Amazon ) (parafraseado):

Originalmente, "resolver" era la estrategia predeterminada para las fusiones de Git.

En situaciones de fusión entrecruzadas, donde hay más de una base de fusión posible, la estrategia de resolución funciona así: elige una de las bases de fusión posibles y espera lo mejor. En realidad, esto no es tan malo como parece. A menudo resulta que los usuarios han estado trabajando en diferentes partes del código. En ese caso, Git detecta que está resurgiendo algunos cambios que ya están en su lugar y omite los cambios duplicados, evitando el conflicto. O, si se trata de cambios leves que causan conflictos, al menos el conflicto debería ser fácil de manejar para el desarrollador.

He fusionado exitosamente árboles usando "resolver" que falló con la estrategia recursiva predeterminada. Estaba recibiendo fatal: git write-tree failed to write a treeerrores, y gracias a esta publicación de blog ( espejo ) probé "-s resolve", que funcionó. Todavía no estoy exactamente seguro de por qué ... pero creo que fue porque tuve cambios duplicados en ambos árboles y resolví "omitirlos" correctamente.

thaddeusmt
fuente
Estoy usando la combinación de 3 vías (p4merge) y tuve conflictos escritos en el archivo .BASE cuando la fusión recursiva falló. Recurrir a la estrategia de resolución ayudó en este caso.
mrzl
-2

Como las respuestas anteriores no muestran todos los detalles de la estrategia. Por ejemplo, alguna respuesta le faltan los detalles acerca de la importación resolveopción y la recursiveque tiene muchas opciones secundarias como ours, theirs, patience, renormalize, etc.

Por lo tanto, recomendaría visitar la gitdocumentación oficial que explica todas las características posibles:

https://git-scm.com/docs/merge-strategies

Rene B.
fuente