0%
Tutorial 4 de 10
40% completado

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.

mainfeature-bInitialFeature AFeature B-1Feature B-2HotfixRelease

Conceptos fundamentales

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
mainfeatureABCD

Three-Way Merge

Cuando ambas ramas han evolucionado:

git merge feature/login-system
mainfeatureABCDEMerge

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
mainfeatureABCDEC'D'

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ón
  • develop: integración de las funcionalidades
  • feature/*: nuevas funcionalidades
  • release/*: preparación de las versiones
  • hotfix/*: 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ón
  • feature/*: 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

  1. Parte siempre de un main actualizado

    git switch main
    git pull origin main
  2. Crea ramas cortas y centradas

    git switch -c feature/specific-task
  3. Commits frecuentes y atómicos

    git commit -m "feat: add specific functionality"
  4. Prueba antes de fusionar

    # Tests, linting, etc.
  5. Limpia después de la fusión

    git branch -d feature/completed-task

Evitar los errores más comunes

  1. No desarrolles directamente en main
  2. Comprueba siempre la rama actual
  3. Resuelve los conflictos con atención
  4. No fuerces el push después de un rebase
  5. 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