Diferentes resultados para Git Merge y Rebase

Git merge y rebase objective es el mismo, reuniendo dos twigs juntas para get una única twig actualizada.

Al probar la herramienta Merge and Rebase en Android Studio (que usa obviamente commands git), obtengo resultados diferentes.

Fusionar: muéstrame conflictos reales entre muchos files.

Rebase: muestra solo 1 file en conflicto.

Sé que merge y rebase son dos commands completamente diferentes (rebase cambia el HEAD de la twig de características y agrega los nuevos commits encima de él (manteniendo el logging de historial de commits) mientras merge intenta combinar los HEADS de ambas twigs). Pero no tiene sentido que devuelvan resultados diferentes. Quiero decir, el conflicto es un conflicto, ¿no? Si el usuario A y el usuario B cambiaron la misma línea por lo que siempre debe entrar en conflicto con esa línea, no importa si usa fusionar o rebasear

Tal vez depende de la cantidad de compromiso que tenga después del punto de ramificación.

Si tienes más de un commit, git merge te mostrará todos los conflictos a la vez y git rebase te mostrará los conflictos para cada commit.

Supongamos que tiene esta situación:

 master A --- B --- C <- HEAD of master \ branch --- D --- E <- HEAD of branch 

Si estás en E y haces un git merge master , git te mostrará todos los conflictos y te pedirá que lo corrijas antes para crear el commit de fusión.

Si haces un git rebase master , en cambio, git tomará la cabeza del maestro ( C ) luego aplicará tu compromiso D y mostrará los conflictos (si los hay) pidiendo que se corrija y proceda con la rebase. Cuando solucionas los conflictos y modificas la confirmación, continúas con git rebase --continue y aplicará la confirmación E y volverá a mostrarte los conflictos.

Piense en una rebase como una fusión en la dirección opuesta.

Si la dirección es diferente, es natural que la fusión o la rebase se detenga en un conflicto diferente.

(Es por eso que solo ves 1 conflicto durante la rebase).

Los resultados de rebase vs merge dependen en gran medida de los cambios reales. Deben ser iguales si los cambios son independientes entre sets de compromisos.

Pero si alguna confirmación cambia algo que fue modificado por una confirmación anterior, entonces la order (combinación vs rebase) puede dar diferentes resultados / conflictos.

Ejemplo

Si, por ejemplo, elimina una línea de código y rebase, y la última versión de un file tiene las mismas líneas que la rodean, es probable que esa línea se elimine sin problemas.

Todo lo que se necesita es que "se aplique limpiamente", sin importar lo que haya cambiado debajo.

Pero, si se fusiona y el código en el área fusionada cambia, eliminar la línea puede entrar en conflicto con otros cambios (incluso si el "resultado neto" de las confirmaciones fusionadas es el mismo que el original en el que trabajó).

Solución

El mejor enfoque es probablemente rebase de forma interactiva git rebase -i master . De esta forma, puede "influir" en el order de los cambios en su rebase para que se apliquen de forma limpia o generen less conflictos.

Por lo general, es probable que solo desee utilizar la combinación cuando está integrando cambios de múltiples twigs en un lanzamiento. Así que tanto la rebase como la fusión tienen funcionalmente "propósitos diferentes". Restaure la database cuando desee agregar sus propios cambios locales a una sucursal remota, y fusione cuando esté eligiendo y mezclando cambios que otras personas hayan realizado.

Tenga en count que tanto la fusión como la rebase son "trampas": cambian la línea de time de las confirmaciones y los cambios pueden tener efectos secundarios según el order.

(Por ejemplo, si una persona quita una línea y luego revierte el cambio … mientras que otra simplemente elimina la línea … ¿debería quitarse la línea o no?)

Entonces el order (rebase vs merge) importa.