DEV Community

Cover image for Fusión de ramas en git con rebase 🍂
Cristian Fernando
Cristian Fernando

Posted on

Fusión de ramas en git con rebase 🍂

Índice

  1. Introducción
  2. ¿Qué significa hacer un rebase?
  3. Tipos de rebase
  4. ¿Cuándo considerar hacer un rebase en lugar de un merge?
  5. Preparación del ejemplo
  6. Los 4 pasos para hacer un rebase exitoso
  7. La regla de oro del rebase
  8. Referencias
  9. Conclusiones

1. Introducción

Cuando empezamos a manipular ramas en git una de los primeros conceptos que aprendemos es el de fusión o merge para poder unir nuestro trabajo con el de otras personas. Pero si queremos dar un paso más en nuestro aprendizaje de git tarde o temprano tendremos que aprender a hacer cambios de base o rebase.

Un rebase en términos sencillos es otra estrategia que tenemos disponible para poder unir ramas en git y que puede ser muy útil para poder mantener un historial de cambios más pulcro.

A diferencia de un merge, un rebase en git puede ser un poco más complejo de entender al principio, adicionalmente a ello pueden darse casos en los que un rebase mal hecho puede desordenar completamente el historial de cambios de un proyecto y por esta razón justamente es una técnica un poco temida por los desarrolladores.

Este post será una guía para aprender tanto con teoría como con práctica todo lo necesario que debes saber para poder hacer un rebase exitoso en tus proyectos de desarrollo.

¡Comencemos!😃

2. ¿Qué significa hacer un rebase?

El rebase se puede traducir al español como un cambio de base, esto significa que podemos unir ramas de nuestro proyecto con un enfoque un poco diferente al merge típico que conocemos.

Lo que me gustaría que quede claro en este punto es que hacer un rebase no es más que una manera diferente de unir ramas, esta manera tiene claras diferencias con un merge y será decisión de cada desarrollador optar por un o por otro método de unión.

3. Tipos de rebase

Git nos ofrece dos tipos de rebase:

  • Por un lado tenemos un "rebase a secas" o rebase simple que como ya habíamos mencionado nos sirve para poder unir ramas. Este rebase es la manera más sencilla de usar el comando y también de los más usados.

  • Por otro lado tenemos lo que se denomina un rebase interactivo, este tipo de rebase ya no nos sirve para unir ramas sino para poder tener una mejor organización en nuestro historial de cambios, por ejemplo podemos modificar el mensaje de commit de algún cambio hecho, podemos separar un commit grande en commits más pequeños, podemos unir commits pequeños en un commit más robusto e inclusive podemos eliminar commits.

Como te das cuenta estas operaciones no son muy del día a día, son comandos que nos pueden ayudar a tener un historial limpio antes de mandar los cambios al repositorio remoto y que nuestros compañeros vean nuestro trabajo ordenado.

En este post nos concentramos netamente en el "rebase a secas" que nos permite unir ramas y dejaremos el rebase interactivo para otro post del blog.

4. ¿Cuándo considerar hacer un rebase?

¿Por qué debería aprender a hacer un rebase?
¿Si ya aprendí a unir ramas con merge eso es suficiente verdad?

Bueno si y no. Si bien la mayoría de las ocasiones un merge solucionará nuestro problemas me parece que es interesante comprender que existen otras herramientas que nos proporciona git para solucionar nuestros problemas desde otro enfoque.

Considera usar rebase en los siguientes casos:

  • Cuando quieras priorizar la pulcritud del historial de cambios y quieras mantener un historial lineal y sencillo de comprender.
  • Cuando tengas un repositorio con muchas ramas puede ser complicado entenderlo, entonces por simplicidad es recomendable usar rebase.

5. Preparación del ejemplo

Para ejemplificar mejor un rebase vamos a usar gráficos y dos ramas de ejemplo: una rama develop y otra rama branch-feature.

Para nuestro ejemplo ambas ramas divergen en su historial de cambios, esto significa que no es posibles unirlas de modo directo haciendo un fast forward ya que una rama tiene commits que la otra rama desconoce. Veamos esto a mas detalle con nuestro ejemplo:

img

Nuestro ejemplo consta de nuestra rama develop con 4 commits en azul nuestra rama branch-feature con 3 commits en amarillo, cada commit cuenta con su respectivo hash de identificación y el HEAD apunta al último commit de la rama develop lo que en otras palabras siginifica que actualmente nos encontramos en dicha rama.

