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 main o master), 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:

  1. Abre el archivo y decide qué versión conservar
  2. Elimina las marcas de conflicto (<<<<<<<, =======, >>>>>>>)
  3. Guarda el archivo
  4. Añádelo al staging: git add archivo.txt
  5. 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
  1. Crea una rama llamada feature/nueva-pagina.
  2. En esa rama, crea un archivo pagina.html con contenido HTML básico.
  3. Haz commit de los cambios.
  4. Vuelve a la rama main.
  5. Fusiona la rama feature/nueva-pagina en main.
  6. Elimina la rama feature/nueva-pagina.
Actividad 2

Práctica de conflictos:

  1. En la rama main, edita la primera línea de README.md.
  2. Haz commit.
  3. Crea una rama conflicto-test desde un commit anterior.
  4. Edita la misma línea del README con texto diferente.
  5. Haz commit.
  6. Intenta fusionar conflicto-test en main.
  7. Resuelve el conflicto manualmente.
  8. Completa el merge.

This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.

Will you buy me a coffee?