Software Engineer
Aquellos que han comido un trozo de wasabi pensando que era un trozo de aguacate han aprendido la importancia de distinguir entre dos cosas muy parecidas. Comprender la diferencia entre los comandos merge y rebase de Git puede no ser tan esencial para su bienestar físico, pero el punto sigue en pie.
git merge y git rebase ofrecen el mismo servicio: incorporar confirmaciones de una rama de Git a otra. La distinción clave radica en cómo se logra este resultado.
Averigüemos cómo , ¿de acuerdo?
Basaremos nuestra breve discusión en el “sitio web” más exiguo jamás concebido. Inicialmente, este sitio web consta de una sola página con las letras "ab". Eso es todo.
Esto va en el currículum.
A menudo, en los flujos de trabajo de Git, los desarrolladores crearán ramas de funciones para trabajar en nuevas funciones de forma aislada. Esto les da la libertad de realizar confirmaciones incrementales para una función en progreso sin afectar la rama maestra del proyecto (puede encontrar más información sobre el uso de ramas de funciones en los tutoriales de Git de Atlassian ).
En el repositorio Git de nuestro proyecto, actualmente existen dos ramas: la rama principal habitual y una rama de funciones que creamos justo después de la confirmación inicial. En la rama maestra, hemos puesto en cursiva la 'a' y luego en negrita la 'a'. En nuestra rama de características, hemos puesto en cursiva la 'b' y luego en negrita la 'b'.
Las ramas maestras y características del proyecto web más complicado de 2017.
Los registros/historiales de confirmación para las ramas principales y de características (leídos de arriba a abajo).
Averigüemos en qué se diferencian fusionar y reorganizar pasando por un par de situaciones típicas de flujo de trabajo de Git con este proyecto.
Creemos que nuestro rediseño de la letra 'b' es nada menos que una obra maestra, por lo que decidimos que queremos volver a llevar nuestro trabajo a la rama principal, incorporándolo al proyecto real:
función de combinación de git checkout mastergit
Al fusionar la característica con el maestro , el maestro obtiene una nueva confirmación: una "compromiso de fusión".
Fusionando maestro en nuestra rama de características. “Vamos a aplastar estas ramas juntas”.
Historiales de rama después de la fusión, con la nueva confirmación de fusión del maestro.
Por sí mismo, la confirmación de fusión representa todos los cambios que se han producido en la característica desde que se bifurcó desde el maestro. Limpio y sencillo.
¿La desventaja de fusionarse? Si se usan con demasiada liberalidad, las confirmaciones de combinación pueden saturar los registros de Git y dificultar mucho más la comprensión del flujo del historial de su proyecto. Para flujos de trabajo colaborativos en los que otros desarrolladores (y potencialmente incluso gerentes de proyecto/líderes o control de calidad) leen los registros de Git de su proyecto para obtener información y contexto, la legibilidad es importante.
Un ejemplo extremo de fusión-manía. Difícil de descifrar, pero al menos los colores son bonitos... Crédito de la imagen
Para evitar este escollo, intente utilizar fusiones deliberadamente y con moderación. Evite bifurcarse y fusionarse cuando solo realice ajustes menores o corrija errores triviales. Utilice merge para los casos en los que desee que se destaque un conjunto de confirmaciones.
Los refactores grandes y las principales adiciones de funciones son buenos candidatos para ramas de funciones separadas que luego se pueden fusionar en el maestro. Como beneficio adicional, cuando las fusiones se reservan para estos cambios importantes, las confirmaciones de fusión actúan como hitos que otros pueden usar para averiguar cuándo se incorporaron estos cambios importantes al proyecto.
Rebobinemos y supongamos que, en cambio, queríamos seguir trabajando en el estilo de la letra 'b', tal vez cambiar su tamaño, fuente, color, etc. Necesitamos hacerlo bien: ¡este cambio afecta el 50% de nuestra base de código! Pero antes de continuar trabajando en nuestra rama de funciones, decidimos que queremos traer los últimos cambios del maestro para mantener las cosas frescas.
En lugar de fusionar las nuevas confirmaciones del maestro en la función, optamos por reorganizar nuestra rama de función en el maestro .
característica de pago de gitgit rebase master
En un nivel alto, el cambio de base puede entenderse como "mover la base de una rama a una posición diferente". Piense en ello como un rehacer: "Quería comenzar aquí ".
El resultado de cambiar la base de nuestra rama de funciones en master.
En un nivel más bajo, lo que hace rebase en realidad es extraer confirmaciones de una rama una por una (cronológicamente) y volver a adjuntarlas a una confirmación diferente. El punto en el que la rama... se bifurcó ahora ha cambiado.
Lo que realmente sucede cuando cambiamos la base de nuestra rama de funciones a master. Básicamente, estamos reproduciendo las confirmaciones de la rama de funciones desde un nuevo punto de partida.
Puede ver en los diagramas anteriores por qué elegiríamos reorganizar en lugar de fusionarnos en esta situación. A diferencia de la fusión, la rebase no crea una confirmación adicional. Esto es ideal para nuestra situación, ya que todo lo que intentamos hacer actualmente es mantener nuestra rama de funciones actualizada con cualquier confirmación nueva del maestro. Este definitivamente no es un evento significativo que queremos preservar en la historia de nuestro proyecto.
Aunque los cambios en la nueva rama de funciones reorganizada son idénticos a los que eran antes, es bueno tener en cuenta que, desde la perspectiva de Git, se trata de nuevas confirmaciones con nuevos SHA (identificadores de confirmaciones).
Pero lo que es más importante, tenga en cuenta que el historial de la rama de funciones se ha reescrito por completo. Eso suena un poco pesado, ¿no? Quizás se pregunte si esto tiene implicaciones de las que debería preocuparse.
Un experto en viajes en el tiempo y sus inconvenientes: Barry Allen, un avance rápido hacia un futuro de arrepentimiento. Credito de imagen
Aunque no es importante cuando eres la única persona que trabaja en una rama en particular, la reorganización imprudente puede ser un problema importante cuando se colabora con otros. En resumen, surge la posibilidad de que otros tengan copias de la sucursal desprotegidas (con historial inalterado) que entran en conflicto con su copia alterada.
Imagina que otro desarrollador llamado Mark está trabajando en la rama de características junto a ti. Revisó la rama de características en su segundo compromiso, cuando la 'b' estaba en cursiva. Mientras volvíamos a basar nuestra versión de la rama de características en maestra, Mark inocentemente decidió agregar otra confirmación en su propia versión, agregando la letra 'c'. Así es como se vería el escenario:
La rama principal, nuestra versión rediseñada de la rama de funciones y la copia de Mark de la rama de funciones. Observe las inconsistencias entre nuestra rama (negrita) y la copia de Mark (azul). No es inmediatamente obvio cómo resolver esto.
Incluso con nuestro proyecto absolutamente simple, se necesitaría un poco de esfuerzo y capacidad intelectual para descubrir cómo resolver las discrepancias. Imagínese tratar de resolver este tipo de conflicto en un proyecto de mayor escala de la vida real. No es muy divertido.
Puedes leer más sobre la forma correcta de rebase aquí: La regla de oro del rebase . El resumen de una línea: no cambie la base de una rama a menos que sea el único que la use. O disfrutas del caos.
En resumen, al buscar incorporar cambios de una rama de Git a otra:
Eso es todo lo que tengo. Si algo en el artículo no quedó claro, o si tiene alguna pregunta, comentario o sugerencia, ¡no dude en dejarlos en las respuestas a continuación! ¡Gracias por tu tiempo!