Un dato importante para comprender bien este ejemplo es que asumimos que en ninguna parte del proceso nos encontraremos con conflictos.

Resolver conflictos con rebase es más complicado que con merge y vale la pena dedicarle un post individual por aparte para comprender mejor este aspecto. Por ahora mantengamos todo simple.

6. Los 4 pasos para hacer un rebase exitoso

Paso #1: identificar el commit base

Llamaremos commit base al commit donde ambas ramas se separan, en este caso nuestro commit base será 159b69 de la rama develop:

img

Paso #2: aplicamos el comando git rebase

Cambiamos de rama y nos posicionamos en branch-feature y en nuestra consola escribimos git rebase develop.

Esto creará una área temporal en nuestro proyecto, en dicha área estarán nuestro commits de la rama branch-feature de la siguiente manera:

img

Notar que:

  • El HEAD se movió al último commit de la rama branch-feature.
  • Se creó el área temporal de commits separando ambas ramas.

Paso #3: se mueve la rama y se cambian los commits

Al hacer git rebase develop adicionalmente de crear el área temporal de commits, movemos la rama branch-feature al inicio de la rama develop pero los commits se cambian.

img

Ahora la rama branch-feature "cambia de base" moviéndose al inicio del historial de cambios del proyecto y todos sus commits cambiaron de hash.

Este cambio de hash es de vital importancia y uno de los principales motivos por los que se pueden tener problemas muy complejos de resolver. Esto lo veremos a más detalle en el siguiente punto.

Paso #4: fusionar ambas ramas

Para que nuestro rebase este completo solo nos queda fusionar ambas ramas, puesto que ya no existen divergencias entre las ramas se procede a hacer un fast forward desde la rama develop haciendo git merge branch-feature de la siguiente manera:

img

El objetivo final de hacer un rebase siempre será quedar con un historial de cambios más limpio y lineal.

Para finalizar este apartado solo imaginemos qué hubiera pasado en nuestro ejemplo si en lugar de hacer un rebase hubiéramos hecho un merge:

img

Debido a que el ejemplo parte con ambas ramas divergiendo no es posible hacer un merge de tipo fast-forward, necesariamente tendremos que hacer un merge de tipo 3-way donde creamos un commit adicional que representará la unión de ambas ramas.

El resultado práctico al final es el mismo: unir ambas ramas. Pero cabe notar que cuando hacemos rebase el resultado final queda mucho más fácil de entender que cuando hacemos merge.

7. La regla de oro del rebase

Luego de comprender los aspectos básicos a tomar en cuenta para hacer un rebase toca hablar de una única regla de oro que debemos tener siempre presente:

NUNCA PERO NUNCA HACER REBASE EN RAMAS REMOTAS.

Como ya aprendimos una de las principales características del rebase es el cambio de commits, ahora imagina que cambias los commits y mandas esos cambios a una rama remota, ¿qué crees que pasará?

En algún momento es muy probable que uno o varios colegas tuyos necesiten acceder a esos commits pero ahora que les cambiaste el hash con el rebase no los podrá encontrar, para ellos será como si no existieran.

El rebase solo debe usarse en entornos locales para organizar mejor tus ramas, una vez hecho esto recién manda tus cambios al repositorio remoto.

Cumple esta única regla a rajatabla y nunca tendrás problemas serios con el rebase.

8. Referencias

Gran parte de la información recobrada para este post fue extraida del libro Learning Git: A Hands-On and Visual Guide to the Basics of Git de Anna Skoulikari

img

9. Conclusiones

  • rebase es una manera diferente de unir ramas en git.
  • rebase es muy útil cuando tenemos muchas ramas en nuestro proyecto y la comprensión visual puede ser complicada, entonces nos facilita la unión de ramas quedando como resultado final un historial de cambios más limpio.
  • Resolver conflictos con rebase es más complicado que con merge.
  • Existen 2 variantes del rebase: el "rebase a secas" que vimos en este post y el rebase interactivo que es útil para combinar, separar o borrar commits.
  • Nunca uses rebase en ramas remotas, como los hash de los commits cambian te puede generar muchos problemas serios y complejos de resolver.

Otros post de mi autoría que te pueden interesar:

end

Top comments (0)