---
name: git-worktrees-paralelo
description: Uso de git worktrees para ejecución paralela de agentes. Crear, usar y limpiar worktrees de forma segura para que múltiples agentes trabajen sin conflictos.
version: "1.0.0"
herramientasPermitidas: [Read, Bash]
evolvable: true  # default para skill estandar
exclusiones:
  - "No cargar para trabajo secuencial de un solo agente — un checkout normal es suficiente; los worktrees añaden complejidad sin beneficio."
  - "No cargar para gestión de ramas sin paralelismo real (feature branching estándar) — para flujo de ramas estándar seguir la regla `git-workflow.md`."
  - "No cargar para repositorios monorepo con submódulos Git — los worktrees en repos con submódulos tienen comportamiento inconsistente; usar contenedores o directorios de trabajo separados."
  - "No cargar para tareas que requieren estado compartido entre agentes (mismo archivo modificado simultáneamente) — los worktrees aíslan pero no resuelven conflictos de edición concurrente."
---
# Git Worktrees para Ejecución Paralela

## Cuándo NO cargar

- Solo hay un agente trabajando en el repo: un checkout normal es suficiente.
- La tarea es feature branching secuencial sin paralelismo real: seguir `git-workflow.md`.
- El repo tiene submódulos Git: los worktrees con submódulos tienen comportamiento inconsistente.
- Los agentes paralelos modificarían los mismos archivos simultáneamente: los worktrees aíslan ramas pero no resuelven conflictos de edición concurrente.

## Qué es un worktree

Un **git worktree** permite tener múltiples directorios de trabajo conectados al mismo
repositorio. Cada worktree tiene su propio árbol de trabajo y puede estar en una rama
distinta, pero comparten el objeto store de Git (commits, blobs, trees). Esto es ideal
para agentes paralelos: cada uno trabaja en su propia rama y su propio directorio sin
interferir con los demás.

---

## Cuándo usar worktrees

- Múltiples agentes ejecutando tareas en paralelo sobre el mismo repo.
- Trabajar en un hotfix mientras el desarrollo principal sigue en `main`.
- Revisar el código de una rama sin perder el contexto de la rama actual.
- Ejecutar la suite de tests de una rama sin hacer checkout.
- Comparar implementaciones de dos ramas side-by-side.

**No usar worktrees cuando:**
- Solo hay un agente trabajando. Un checkout normal es suficiente.
- Las tareas tienen dependencias de orden entre sí.

---

## Comandos esenciales

### Crear un worktree

```bash
# Sintaxis básica
git worktree add <ruta> <rama>

# Crear worktree en rama existente
git worktree add ../mi-proyecto-feature feature/login

# Crear worktree con nueva rama desde HEAD
git worktree add -b feature/nueva-ruta ../mi-proyecto-nueva-ruta

# Crear worktree con nueva rama desde commit específico
git worktree add -b hotfix/auth ../mi-proyecto-hotfix origin/main
```

### Listar worktrees activos

```bash
git worktree list
# Salida:
# /ruta/repo-principal     abc1234 [main]
# /ruta/repo-feature       def5678 [feature/login]
# /ruta/repo-hotfix        ghi9012 [hotfix/auth]
```

### Eliminar un worktree

```bash
# Primero quitar el directorio, luego limpiar la referencia
git worktree remove ../mi-proyecto-feature

# Forzar si el directorio tiene cambios sin commitear (cuidado)
git worktree remove --force ../mi-proyecto-feature

# Limpiar referencias a worktrees eliminados manualmente
git worktree prune
```

### Mover un worktree

```bash
git worktree move ../mi-proyecto-feature ../nueva-ubicacion
```

---

## Patrón de trabajo para agentes paralelos

### Estructura de directorios recomendada

```
proyectos/
├── mi-app/              # Worktree principal (main)
├── mi-app-agente-1/     # Worktree para Agente 1 (feature/modulo-a)
├── mi-app-agente-2/     # Worktree para Agente 2 (feature/modulo-b)
└── mi-app-agente-3/     # Worktree para Agente 3 (feature/modulo-c)
```

### Flujo completo: lanzar agentes paralelos

```bash
# 1. Asegurarse de estar en main actualizado
cd /ruta/mi-app
git checkout main
git pull origin main

# 2. Crear worktrees para cada agente
git worktree add -b feature/modulo-usuarios ../mi-app-agente-1
git worktree add -b feature/modulo-reportes ../mi-app-agente-2
git worktree add -b feature/modulo-notificaciones ../mi-app-agente-3

# 3. Cada agente trabaja en su propio directorio
# Agente 1 → cd ../mi-app-agente-1
# Agente 2 → cd ../mi-app-agente-2
# Agente 3 → cd ../mi-app-agente-3

# 4. Los agentes hacen commits normalmente dentro de su worktree
cd ../mi-app-agente-1
git add .
git commit -m "feat(usuarios): implementa CRUD de usuarios"

# 5. Al terminar, crear PRs o mergear
cd /ruta/mi-app
git merge feature/modulo-usuarios

# 6. Limpiar worktrees terminados
git worktree remove ../mi-app-agente-1
git worktree remove ../mi-app-agente-2
git worktree remove ../mi-app-agente-3
git worktree prune
```

---

## Reglas de seguridad para worktrees paralelos

### La misma rama NO puede estar en dos worktrees

Git prohíbe hacer checkout de la misma rama en dos worktrees. Si se intenta:

```bash
git worktree add ../copia-main main
# fatal: 'main' is already checked out at '/ruta/repo-principal'
```

