Merge y rebase

9 min

Tabla de contenidos


1 — Reunir dos ramas: la necesidad

Has trabajado en una rama feature, el código está listo. Ahora hay que reintegrarlo en main. Git ofrece dos mecanismos para eso: la fusión (merge) y el rebase (rebase).

Los dos alcanzan el mismo objetivo — reunir el trabajo — pero con una forma de historial distinta. Eso es todo el asunto de esta lección.

MecanismoIdea en una frase
MergeSe crea un commit que une las dos ramas, conservando su historia tal cual.
RebaseSe reproducen los commits de una rama encima de otra, como si se hubiera empezado más tarde.

Antes de cualquier integración, nos aseguramos de tener la última versión:

bash
git switch main
git pull origin main

↑ Volver arriba


2 — La fusión (merge)

El comando git merge reúne una rama en otra. Hay dos casos.

Caso 1 — Fusión rápida (fast-forward): si main no se ha movido desde la creación de la rama, Git simplemente avanza el puntero. No se crea ningún commit de fusión.

Caso 2 — Fusión a tres ramas (three-way merge): si main ha recibido commits nuevos entretanto, Git crea un commit de fusión que tiene dos padres.

bash
# Situarse en la rama destino, luego fusionar
git switch main
git merge feature/panier

# Forzar un commit de fusión aunque el fast-forward sea posible
git merge --no-ff feature/panier
OpciónEfecto
git merge featureFusión (fast-forward si es posible)
git merge --no-ff featureCrear siempre un commit de fusión (deja rastro de la rama)
git merge --abortCancelar una fusión en conflicto

El merge conserva la historia real: se ve cuándo y cómo se han reunido las ramas. Es honesto, pero el historial puede volverse tupido con muchos commits de fusión.

🔧 Mini-ejercicio — Quieres fusionar feature/panier en main forzando la creación de un commit de fusión, aunque un fast-forward sería posible. Escribe el comando.

✅ Ver una solución

git merge --no-ff feature/panier — el --no-ff deja un rastro explícito de la rama fusionada.

↑ Volver arriba


3 — El rebase (rebase)

El git rebase desplaza los commits de tu rama para reproducirlos encima de la punta de otra rama. Resultado: un historial lineal, como si hubieras empezado tu trabajo después de los últimos commits de main.

Antes del rebase:

Después de git rebase main (los commits B y C se reproducen después de D):

bash
# En la rama feature, reproducir encima de main
git switch feature/panier
git rebase main

# Luego fusión fast-forward limpia en main
git switch main
git merge feature/panier
Ventaja del rebasePrecaución
Historial lineal y legibleReescribe los commits (SHA nuevos)
Sin commits de fusión parásitosNunca rebasar una rama ya empujada y compartida
Ideal antes de una pull requestConflictos que hay que resolver commit a commit

⚠️ Regla de oro del rebase: nunca rebases commits ya publicados y usados por otros. Reescribes la historia, y eso rompería sus repositorios. El rebase es para tu trabajo local no compartido.

🔧 Mini-ejercicio — Estás en tu rama feature/panier. Escribe el comando para reproducir tus commits encima de la punta de main (historial lineal).

✅ Ver una solución

git rebase main (estando bien en feature/panier).

↑ Volver arriba


4 — Resolver los conflictos

Un conflicto aparece cuando Git no puede decidir automáticamente: dos ramas han modificado la misma línea de un mismo archivo. Git se detiene y te pide que decidas.

Git inserta marcadores de conflicto en el archivo:

text
<<<<<<< HEAD
prix = 10   # versión de main
=======
prix = 12   # versión de feature
>>>>>>> feature/panier

La resolución paso a paso:

  1. Abrir el archivo y elegir (o combinar) la versión correcta.
  2. Borrar los marcadores <<<<<<<, =======, >>>>>>>.
  3. Marcar el archivo como resuelto con git add.
  4. Terminar la operación.
bash
# Ver los archivos en conflicto
git status

# Tras la edición manual
git add fichier-en-conflit.py

# Terminar un merge
git commit

# Terminar un rebase
git rebase --continue

# Si cunde el pánico: cancelarlo todo
git merge --abort      # o: git rebase --abort
Herramienta de ayudaUso
git statusListar los archivos en conflicto
git diffVer las diferencias conflictivas
git mergetoolLanzar una herramienta gráfica de resolución
VS CodeBotones Accept Current / Incoming / Both

Un conflicto no es un error: es Git que, con honestidad, te dice «no sé cuál conservar, es tu decisión». Mantener la calma y leer los marcadores basta en el 99 % de los casos.

🔧 Mini-ejercicio — Has editado el archivo app.py para resolver un conflicto surgido durante un rebase. ¿Qué dos comandos terminan la operación?

✅ Ver una solución
bash
git add app.py
git rebase --continue

(Para un merge, sería git add app.py y luego git commit.)

↑ Volver arriba


5 — Merge o rebase: ¿qué elegir?

Los dos reúnen el trabajo, pero producen un historial distinto. La elección suele ser una convención de equipo.

AspectoMergeRebase
HistorialFiel, ramificadoLineal, limpio
Commit de fusiónSí (si no es fast-forward)No
Reescribe la historiaNoSí (SHA nuevos)
Seguro en rama compartida✅ Sí❌ No
Legibilidad del logMás densaMás clara

La práctica recomendada más habitual:

  • Rebase tu rama local sobre main antes de abrir una pull request → historial limpio.
  • Merge la pull request en main → rastro claro de la integración.
bash
# 1. Limpiar su rama local antes de la PR
git switch feature/x
git rebase main

