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.
| Mecanismo | Idea en una frase |
|---|---|
| Merge | Se crea un commit que une las dos ramas, conservando su historia tal cual. |
| Rebase | Se 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:
git switch main
git pull origin mainEl 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.
# 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ón | Efecto |
|---|---|
git merge feature | Fusión (fast-forward si es posible) |
git merge --no-ff feature | Crear siempre un commit de fusión (deja rastro de la rama) |
git merge --abort | Cancelar 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.
git merge --no-ff feature/panier — el --no-ff deja un rastro explícito de la rama fusionada.
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):
# 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 rebase | Precaución |
|---|---|
| Historial lineal y legible | Reescribe los commits (SHA nuevos) |
| Sin commits de fusión parásitos | Nunca rebasar una rama ya empujada y compartida |
| Ideal antes de una pull request | Conflictos 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).
git rebase main (estando bien en feature/panier).
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:
<<<<<<< HEAD
prix = 10 # versión de main
=======
prix = 12 # versión de feature
>>>>>>> feature/panierLa resolución paso a paso:
<<<<<<<, =======, >>>>>>>.git add.# 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 ayuda | Uso |
|---|---|
git status | Listar los archivos en conflicto |
git diff | Ver las diferencias conflictivas |
git mergetool | Lanzar una herramienta gráfica de resolución |
| VS Code | Botones 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?
git add app.py
git rebase --continue(Para un merge, sería git add app.py y luego git commit.)
Los dos reúnen el trabajo, pero producen un historial distinto. La elección suele ser una convención de equipo.
| Aspecto | Merge | Rebase |
|---|---|---|
| Historial | Fiel, ramificado | Lineal, limpio |
| Commit de fusión | Sí (si no es fast-forward) | No |
| Reescribe la historia | No | Sí (SHA nuevos) |
| Seguro en rama compartida | ✅ Sí | ❌ No |
Legibilidad del log | Más densa | Más clara |
La práctica recomendada más habitual:
main antes de abrir una pull request → historial limpio.main → rastro claro de la integración.# 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 mergeFrase mnemotécnica: «Rebase en privado, merge en público.» Se rebasea lo que es propio, se fusiona lo que está compartido.
¿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
✅ Respuesta: b) — Es una fusión a tres ramas: Git crea un commit de fusión que reúne las dos historias.
¿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
✅ Respuesta: a) — El rebase desplaza y reproduce tus commits en la cima de main, y produce una historia lineal.
¿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
✅ Respuesta: b) — El rebase crea SHA nuevos. Si otros ya tienen esos commits, su historial se vuelve incoherente.
¿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
✅ Respuesta: c) — Son los marcadores de conflicto: arriba la versión actual (HEAD), abajo la versión entrante. Se elige y se borran.
¿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
✅ Respuesta: b) — git merge --abort (o git rebase --abort) devuelve el repositorio a su estado de antes de la operación.
main y deja un historial lineal.git merge --abort (o git rebase --abort) cancela y restaura el estado anterior.Dos ramas modifican la misma línea de un archivo config.txt. Reproduce el conflicto y luego resuélvelo conservando las dos informaciones combinadas.
main, el archivo contiene port = 8080.feature/ssl cambia esa línea a port = 443.main cambia la misma línea a port = 9090.feature/ssl en main, resuelve el conflicto conservando port = 443 (HTTPS) y termina.# 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/sslGit muestra entonces:
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:
<<<<<<< HEAD
port = 9090
=======
port = 443
>>>>>>> feature/sslSe edita para conservar solo el valor correcto:
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ón | Comando | Salida |
|---|---|---|
| Conflicto resuelto | git status | « nothing to commit, working tree clean » |
| Contenido final | cat config.txt | port = 443 |
| Commit de fusión | git log --oneline -1 | « Fusion feature/ssl : conservation du port 443 » |
Truco: si te equivocas en pleno conflicto,
git merge --abortte devuelve el repositorio intacto. Ningún riesgo en experimentar.
add, se termina.main.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.
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