Solución: cada agente SIEMPRE trabaja en su propia rama, nunca en la misma.

### Archivos de bloqueo compartidos

Los hooks de Git se ejecutan desde el directorio `.git` compartido. Si dos agentes
ejecutan hooks simultáneamente puede haber condiciones de carrera. Usar ramas
completamente independientes minimiza este riesgo.

### Variables de entorno por worktree

Cada proceso de agente debe tener `GIT_DIR` implícito resuelto desde su CWD, no
configurado manualmente. Nunca exportar `GIT_DIR` de forma global si hay múltiples
worktrees activos.

---

## Integración con agentes del sistema SWL

### Estado en ESTADO.md por worktree

Cada agente debe registrar en su `ESTADO.md` local:

```markdown
## Worktree
- Ruta: /ruta/mi-app-agente-1
- Rama: feature/modulo-usuarios
- Worktree base: /ruta/mi-app (main @ abc1234)
- Creado: 2026-03-25T10:00:00
```

### Protocolo de limpieza

El agente coordinador (orquestador) es responsable de:
1. Crear los worktrees ANTES de lanzar los agentes.
2. Verificar que cada agente terminó (commit final presente).
3. Mergear las ramas al trunk.
4. Eliminar los worktrees con `git worktree remove`.
5. Borrar las ramas de feature si ya fueron mergeadas.

### Script de limpieza completa

```bash
#!/usr/bin/env bash
# cleanup-worktrees.sh
set -euo pipefail

REPO_ROOT="/ruta/mi-app"
cd "$REPO_ROOT"

echo "Worktrees activos:"
git worktree list

echo "Limpiando worktrees terminados..."
git worktree prune

echo "Estado final:"
git worktree list
```

---

## Troubleshooting común

### El worktree quedó en estado corrupto

```bash
# Verificar integridad
git fsck

# Si el directorio ya no existe pero el worktree está registrado
git worktree prune --verbose
```

### Conflicto al intentar hacer checkout en el worktree principal

```bash
# Ver en qué worktree está cada rama
git worktree list --porcelain

# Ir al worktree donde está la rama y hacer el trabajo ahí
cd /ruta/worktree-con-esa-rama
```

### Cambios sin commitear en un worktree al intentar eliminarlo

```bash
# Opción 1: Commitear antes
cd ../mi-app-agente-1
git stash  # o git commit

# Opción 2: Forzar eliminación (se pierden cambios)
cd /ruta/mi-app
git worktree remove --force ../mi-app-agente-1
```

---

## Resumen de comandos

| Comando | Acción |
|---------|--------|
| `git worktree add <ruta> <rama>` | Crear worktree en rama existente |
| `git worktree add -b <rama> <ruta>` | Crear worktree con rama nueva |
| `git worktree list` | Listar todos los worktrees |
| `git worktree remove <ruta>` | Eliminar worktree limpiamente |
| `git worktree prune` | Limpiar referencias obsoletas |
| `git worktree move <src> <dst>` | Mover worktree a nueva ruta |

## Gotchas / Errores comunes no obvios

**`git worktree add` falla con "fatal: already checked out" aunque la rama aparezca como no activa en `git branch`**: si un worktree anterior fue eliminado manualmente (borrando el directorio sin `git worktree remove`), Git mantiene la referencia del worktree en `.git/worktrees/` y cree que la rama sigue en uso. Causa: Git no detecta automáticamente que el directorio del worktree desapareció. Fix: ejecutar `git worktree prune` primero para limpiar referencias obsoletas, luego volver a intentar el `add`.

**Las hooks de Git (pre-commit, pre-push) se ejecutan desde `.git/hooks/` compartido entre todos los worktrees y pueden fallar si usan rutas relativas al directorio del worktree principal**: los hooks que asumen que `$PWD` es el directorio raíz del repositorio principal fallan cuando se ejecutan desde un worktree secundario porque `$PWD` apunta al directorio del worktree hijo. Causa: los hooks no tienen acceso automático al worktree actual — solo a `$GIT_DIR` y `$GIT_WORK_TREE`. Fix: en los hooks, usar `git rev-parse --show-toplevel` para obtener el directorio del worktree actual en lugar de rutas hardcodeadas, y `git rev-parse --git-common-dir` para encontrar el `.git` compartido.

**`git stash` en un worktree guarda el stash en el stash global del repositorio compartido, no en el worktree**: si el Agente 1 hace `git stash` en `mi-app-agente-1/` y luego el Agente 2 hace `git stash pop` en `mi-app-agente-2/`, aplica el stash del Agente 1 en la rama incorrecta. Causa: el stash de Git es una referencia global en `.git/refs/stash`, no por worktree. Fix: NUNCA usar `git stash` en flujos con múltiples worktrees. En su lugar, hacer un commit temporal con mensaje `WIP:` y usar `git reset HEAD~1` para deshacer cuando se necesite.

**Eliminar un worktree con `git worktree remove --force` mientras hay un agente activo escribiendo archivos en ese directorio produce corrupción del objeto store de Git**: si el agente tiene archivos en proceso de escritura (commit parcial, `git add` pendiente) y otro proceso ejecuta `remove --force`, Git puede quedar con objetos huérfanos o referencias rotas. Causa: `--force` no verifica si hay procesos con file handles abiertos en el worktree. Fix: el orquestador debe verificar que cada agente emitió su commit final antes de ejecutar `git worktree remove`. Usar `git worktree list --porcelain` para confirmar que la rama del worktree tiene el commit esperado.