# 2. Una vez aprobada la PR, GitHub hace el merge

Frase mnemotécnica: «Rebase en privado, merge en público.» Se rebasea lo que es propio, se fusiona lo que está compartido.

↑ Volver arriba


6 — Quiz — Merge y rebase

Question 1

¿Qué hace git merge feature desde main cuando main también tiene commits nuevos?

a) Borra la rama feature

b) Crea un commit de fusión con dos padres

c) Borra el historial

d) Se niega siempre a fusionar

💡 Ver la solución

Respuesta: b) — Es una fusión a tres ramas: Git crea un commit de fusión que reúne las dos historias.


Question 2

¿Cuál es el efecto principal de un git rebase main?

a) Reproducir los commits de la rama encima de main para un historial lineal

b) Clonar el repositorio

c) Borrar main

d) Crear una copia de seguridad remota

💡 Ver la solución

Respuesta: a) — El rebase desplaza y reproduce tus commits en la cima de main, y produce una historia lineal.


Question 3

¿Por qué no hay que rebasar una rama ya empujada y compartida?

a) Porque GitHub lo prohíbe

b) Porque reescribe los commits y rompe los repositorios de los demás

c) Porque el rebase es más lento

d) Porque borra main

💡 Ver la solución

Respuesta: b) — El rebase crea SHA nuevos. Si otros ya tienen esos commits, su historial se vuelve incoherente.


Question 4

¿Qué representan los marcadores <<<<<<<, =======, >>>>>>>?

a) Comentarios de código

b) Un error de sintaxis Python

c) Las zonas de un conflicto que hay que resolver a mano

d) El final de un archivo

💡 Ver la solución

Respuesta: c) — Son los marcadores de conflicto: arriba la versión actual (HEAD), abajo la versión entrante. Se elige y se borran.


Question 5

¿Cómo se cancela con limpieza una fusión bloqueada por conflictos?

a) git delete

b) git merge --abort

c) git reset --cloud

d) Borrar la carpeta .git

💡 Ver la solución

Respuesta: b)git merge --abort (o git rebase --abort) devuelve el repositorio a su estado de antes de la operación.

Corrigé

  1. b — Fusión a tres ramas: un commit de fusión reúne las dos historias.
  2. a — El rebase reproduce los commits encima de main y deja un historial lineal.
  3. b — El rebase crea SHA nuevos y rompe el historial de quien ya tenía esos commits.
  4. c — Los marcadores delimitan las dos versiones en conflicto; se elige y se borran.
  5. b — git merge --abort (o git rebase --abort) cancela y restaura el estado anterior.

↑ Volver arriba


7 — Práctica — Resolver un conflicto de fusión

Consigna

Dos ramas modifican la misma línea de un archivo config.txt. Reproduce el conflicto y luego resuélvelo conservando las dos informaciones combinadas.

  1. En main, el archivo contiene port = 8080.
  2. Una rama feature/ssl cambia esa línea a port = 443.
  3. Entretanto, main cambia la misma línea a port = 9090.
  4. Fusiona feature/ssl en main, resuelve el conflicto conservando port = 443 (HTTPS) y termina.

Corrección

bash
# Preparación: crear el conflicto
echo "port = 8080" > config.txt
git add config.txt
git commit -m "Config initiale"

git switch -c feature/ssl
echo "port = 443" > config.txt
git commit -am "Passage en HTTPS (port 443)"

git switch main
echo "port = 9090" > config.txt
git commit -am "Changement de port en 9090"

# Intento de fusión → conflicto
git merge feature/ssl

Git muestra entonces:

text
Auto-merging config.txt
CONFLICT (content): Merge conflict in config.txt
Automatic merge failed; fix conflicts and then commit the result.

El archivo config.txt contiene:

text
<<<<<<< HEAD
port = 9090
=======
port = 443
>>>>>>> feature/ssl

Se edita para conservar solo el valor correcto:

bash
echo "port = 443" > config.txt   # se decide a favor de HTTPS

git add config.txt
git commit -m "Fusion feature/ssl : conservation du port 443"

Resultado esperado:

VerificaciónComandoSalida
Conflicto resueltogit status« nothing to commit, working tree clean »
Contenido finalcat config.txtport = 443
Commit de fusióngit log --oneline -1« Fusion feature/ssl : conservation du port 443 »

Truco: si te equivocas en pleno conflicto, git merge --abort te devuelve el repositorio intacto. Ningún riesgo en experimentar.

↑ Volver arriba


8 — Síntesis

Puntos a recordar

  1. Merge y rebase reúnen dos ramas, pero producen un historial distinto.
  2. Merge conserva la historia real; crea un commit de fusión con dos padres (salvo fast-forward).
  3. Rebase reproduce los commits para un historial lineal y limpio.
  4. Regla de oro: rebase en privado, merge en público — nunca rebasar código compartido.
  5. Un conflicto aparece cuando la misma línea se modifica en los dos lados: se edita, se hace add, se termina.
  6. Buena práctica: rebasar su rama antes de la PR, luego fusionar la PR en main.

A continuación

Sabes integrar el código técnicamente. La lección 03 — Pull requests muestra cómo hacer releer ese trabajo antes de integrarlo, en el corazón de la colaboración en GitHub.

↑ Volver arriba


Todos los derechos reservados. Toda reproducción, difusión, uso o adaptación de este curso, en todo o en parte, está estrictamente prohibida sin la autorización escrita previa del Dr. Haythem REHOUMA.

Curso creado por Dr. Haythem REHOUMA — Desarrollo y despliegue de soluciones de datos