4. Branching y Merging
Las ramas son una de las características más poderosas de Git. Te permite crear una versión del código principal para trabajar en nuevas funcionalidades, corregir bugs o simplemente jugar, sin afectar el código original. Después, puedes descargar los cambios o incluir el nuevo código en la versión "oficial".
Imagina que tu proyecto es un árbol:
- La rama principal (normalmente llamada
mainomaster), que es el tronco del árbol. - Las ramas de desarrollo (o nuevas características), que son las ramas que salen del tronco.
Cada rama puede evolucionar de forma independiente, incluso crearse otras ramas a partir de ellas. Si un cambio es interesante y aporta valor, se puede unir los nuevos cambios al tronco.
De esta manera puedes:
- Trabajar en nuevas funcionalidades sin romper el código estable.
- Múltiples personas pueden trabajar en paralelo con la misma base de código.
- Experimentar con ideas sin consecuencias. Al borrar una rama, todo lo que hiciste en ella desaparece sin consecuencias.
Para gestionar las ramas usaremos los siguientes comandos:
# Ver todas las ramas
git branch
# Ver todas las ramas (incluyendo remotas)
git branch -a
# Crear una nueva rama
git branch nueva-funcionalidad
# Crear y cambiar a una rama
git branch -c mi-rama
# Eliminar una rama
git branch -d nombre-rama
# Eliminar una rama forzosamente
git branch -D nombre-rama
# Renombrar una rama
git branch -m viejo-nombre nuevo-nombre
git checkout
Cambia entre ramas o restaura archivos.
# Cambiar a una rama existente
git checkout main
# Crear una rama y cambiar a ella
git checkout -b nueva-rama
# Cambiar a un commit específico
git checkout abc1234
# Restaurar un archivo del último commit
git checkout -- archivo.txt
git switch
Un comando más moderno y específico para cambiar ramas (desde Git 2.23).
# Cambiar a una rama
git switch main
# Crear y cambiar a una nueva rama
git switch -c nueva-funcionalidad
# Volver a la rama anterior
git switch -
Recomendación: Usa git switch para cambiar ramas y git checkout para operaciones con archivos.
Flujo de trabajo con ramas
# 1. Crear una rama para tu funcionalidad
git switch -c feature/login
# 2. Hacer cambios
echo "Login component" > login.js
git add login.js
git commit -m "Añade componente de login"
# 3. Hacer más commits según necesites
echo "Tests" > login.test.js
git add login.test.js
git commit -m "Añade tests para login"
# 4. Volver a main
git switch main
# 5. Fusionar tu rama
git merge feature/login
git merge
Fusiona una rama en la rama actual.
# Fusionar una rama
git merge nombre-rama
# Fusionar sin fast-forward (crea un commit de merge)
git merge --no-ff nombre-rama
# Abortar un merge
git merge --abort
Tipos de merge:
Fast-forward: Cuando no hay nuevos commits en la rama base.
main: A---B
\
feature: C---D
Después del merge:
main: A---B---C---D
Three-way merge: Cuando hay cambios en ambas ramas.
main: A---B---E---F
\
feature: C---D
Después del merge:
main: A---B---E---F---M
\ /
feature: C-------D
Resolución de conflictos
Un conflicto ocurre cuando dos ramas modifican las mismas líneas de código.
Ejemplo de conflicto:
# En rama main
echo "Versión main" > archivo.txt
git add archivo.txt
git commit -m "Actualiza en main"
# Crear y cambiar a nueva rama desde un commit anterior
git switch -c feature
echo "Versión feature" > archivo.txt
git add archivo.txt
git commit -m "Actualiza en feature"
# Intentar fusionar
git switch main
git merge feature
# ¡Conflicto!
Git marcará el conflicto en el archivo:
<<<<<<< HEAD
Versión main
=======
Versión feature
>>>>>>> feature
Resolver el conflicto:
- Abre el archivo y decide qué versión conservar
- Elimina las marcas de conflicto (
<<<<<<<,=======,>>>>>>>) - Guarda el archivo
- Añádelo al staging:
git add archivo.txt - Completa el merge:
git commit
Herramientas para resolver conflictos:
# Ver archivos con conflictos
git status
# Usar una herramienta de merge visual
git mergetool
# Aceptar todos los cambios de una rama
git checkout --theirs archivo.txt # Rama que estás fusionando
git checkout --ours archivo.txt # Rama actual
Estrategias de branching
Feature Branch (Rama por funcionalidad)
La estrategia más simple: una rama por cada funcionalidad.
main
├── feature/login
├── feature/dashboard
└── bugfix/header-typo
# Crear rama de funcionalidad
git switch -c feature/nueva-funcionalidad
# Desarrollar
git add .
git commit -m "Implementa funcionalidad"
# Fusionar cuando esté lista
git switch main
git merge feature/nueva-funcionalidad
Actividad 1
- Crea una rama llamada
feature/nueva-pagina. - En esa rama, crea un archivo
pagina.htmlcon contenido HTML básico. - Haz commit de los cambios.
- Vuelve a la rama
main. - Fusiona la rama
feature/nueva-paginaenmain. - Elimina la rama
feature/nueva-pagina.
Actividad 2
Práctica de conflictos:
- En la rama
main, edita la primera línea deREADME.md. - Haz commit.
- Crea una rama
conflicto-testdesde un commit anterior. - Edita la misma línea del README con texto diferente.
- Haz commit.
- Intenta fusionar
conflicto-testenmain. - Resuelve el conflicto manualmente.
- Completa el merge.
This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.