Los conflictos de Git-rebase después de `git merge -X theirs develop`

Estoy en la sucursal foo y deseo fusionarme para develop mi twig de function foo . Quiero que todos los conflictos se resuelvan automáticamente y que el código de la sucursal sea automáticamente escrito. Desde la sucursal foo , hago git merge -X theirs develop que funciona. Cuando lo hago dos veces para verificarlo, ya estoy Already up-to-date .

Pero luego cuando me git rebase develop para asegurarme de que foo git rebase develop atrapado obtengo conflictos de fusión. ¿Por qué es esto cuando git merge -X theirs develop the merge debería tener todo el código de develop actualizado en branch foo ?

Rebase y fusión hacen cosas muy diferentes.

Cuando ejecutas git merge develop le estás diciendo a Git que:

  1. Identificar la confirmación actual ( HEAD ). Esto tiene algo de ID hash.
  2. Identifica otro compromiso, develop . Esto tiene algo de ID hash.
  3. Rastree el gráfico de compromiso para encontrar la confirmación básica de fusión de los antepasados ​​comunes de las dos confirmaciones identificadas en los pasos 1 y 2:

     ...--o--B--o--1 <-- somebranch (HEAD) \ o--o--2 <-- develop 
  4. Compara (como en git diff ) la base de combinación para cometer # 1.

  5. Compare la base de combinación para confirmar # 2.
  6. Combina estos dos diffs. (Este paso de combinación es donde -X theirs hace una diferencia: si hay conflictos de fusión en las dos diferencias, Git prefiere "su" cambio. Tenga en count que para cualquier parte de un solo file que muestra dos cambios diferentes pero no conflictivos, Git aún toma ambos cambios.) Aplica el resultado al tree en la base de fusión.
  7. Realiza una nueva confirmación de tipo "fusionar compromiso", con los padres n.º 1 y n.º 2 (en ese order) en la sucursal actual:

     ...--o--B--o--1---M <-- somebranch (HEAD) \ / o--o--2 <-- develop 

Si ahora ejecuta la misma git merge nuevamente, Git encuentra M y 2 , encuentra su base de combinación (que no es B esta vez sino 2 ) y declara que no hay nada que hacer: la base de fusión ya es una de las dos confirmaciones .

Cuando ejecutas git rebase develop estás diciendo a Git que:

  1. Haga una list de todas las confirmaciones accesibles desde la sugerencia de sucursal actual ( M , una vez realizada esta fusión) que no son alcanzables desde la confirmación identificada por develop (commit # 2):

     ...--o--B--o*-1*--M <-- somebranch (HEAD) \ / o--o--2 <-- develop 

    Marqué estos commits con * . Nota: M también se puede alcanzar desde M pero no desde 2 ; pero git rebase deliberadamente descarta todas las fusiones, ya que no tiene sentido tratar de volver a establecer una fusión.

  2. Usando el modo "HEAD desconectado", copie (vea a continuación) las confirmaciones marcadas, colocando las nuevas copys después de que se desarrolle el compromiso identificado por el nombre:

     ...--o--B--o*-1*--M <-- somebranch \ / o--o--2 <-- develop \ o*'--1*' <-- HEAD 
  3. Después de todas las copys realizadas con éxito (incluida la resolución de cualquier conflicto de fusión), elimine la label de somebranch de donde sea que esté ahora y colóquela al final de las confirmaciones copydas:

     ...--o--B--o--1---M [abandoned] \ / o--o--2 <-- develop \ o'--1' <-- somebranch (HEAD) 

Para copyr un commit, Git esencialmente (y a veces literalmente) ejecuta git cherry-pick en él. La operación de selección de cereza es en sí misma el "tipo de verbo" de la fusión (con una base de fusión un tanto peculiar, y "nuestra" y "de ellos" también puede ser confusa; vea comentarios). Por lo tanto, cada una de estas copys, independientemente de la cantidad de confirmaciones que se copien, puede tener conflictos de combinación. Cualquier resolución que hagas en M se ignorará (naturalmente, dado que M se ignora).