gitrebaseflujo de trabajoversionado

Git rebase vs merge: cuál usar y los flujos de ramas que funcionan

Cuándo hacer merge y cuándo rebase, cómo resolver conflictos sin pánico, interactive rebase para limpiar historial y qué flujos de ramas usar según equipo.

27 de agosto de 2026·9 min de lectura

Merge o rebase es el debate eterno de Git, y la mayoría de discusiones se pierden porque mezclan dos preguntas distintas: ¿cómo integro cambios ajenos? y ¿qué historia quiero contar? Separarlas convierte el dilema en una decisión técnica de diez segundos. Este artículo cubre ambos, más las técnicas de limpieza que hacen tu historial legible.

Qué hace cada uno, exactamente

Partimos del escenario típico: rama main avanzó mientras trabajabas en feature.

Merge crea un commit nuevo con DOS padres, uniendo las líneas temporales:

      A---B---C  feature
     /         \
D---E---F---G---M   main (M = merge commit)

La historia queda literal como ocurrió: bifurcación y reunión visibles. El grafo se complica con cada feature, pero ningún commit cambia jamás.

Rebase reescribe tus commits como si hubieran nacido sobre la punta actual:

D---E---F---A'---B'---C'  feature (reescribida)
              ↑
main sigue en F

Git copia tus commits uno a uno aplicándolos sobre la nueva base. La historia resultante es lineal — pero son commits NUEVOS con hashes distintos. Los originales quedan huérfanos hasta que el garbage collector los recoge.

La regla de oro que termina debates

Rebase lo privado; merge lo público.

  • Commits que SOLO tú tienes (tu feature local, tu rama personal sin pushear): rebase libre. Reescribes tu propio borrador.
  • Commits ya compartidos (pusheados y usados por otros, o integrados): jamás rebase. Reescribir historia pública rompe el trabajo de todos — sus clones apuntan a commits que ya no existen.

Aplicado al flujo estándar: mantén tu feature al día con git fetch && git rebase origin/main (historial limpio), y cuando esté lista, integra con merge (o fast-forward si no divergió) hacia main.

El fast-forward: merge sin commit

Si main no avanzó desde que bifurcaste, Git ni necesita commit de fusión: simplemente mueve el puntero (--ff). Es el caso feliz — historial perfectamente lineal sin reescribir nada.

Con --no-ff fuerzas SIEMPRE el merge commit, preservando la agrupación visual de cada feature (útil para revertir features enteras con un solo revert). Elección de proyecto, ambas legítimas:

git merge --ff-only origin/main    # falla si no puede fast-forward: seguro
git merge --no-ff feature          # siempre genera commit de merge

Conflictos sin pánico

Un conflicto significa: ambos lados tocaron las mismas líneas y Git no puede decidir. El fichero queda marcado:

<<<<<<< HEAD
texto de la rama actual
=======
texto que llega
>>>>>>> feature

Protocolo tranquilo:

  1. git status lista los ficheros en conflicto — solo esos.
  2. Edita cada marcador decidiendo el contenido FINAL (a veces combinación de ambos, a veces solo uno).
  3. Los marcadores <<<<<<</=======/>>>>>>> JAMÁS sobreviven a tu edición.
  4. git add fichero marca resuelto; al terminar todos: continúa (git rebase --continue o git merge --continue).

Dos escapes de emergencia: git merge --abort / git rebase --abort devuelven todo al estado preoperación — sin daño, sin pérdida. Usarlos sin miedo es lo que quita el pánico.

Truco pro: git config merge.conflictstyle diff3 añade un tercer bloque con el ancestro común, mostrando QUÉ cambió cada lado respecto al original — la diferencia entre adivinar y entender el conflicto.

Interactive rebase: cirugía de historial

git rebase -i HEAD~5 abre el editor con tus últimos 5 commits y acciones por línea:

pick a1b2c3 feat: añade formulario
pick d4e5f6 fix: typo
pick g7h8i9 fix: otro typo
pick j0k1l2 wip

Cambias pick por el verbo y guardas:

  • squash/s: funde con el anterior (los tres "fix/wip" → un commit coherente).
  • reword/r: edita solo el mensaje.
  • edit/e: párate ahí para modificar contenido (añadir olvidos con git commit --amend).
  • drop/d: elimina el commit.
  • fixup/f: squash descartando el mensaje del commit absorbido.

Resultado: "feat: añade formulario" + un solo "fix" fusionado — historial donde cada commit compila y tiene sentido. Es la diferencia entre un log navegable y un vertedero de "wip", "asdf" y "fix2-final-REAL".

Advertencias de seguridad: nunca rebase interactivo sobre commits compartidos; haz backup previo con git branch backup-pre-rebase (borrar rama es gratis); y si te pierdes a mitad, git reflog muestra dónde estabas — git reset --hard HEAD@{n} restaura cualquier punto reciente.

Flujos de ramas por tamaño de equipo

Trunk-based (1-dev o equipos maduros con CI fuerte): ramas viven horas, no días. Todo integra rápido a main; feature flags ocultan lo incompleto. Máxima simplicidad operativa, requiere disciplina de tests.

Feature branches ligeros (el punto dulce de la mayoría): una rama por feature/tarea, vida de pocos días, PR con review, merge a main, borrado. Es lo que hace GitHub/GitLab cómodos y auditable.

GitFlow (main + develop + release + hotfix): nació para software versionado con releases planificados (apps empaquetadas, on-premise). Para web con deploy continuo es ceremonia muerta — demasiadas ramas permanentes para cero beneficio.

La tendencia real de la industria converge en trunk-based o feature-branches-ligeras + CI estricto.

Compara antes de decidir

Antes de un merge delicado, mira EXACTAMENTE qué traerá:

git diff main...feature        # qué añade feature respecto al ancestro común
git log main..feature --oneline  # commits que llegan

Nuestro comparador de textos sirve para revisar diffs pegados fuera de terminal (code reviews por chat, snippets de compañeros), y si quieres dominar los comandos sueltos, el cheatsheet de Git tiene los imprescindibles en una página.

Preguntas frecuentes

¿Perdí commits tras un rebase? Casi seguro que no: git reflog guarda todo movimiento de HEAD durante meses. Localiza el hash previo al desastre y git branch recuperado <hash>.

¿Pushee con force? Solo --force-with-lease (falla si alguien pusheó mientras tanto) y solo en TUS ramas. Force naked a shared branches es cómo se borra el trabajo ajeno.

¿Squash al mergear o merge normal? Squash (PR entera = 1 commit en main) da main limpia a costa de granularidad de revert. Merge normal conserva todo. Equipos con buen hygiene de commits: merge normal; equipos con "wip": squash sin dudarlo.


Compara versiones de texto fuera de la terminal con nuestro Diff Checker, gratis y directamente en tu navegador.

Pruébalo sin código

Comparador de Texto

Diferencias línea a línea entre textos.

Abrir Comparador de Texto

Hecho por

Miguel Ángel Colorado Marin (MACM)

Full-Stack Developer · Guadalajara, España

Desarrollo aplicaciones web, herramientas digitales y proyectos completos — desde el diseño hasta el despliegue.

Contáctame