Ramas y fusión
Aprende a crear ramas para trabajar en distintas funcionalidades y a fusionarlas en tu código principal.
Ramas y fusión
Las ramas son una de las funcionalidades más potentes de Git. Permiten desarrollar funcionalidades en paralelo, experimentar sin riesgo y mantener un historial limpio. En este tutorial aprenderás a dominar las ramas y las técnicas de fusión.
¿Qué es una rama?
Una rama de Git es un puntero móvil a un commit concreto. Permite divergir de la línea principal de desarrollo y trabajar en funcionalidades aisladas.
Conceptos fundamentales
HEAD
HEAD es un puntero al commit actual (generalmente el último commit de la rama actual).
Rama por defecto
- Históricamente:
master - Actualmente:
main - Configurable según tus preferencias
Gestión de ramas
Listar las ramas
# Ramas locales
git branch
# Todas las ramas (locales y remotas)
git branch -a
# Solo ramas remotas
git branch -r
# Con información detallada
git branch -v
Crear una rama
# Crear una nueva rama
git branch nouvelle-fonctionnalite
# Crear y cambiar a la nueva rama
git checkout -b nouvelle-fonctionnalite
# Con Git 2.23+ (recomendado)
git switch -c nouvelle-fonctionnalite
# Crear una rama desde un commit concreto
git branch nouvelle-branche abc1234
Cambiar entre ramas
# Método tradicional
git checkout nom-branche
# Método moderno (Git 2.23+)
git switch nom-branche
# Volver a la rama anterior
git switch -
# Cambiar creando la rama si no existe
git switch -c nouvelle-branche
Renombrar una rama
# Renombrar la rama actual
git branch -m nouveau-nom
# Renombrar otra rama
git branch -m ancien-nom nouveau-nom
Eliminar una rama
# Eliminar una rama fusionada
git branch -d nom-branche
# Forzar la eliminación (incluso si no está fusionada)
git branch -D nom-branche
# Eliminar una rama remota
git push origin --delete nom-branche
Flujo de trabajo con ramas
Ejemplo práctico: desarrollo de una funcionalidad
# 1. Partir de la rama principal
git switch main
git pull origin main
# 2. Crear una rama para la funcionalidad
git switch -c feature/login-system
# 3. Desarrollar la funcionalidad
echo "function login() { /* code */ }" > login.js
git add login.js
git commit -m "feat: add basic login function"
# 4. Continuar el desarrollo
echo "function logout() { /* code */ }" >> login.js
git add login.js
git commit -m "feat: add logout function"
# 5. Volver a main para la fusión
git switch main
Tipos de fusión (Merge)
Fast-Forward Merge
Cuando la rama principal no ha evolucionado:
git merge feature/login-system
Three-Way Merge
Cuando ambas ramas han evolucionado:
git merge feature/login-system
Merge con mensaje personalizado
git merge feature/login-system -m "Merge login system feature"
No-Fast-Forward Merge
Forzar la creación de un commit de merge:
git merge --no-ff feature/login-system
Rebase: alternativa al merge
El rebase reescribe el historial moviendo los commits:
# Rebasar la rama actual sobre main
git rebase main
# Rebase interactivo para modificar el historial
git rebase -i HEAD~3
Diferencia entre Merge y Rebase
Merge:
- Conserva el historial exacto
- Crea commits de fusión
- Historial más complejo pero completo
Rebase:
- Historial lineal y limpio
- Reescribe el historial
- Puede complicar la colaboración
Resolución de conflictos
¿Qué es un conflicto?
Un conflicto se produce cuando Git no puede fusionar automáticamente las modificaciones.
Ejemplo de conflicto
# Archivo con conflicto
<<<<<<< HEAD
function greet() {
return "Hello World!";
}
=======
function greet() {
return "Bonjour le monde!";
}
>>>>>>> feature/french-translation
Resolver un conflicto
# 1. Identificar los archivos en conflicto
git status
# 2. Editar los archivos para resolver los conflictos
# Eliminar los marcadores <<<<<<<, =======, >>>>>>>
# Conservar el código deseado
# 3. Marcar como resuelto
git add fichier-resolu.js
# 4. Finalizar la fusión
git commit
Herramientas para resolver conflictos
# Configurar una herramienta de merge
git config --global merge.tool vimdiff
# Lanzar la herramienta de resolución
git mergetool
# Cancelar una fusión en curso
git merge --abort
Estrategias de ramas
Git Flow
Flujo de trabajo estructurado con ramas especializadas:
main: código de produccióndevelop: integración de las funcionalidadesfeature/*: nuevas funcionalidadesrelease/*: preparación de las versioneshotfix/*: correcciones urgentes
# Ejemplo de Git Flow
git switch develop
git switch -c feature/user-profile
# ... desarrollo ...
git switch develop
git merge feature/user-profile
GitHub Flow
Flujo de trabajo simplificado:
main: código de producciónfeature/*: todas las modificaciones
# Ejemplo de GitHub Flow
git switch main
git switch -c feature/new-header
# ... desarrollo ...
git push origin feature/new-header
# ... Pull Request en GitHub ...
Trunk-Based Development
Desarrollo directamente sobre la rama principal con ramas de corta duración.
Comandos avanzados
Cherry-pick
Aplicar un commit concreto de otra rama:
# Aplicar un commit concreto
git cherry-pick abc1234
# Aplicar varios commits
git cherry-pick abc1234 def5678
Stash con ramas
# Guardar las modificaciones
git stash
# Cambiar de rama
git switch autre-branche
# Aplicar el stash en la nueva rama
git stash pop
Comparar ramas
# Ver las diferencias entre ramas
git diff main..feature/login
# Ver los commits exclusivos de una rama
git log main..feature/login
# Ver los archivos modificados
git diff --name-only main..feature/login
Ejercicios prácticos
Ejercicio 1: flujo de trabajo básico con ramas
# 1. Inicializar un proyecto
mkdir git-branches-demo
cd git-branches-demo
git init
echo "# Projet Demo" > README.md
git add README.md
git commit -m "Initial commit"
# 2. Crear una rama feature
git switch -c feature/add-calculator
echo "function add(a, b) { return a + b; }" > calculator.js
git add calculator.js
git commit -m "feat: add calculator function"
# 3. Volver a main y crear otra rama
git switch main
git switch -c feature/add-styles
echo "body { font-family: Arial; }" > styles.css
git add styles.css
git commit -m "style: add basic styles"
# 4. Fusionar las ramas
git switch main
git merge feature/add-calculator
git merge feature/add-styles
# 5. Limpiar
git branch -d feature/add-calculator
git branch -d feature/add-styles
Ejercicio 2: gestión de conflictos
# 1. Crear un conflicto intencionado
git switch main
echo "Version main" > conflict.txt
git add conflict.txt
git commit -m "Add conflict file from main"
git switch -c feature/conflict-test
echo "Version feature" > conflict.txt
git add conflict.txt
git commit -m "Modify conflict file from feature"
# 2. Intentar la fusión (se espera un conflicto)
git switch main
git merge feature/conflict-test
# 3. Resolver el conflicto
# Editar conflict.txt para resolverlo
echo "Version fusionnée" > conflict.txt
git add conflict.txt
git commit -m "Resolve conflict"
Ejercicio 3: Rebase vs Merge
# Preparar el entorno
git switch main
echo "Line 1" > file.txt
git add file.txt
git commit -m "Add line 1"
# Rama con merge
git switch -c branch-merge
echo "Line 2 from merge" >> file.txt
git add file.txt
git commit -m "Add line 2 via merge"
git switch main
echo "Line 3 from main" >> file.txt
git add file.txt
git commit -m "Add line 3 from main"
git merge branch-merge
# Rama con rebase
git switch -c branch-rebase
echo "Line 4 from rebase" >> file.txt
git add file.txt
git commit -m "Add line 4 via rebase"
git switch main
echo "Line 5 from main" >> file.txt
git add file.txt
git commit -m "Add line 5 from main"
git switch branch-rebase
git rebase main
git switch main
git merge branch-rebase
# Comparar los historiales
git log --oneline --graph
Buenas prácticas
Nomenclatura de las ramas
# Convenciones habituales
feature/user-authentication
bugfix/login-error
hotfix/security-patch
release/v1.2.0
experiment/new-algorithm
Flujo de trabajo recomendado
-
Parte siempre de un main actualizado
git switch main git pull origin main -
Crea ramas cortas y centradas
git switch -c feature/specific-task -
Commits frecuentes y atómicos
git commit -m "feat: add specific functionality" -
Prueba antes de fusionar
# Tests, linting, etc. -
Limpia después de la fusión
git branch -d feature/completed-task
Evitar los errores más comunes
- No desarrolles directamente en main
- Comprueba siempre la rama actual
- Resuelve los conflictos con atención
- No fuerces el push después de un rebase
- Comunica los rebase al equipo
Herramientas e interfaces
Herramientas de línea de comandos
# Ver el árbol de ramas
git log --oneline --graph --all
# Alias útil
git config --global alias.tree 'log --oneline --graph --all'
Herramientas gráficas
- GitKraken: excelente visualización de las ramas
- SourceTree: interfaz completa
- VS Code: extensión Git Graph
- GitHub Desktop: sencillo y eficaz
Solución de problemas
Rama desacoplada (Detached HEAD)
# Si estás en HEAD desacoplado
git switch -c nouvelle-branche-sauvegarde
git switch main
Deshacer una fusión
# Deshacer el último merge
git reset --hard HEAD~1
# O si el merge aún no se ha confirmado
git merge --abort
Recuperar una rama eliminada
# Encontrar el commit de la rama eliminada
git reflog
# Recrear la rama
git branch branche-recuperee abc1234
Recursos adicionales
Documentación
Herramientas interactivas
Conclusión
Dominar las ramas y la fusión es esencial para desarrollar de forma eficaz con Git. Estos conceptos te permiten trabajar en paralelo, experimentar sin riesgo y mantener un historial limpio.
En el próximo tutorial descubriremos GitHub, la plataforma que ha revolucionado la colaboración en torno a Git.
Tiempo de lectura estimado: 30 minutos
Nivel: Intermedio
Etapa anterior: Comandos esenciales de Git
Siguiente etapa: Introducción a GitHub