Git rebase vs Git merge

Qué estrategia usar al integrar cambios en tu proyecto, ¿git merge o git rebase?

estrategias-git-rebase-vs-merge

Git ofrece varias formas de integrar cambios en un proyecto. Dos de los métodos más usados son merge y rebase. Cada uno tiene sus propias características, usos y consecuencias en el historial de la rama. En este artículo veremos en qué se diferencian estas estrategias, cómo se utilizan en distintos escenarios y algunos ejemplos prácticos.

Git Merge

El comando git merge une ramas creando un nuevo commit de fusión. Esto permite ver claramente la historia de la integración, ya que se preservan los commits originales. Es una opción que puede facilitar la revisión del proceso cuando se trabaja en equipo.

Por ejemplo, si tienes una rama de características y deseas integrar sus cambios en la rama principal main, puedes hacerlo de la siguiente forma:

Terminal
git checkout main
git merge feature-branch

Este comando creará un commit de fusión, lo que resulta útil si necesitas mantener un registro visual de cuándo se integraron ciertos cambios. La estructura del historial es clara y refleja las líneas paralelas de desarrollo y se puede seguir visualmente cuando una rama divierge de otra.

Git Rebase

Por otro lado, git rebase permite reescribir la base de una rama, colocando los commits de una rama sobre otra. Esto resulta en una historia lineal, sin los commits de fusión, lo que puede facilitar la lectura del historial.

Un ejemplo típico es actualizar una rama de características con los últimos cambios de main:

Terminal
git checkout feature-branch
git rebase main

Este comando aplica los cambios de feature-branch sobre la punta actual de main. Si aparecen conflictos, Git te permitirá resolverlos antes de continuar con el proceso.

Comparación y Consideraciones

Al elegir entre merge y rebase, es importante considerar algunos puntos:

  • Historial:

    • Merge preserva el historial completo con bifurcaciones y fusiones.
    • Rebase reescribe el historial, resultando en una línea continua.
  • Trabajo en Equipo:

    • Usar merge puede evitar confusiones cuando varias personas colaboran en una misma rama.
    • Con rebase es crucial coordinar bien para evitar conflictos en ramas compartidas.
  • Claridad vs. Limpieza:

    • Merge proporciona una imagen clara de cómo se integraron los cambios.
    • Rebase da un historial lineal que puede ser más fácil de leer en ciertos contextos.

Cada estrategia tiene su uso. Por ejemplo, en un entorno donde se requiere mantener un registro completo de la evolución del proyecto, git merge es una opción que permite visualizar las integraciones. En cambio, si se busca simplificar el historial para facilitar la revisión, git rebase puede ser preferible.

Ejemplo de un flujo de trabajo para evitar conflictos

Supongamos que desarrollando una nueva funcionalidad y sigues este flujo común en una rama que ya existe en remoto feature-branch:

  1. Crear y cambiar a una nueva rama:

    Terminal
    git checkout feature-branch
  2. Hacer algunos cambios y confirmarlos:

    Terminal
    echo "Nuevo código" >> archivo.txt
    git add archivo.txt
    git commit -m "feat: añadir nueva funcionalidad"
  3. Intentar hacer push:

    Terminal
    git push origin feature-branch
  4. Error al hacer push porque hay cambios en remoto:

    Terminal
    ! [rejected] feature-branch -> feature-branch (fetch first)

    Esto significa que alguien más ha enviado cambios a feature-branch en el repositorio remoto y tu historial local está desactualizado.

Vamos a ver qué pasaría siguiendo cada una de las dos estrategias, git merge vs git rebase.

Opción 1: Usar git pull --merge (Git Merge)

Para mantener el historial tal cual y agregar un commit de fusión, usamos merge:

  1. Traer los cambios con merge:

    Terminal
    git pull --merge origin feature-branch
    • Git descargará los cambios remotos y los fusionará con tu trabajo local.
    • Si no hay conflictos, se creará un nuevo commit de fusión automáticamente.
  2. Resolver conflictos si aparecen:
    Si Git detecta conflictos, edita los archivos afectados y luego ejecuta:

    Terminal
    git add archivo_conflictivo.txt
    git commit -m "Resolver conflictos en la fusión"
  3. Subir los cambios al remoto:

    Terminal
    git push origin feature-branch

    No es necesario --force porque merge mantiene un historial compatible con el remoto.

Opción 2: Usar git pull --rebase (Git Rebase)

En cambio, si decides hacer un rebase, estarás aplicando tus cambios sobre la versión más reciente de la rama remota:

  1. Traer los cambios con rebase:

    Terminal
    git pull --rebase origin feature-branch
    • Git descargará los cambios del remoto.
    • Luego, intentará aplicar tus commits sobre la versión más reciente.
  2. Resolver conflictos si aparecen:
    Si Git detecta conflictos, los marcará en los archivos afectados. Debes editarlos y luego ejecutar:

    Terminal
    git add archivo_conflictivo.txt
    git rebase --continue
  3. Subir los cambios al remoto:

    Terminal
    git push origin feature-branch --force-with-lease

    Usamos --force-with-lease en lugar de --force para evitar sobrescribir cambios inesperadamente.

Conclusión

Tanto git merge como git rebase ofrecen caminos distintos para integrar cambios en un proyecto. Cada uno tiene sus ventajas dependiendo del flujo de trabajo y la necesidad de claridad en el historial. La elección entre uno u otro dependerá del contexto del equipo y del proyecto. Al comprender sus diferencias y utilizar ejemplos prácticos, puedes decidir qué estrategia se adapta mejor a tus necesidades.