2011-06-29 22 views
31

Tuve una cosa interesante que pasa con git, preguntándome si alguien podría explicarme para que pueda entender mejor.Git pulpo fusionar orden de múltiples ramas

Al hacer una fusión de múltiples ramas (A, B),

git merge A B 

falla que no avance rápido, mientras que

git merge B A 

funcionaba bien. ¿Por qué sería eso?

+0

¿Qué tipo de conflictos obtuvo? Creo que, en general, esto va a ser porque el cambio realizado por B hizo que A sea más fácil de fusionar, p. A intentó aplicar un parche a un archivo que no existe hasta que se renombró a ese nombre en B. – Cascabel

Respuesta

41

Supongamos que A es un estricto, direct child de la rama actual. Entonces suponga que B es un niño estricto, directo de A.

La combinación de pulpo, que processes heads given as arguments from left to right, forma incremental con respecto al árbol de, pero de forma independiente con respecto al índice de tiene éxito sin conflicto si se trata de aplicar B y luego A, pero se encuentra con un conflicto si lo hace la convertir.

según el manual git-merge, sección ESTRATEGIAS MERGE:

octopus 
    This resolves cases with more than two heads, but refuses to do a 
    complex merge that needs manual resolution. 

Por ejemplo:

~     $ git init testdir && cd testdir && echo "This is C" > myfile 
Initialized empty Git repository in /home/huitseeker/testdir/.git/ 

~/testdir   $ git add myfile && git commit -m "C" 
[master (root-commit) f0c8c82] C 
    1 files changed, 1 insertions(+), 0 deletions(-) 
    create mode 100644 myfile 

~/testdir(master) $ git checkout -b "A" && echo "This is A1" > myfile 
Switched to a new branch 'A' 
~/testdir(A)  $ git commit -m "A1" myfile 
[A ac5b51c] A1 
    1 files changed, 1 insertions(+), 1 deletions(-) 

~/testdir(A)  $ git checkout -b "B" && echo "This is B1" >> myfile 
Switched to a new branch 'B' 
~/testdir(B)  $ git commit -m "B1" myfile 
[B 5bc838c] B1 
    1 files changed, 1 insertions(+), 0 deletions(-) 

~/testdir(B)  $ git checkout master 
Switched to branch 'master' 
~/testdir(master) $ git merge B A 
Fast-forwarding to: B 
Already up-to-date with A 
Merge made by octopus. 
    myfile | 3 ++- 
    1 files changed, 2 insertions(+), 1 deletions(-) 

~/testdir(master) $ git reset --hard HEAD^^^ 
HEAD is now at f0c8c82 C 
~/testdir(master) $ git merge A B 
Fast-forwarding to: A 
Fast-forwarding to: B 
error: Entry 'myfile' would be overwritten by merge. Cannot merge. 
Merge with strategy octopus failed. 

~/testdir(master) $ cat myfile 
This is A1 

De hecho, cuando el avance rápido a A, la etiqueta de maestro no ha sido empujado hacia adelante, aunque el árbol tiene.

~/testdir(master) $ git status 
# On branch master 
# Changes to be committed: 
# (use "git reset HEAD <file>..." to unstage) 
# 
# modified: myfile 
# 

Si, mirando el código de lo que hace la fusión pulpo, llevo a cabo de forma manual (vea más arriba para los hashes):

~/testdir(master) $ git reset --hard f0c8c82 
HEAD is now at f0c8c82 C  
~/testdir(master) $ git read-tree -u -m f0c8c82 ac5b51c 
~/testdir(master) $ git read-tree -u -m f0c8c82 5bc838c 
error: Entry 'myfile' would be overwritten by merge. Cannot merge. 

En la otra dirección (merge B A), ahora, si mira nuevamente el código de merge-octopus, intenta detectar que la rama que estamos tratando de agregar ya está en el árbol (segundo case del bucle for). De hecho, en la fusión de A, ve que ac5b51c (a.k.a. la cabeza de A) es el ancestro común de A y B, y aborta sin hacer el segundo read-tree.

Este comportamiento es coherente con la versión nueva de git: aunque he señalado v.1.3.1, esto todavía está sucediendo con mi versión.

~/testdir(master) $ git --version 
git version 1.7.5.4 

tl; dr: desea que sus ramas se fusionan pulpo para tocar archivos de distintos

+1

Su enlace realmente no explica lo que quiere decir directamente en sentido ascendente. Mi mejor suposición es que te refieres a que la fusión sería un avance rápido, es decir, B es un "upstream directo" de A significa que A es un ancestro de B. En ese caso, tu ejemplo no funciona. En el primer caso, ambas fusiones son rápidas, y todo es bueno, y en el segundo caso, la primera es un avance rápido y la segunda ya está fusionada y, por lo tanto, no opera, no es causa de conflictos de fusión. – Cascabel

+3

Tienes razón, fui muy impreciso.He editado mi respuesta para reflejar sus comentarios, añade la indicación fundamental que el pulpo no actualiza el índice de la cabeza entre las aplicaciones de mezcla, y se incluye un ejemplo mínimo. – huitseeker

+0

Impresionante, ahora esa es una respuesta. – Cascabel