Merge: Fusionando Ramas en Git
Bienvenido a esta lección sobre merge, uno de los comandos más fundamentales y utilizados cuando trabajas con Git en equipos de desarrollo. Si has seguido el curso, ya conoces cómo crear ramas para trabajar en funcionalidades separadas. Ahora es momento de aprender cómo unir esas ramas de vuelta a la línea principal de desarrollo.
- Comprender qué es un merge y cuándo usarlo
- Diferenciar entre los tipos de merge en Git
- Ejecutar fusiones de ramas de forma segura
- Reconocer y resolver conflictos básicos
- Aplicar buenas prácticas para merges exitosos
¿Qué es un Merge?
Un merge en Git es el proceso de combinar los cambios de una rama diferente dentro de tu rama actual. Cuando trabajas en una rama aislada (como feature/nueva-funcionalidad), todos los commits permanecen en esa rama. El merge permite integrar esos cambios a otra rama, típicamente main o develop.
El merge toma todos los cambios de una rama fuente y los aplica sobre la rama destino, creando un nuevo commit de merge que tiene dos padres. Este commit especial conecta ambas líneas de desarrollo en el historial de Git.
Tipos de Merge en Git
Git maneja diferentes estrategias de merge según la situación. Comprenderlas te ayudará a entender qué ocurre detrás de escenas.
| Tipo de Merge | Descripción | Cuándo ocurre |
|---|---|---|
| Fast-Forward | Git simplemente mueve el puntero hacia adelante | No hay cambios en la rama destino |
| Recursive | Crea un commit de merge con dos padres | Ambas ramas tienen cambios |
| Squash Merge | Combina todos los commits en uno solo | Quieres historial lineal |
| Octopus | Fusiona múltiples ramas a la vez | Ramas de release con múltiples features |
Fast-Forward Merge
Este es el tipo de merge más simple. Ocurre cuando la rama destino no tiene ningún commit nuevo desde que creaste tu rama de trabajo. Git simplemente avanza el puntero de la rama destino hasta el último commit de tu rama.
# Situación antes del merge:
# main: A - B
# feature: C - D - E
git checkout main
git merge feature
# Resultado:
# main: A - B - C - D - E
# (los commits de feature se "avanzan" a main)
--no-ff. Esto crea un commit de merge explícito incluso cuando Git podría hacer fast-forward.Recursive Merge (Three-Way Merge)
Cuando tanto la rama destino como la rama que quieres fusionar tienen cambios nuevos, Git utiliza un merge recursivo de tres vías. Este algoritmo:
- Identifica el ancestro común de ambas ramas
- Compara los cambios de cada rama con ese ancestro
- Combina los cambios automáticamente donde es posible
- Crea un commit de merge que une ambas líneas
# Situación:
# A - B - C (main)
# \
# D - E (feature)
git checkout main
git merge feature
# Resultado:
# A - B - C - F
# \ /
# D - E
#
# F es el commit de merge
El commit de merge tiene dos padres: el último commit de la rama destino y el último commit de la rama que estás fusionando. Esto es lo que permite a Git reconstruir el historial completo de ambas ramas.
Realizando tu Primer Merge
Vamos a practicar con un ejemplo completo paso a paso.
Escenario Práctico
Imagina que estás desarrollando una aplicación web y necesitas agregar una nueva funcionalidad de búsqueda:
# 1. Verifica que estás en main y está actualizado
git checkout main
git pull origin main
# 2. Crea una rama para la nueva funcionalidad
git checkout -b feature/buscador
# 3. Trabaja en tu funcionalidad (agregas archivos, haces commits)
touch buscador.js
git add buscador.js
git commit -m "Agrega módulo de búsqueda básico"
echo "function buscar() { return []; }" > buscador.js
git add buscador.js
git commit -m "Implementa lógica de búsqueda"
# 4. Una vez terminado, vuelves a main
git checkout main
# 5. Fusionas tu rama feature con main
git merge feature/buscador
# 6. Sube los cambios al repositorio remoto
git push origin main
git pull en tu rama destino antes de hacer merge. Esto minimiza la posibilidad de conflictos y asegura que estás integrando código actualizado.¿Qué pasa cuando hay conflictos?
Un conflicto ocurre cuando Git no puede fusionar automáticamente los cambios porque las mismas líneas fueron modificadas en ambas ramas. Esto es común cuando dos desarrolladores trabajan en las mismas partes del código.
Identificando Conflictos
Cuando intentas hacer merge y hay conflictos, Git te lo notificará:
git merge feature/nueva-funcion
Auto-merging archivo.js
CONFLICT (content): Merge conflict in archivo.js
Automatic merge failed; fix conflicts and then commit the result.
El archivo en conflicto tendrá marcadores especiales:
<<<<<<< HEAD (rama actual: main)
const titulo = "Bienvenido";
=======
const titulo = "Hola Mundo";
>>>>>>> feature/nueva-funcion
Los marcadores significan:
<<<<<<< HEAD: Inicio del conflicto, indica tu rama actual=======: Separador entre ambas versiones>>>>>>> feature/nueva-funcion: Fin del conflicto, indica la rama que estás fusionando
Resolviendo Conflictos
- Abre el archivo en conflicto con tu editor de código favorito
- Decide qué versión mantener: puede ser la de HEAD, la otra rama, o una combinación de ambas
- Elimina los marcadores de conflicto (
<<<<<<<,=======,>>>>>>>) - Edita el archivo dejando solo la versión final que deseas
- Guarda el archivo y cierra el editor
- Stage y commit:
git add archivo.jsygit commit
# Ejemplo de resolución - mantienes ambas versiones combinadas:
const titulo = "Bienvenido"; // conservas el texto de main
const subtitulo = "Buscador actualizado"; // agregas algo nuevo
# Luego:
git add archivo.js
git commit -m "Resuelve conflicto: combina títulos de ambas ramas"
# O si decides mantener solo una versión:
const titulo = "Hola Mundo"; // eliminas todo y dejas solo esto
git add archivo.js
git commit -m "Resuelve conflicto: usa versión de feature/nueva-funcion"
Ver más: Herramientas para resolver conflictos visualmente
Además de editar manualmente, existen herramientas que facilitan la resolución de conflictos:
- VS Code: Tiene un editor de conflictos integrado que muestra las diferencias lado a lado
- GitKraken: Cliente visual de Git con resolución de conflictos gráfica
- Meld: Herramienta gratuita de diff visual
- Beyond Compare: Comparador profesional (de pago)
Puedes configurar tu herramienta preferida con: git config --global merge.tool nombre_herramienta
Estrategias para Migrations Exitosos
"Un merge bien ejecutado es aquel donde nadie pierde su trabajo y todos los cambios terminan en el código final."
- Haz commits pequeños y frecuentes: Esto hace que los merges sean más fáciles de resolver
- Sincroniza frecuentemente: Ejecuta
git pullo merge desde la rama principal regularmente - Comunica con tu equipo: Si sabes que alguien más está trabajando en el mismo archivo, coordínalo
- Revisa los cambios antes de commitear: Usa
git diffpara entender qué se está combinando - Usa pull requests: En GitHub, los PRs permiten revisar código antes de hacer merge
Comandos Útiles para Merges
| Comando | Función |
|---|---|
git merge --abort |
Cancela el merge en progreso y vuelve al estado anterior |
git merge --continue |
Continúa después de resolver conflictos |
git merge --no-ff |
Fuerza creación de commit de merge |
git merge --squash |
Combina todos los commits en uno solo |
git merge --ff-only |
Solo hace merge si puede hacer fast-forward |
git log --merge |
Muestra commits que causan conflictos |
Merge vs Rebase: ¿Cuál elegir?
Esta es una pregunta común en la comunidad de Git. Ambos tienen sus ventajas:
- Merge: Preserva el historial completo, más seguro para trabajo en equipo, puede crear historial complejo
- Rebase: Historial lineal y limpio, no usar en ramas públicas, riesgo de perder trabajo si se hace mal
Para principiantes, recomendamos usar merge ya que es más difícil cometer errores irreversibles. El rebase se cubre en detalle en lecciones avanzadas del curso.
Práctica en GitHub
En plataformas como GitHub, también puedes hacer merges directamente desde la interfaz web:
- Abre el Pull Request de la rama que quieres fusionar
- Revisa los cambios en la pestaña "Files changed"
- En la pestaña "Conversation", haz clic en Merge pull request"
- Opcionalmente, marca "Squash and merge" para combinar commits
- Confirma con Confirm merge
Resumen
En esta lección has aprendido:
- Qué es un merge y por qué es fundamental para trabajar en equipo
- Los diferentes tipos de merge: fast-forward, recursive, squash
- Cómo ejecutar un merge paso a paso
- A identificar y resolver conflictos de forma manual
- Estrategias para hacer merges exitosos
- Herramientas y comandos útiles del día a día
1. ¿Qué tipo de merge ocurre cuando la rama destino no tiene cambios nuevos desde que creaste tu rama?
- A) Three-way merge
- B) Fast-forward merge
- C) Squash merge
- D) Octopus merge
2. ¿Qué debes hacer primero cuando Git indica conflictos durante un merge?
- A) Eliminar la rama con conflictos
- B) Editar los archivos en conflicto y resolverlos manualmente
- C) Reiniciar el computador
- D) Crear una nueva rama sin resolver
3. ¿Cuál comando cancela un merge que está en progreso?
- A) git merge --cancel
- B) git merge --undo
- C) git merge --abort
- D) git merge --stop
¡Felicitaciones! Ahora tienes las bases para fusionar ramas en Git de manera efectiva. En la siguiente lección exploraremos cómo resolver conflictos más complejos y las mejores prácticas para trabajo colaborativo.