Índice
- Introducción
- ¿Qué significa hacer un rebase?
- Tipos de rebase
- ¿Cuándo considerar hacer un rebase en lugar de un merge?
- Preparación del ejemplo
- Los 4 pasos para hacer un rebase exitoso
- La regla de oro del rebase
- Referencias
- 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" orebase
simple que como ya habíamos mencionado nos sirve para poder unir ramas. Esterebase
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:
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 conmerge
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
:
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:
Notar que:
- El
HEAD
se movió al último commit de la ramabranch-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.
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:
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
:
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
- https://jmfloreszazo.com/git-mejores-practicas-rebase-vs-merge/
- https://www.atlassian.com/es/git/tutorials/rewriting-history/git-rebase
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
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 conmerge
. - Existen 2 variantes del
rebase
: el "rebase
a secas" que vimos en este post y elrebase
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:
Top comments (0)