Git worktrees para agentes: tareas en paralelo sin pisarse
Un git worktree es un segundo directorio de trabajo del mismo repositorio, con sus propios archivos y su propia rama, pero con el historial compartido. Si le das a cada agente de código su worktree, dos sesiones pueden editar el proyecto a la vez sin sobrescribirse los cambios, y tú revisas y fusionas cada rama por separado.
Por qué dos agentes en la misma carpeta se pisan
Si abres dos sesiones de agente en el mismo directorio, las dos escriben sobre los mismos archivos, el mismo índice de git y la misma rama. No hay ningún bloqueo que lo impida: el último en escribir gana, y el otro agente sigue razonando sobre un archivo que ya no es el que leyó.
Supongamos que le pides a un agente que añada autenticación y, en otra terminal, a un segundo agente que corrija un bug en el mismo módulo. Lo esperable es que uno de los dos lance los tests con código a medio escribir por el otro, vea fallos que no ha causado él e intente "arreglarlos". Además, cuando quieras hacer commit, los cambios de ambas tareas estarán mezclados en un único git status y separarlos te tocará a mano.
La solución no es turnarte entre sesiones, sino darle a cada una su propio directorio. Eso es exactamente lo que hace un worktree, y Claude Code, Codex y Cursor ya lo usan por debajo para sus sesiones paralelas.
Qué comparte un worktree y qué no
Un worktree aísla archivos, HEAD e índice; comparte ramas, etiquetas y configuración. Esta tabla, basada en la documentación oficial de git worktree y en la página de worktrees de Claude Code, resume lo que te afecta como junior:
| Elemento | ¿Compartido? | Consecuencia práctica |
|---|---|---|
| Archivos del directorio de trabajo | No | Cada agente edita su copia sin tocar la tuya. |
HEAD e índice (staging) | No | Cada worktree tiene sus propios commits pendientes. |
Ramas y etiquetas (refs/) | Sí | Desde tu checkout principal ves la rama del agente sin hacer fetch. |
| Config del repositorio | Sí, por defecto | Un cambio en .git/config afecta a todos. |
Archivos ignorados (.env, node_modules) | No existen | El worktree nace sin ellos; hay que copiarlos o instalarlos. |
| Puertos, bases de datos locales, contenedores | Sí | Git no los aísla; dos servidores en el mismo puerto chocan. |
Hay una regla de git que conviene memorizar: por defecto, git worktree add se niega a usar una rama que ya está activa en otro worktree. Es una protección, no un error que haya que esquivar con --force.
Paso 1: prepara el repositorio antes del primer worktree
Necesitas un repositorio con al menos un commit y la carpeta de worktrees ignorada. Según la guía de flujos comunes de Claude Code, en un repositorio sin commits el comando falla con Failed to resolve base branch "HEAD".
Estos comandos añaden la carpeta al .gitignore y hacen commit para que los worktrees no aparezcan como archivos sin seguimiento en tu checkout principal:
echo ".claude/worktrees/" >> .gitignore
git add .gitignore
git commit -m "Ignora worktrees de Claude Code"Otro requisito: la documentación indica que las ejecuciones interactivas con --worktree exigen haber aceptado antes el diálogo de confianza del directorio. Si nunca has abierto claude en ese repo, ábrelo una vez y acéptalo.
Paso 2: lanza cada tarea con claude --worktree
Un comando por terminal y un nombre por tarea es todo lo que necesitas. Según la documentación de worktrees, claude --worktree <nombre> (o -w) crea el directorio en .claude/worktrees/<nombre>/ y una rama nueva llamada worktree-<nombre>:
# Terminal 1
claude --worktree feature-auth
# Terminal 2
claude --worktree fix-paginacion
# Revisar una PR concreta en su propio worktree (comillas por el #)
claude --worktree "#1234"Si omites el nombre, Claude Code genera uno aleatorio. Pon siempre uno descriptivo: dentro de una hora tendrás que saber qué rama es cuál.
Desde qué commit arranca cada worktree
Por defecto ("fresh"), el worktree parte de la rama por defecto del remoto, normalmente main, no de la rama en la que estás. La documentación detalla que, si el repo no se ha actualizado en 24 horas, Claude Code hace un fetch de esa rama con un límite de cinco segundos. Si lo que quieres es que el agente trabaje sobre tus commits locales sin subir, cambia la base en .claude/settings.json:
{
"worktree": {
"baseRef": "head"
}
}No acepta nombres de rama. Para arrancar desde una rama existente concreta, crea el worktree con git a mano (git worktree add ../proyecto-bugfix mi-rama) y abre claude dentro.
Paso 3: dale al worktree tu .env y tus dependencias
Un worktree es un checkout limpio: sin .env, sin node_modules, sin entorno virtual. Si no lo resuelves, lo esperable es que el agente pierda turnos peleándose con errores de configuración que en tu carpeta principal no existen.
Para los archivos ignorados, crea un .worktreeinclude en la raíz del proyecto. Usa sintaxis de .gitignore y, según la documentación, solo copia archivos que coincidan con un patrón y estén ignorados por git, así que nunca duplica archivos versionados:
.env
.env.local
config/secrets.jsonLas dependencias no se copian: hay que instalarlas. Puedes pedírselo al agente como primera instrucción o hacerlo tú. Por ejemplo, en un proyecto con npm:
cd .claude/worktrees/feature-auth
npm ci
npm test # comprueba que el punto de partida está en verdeEse npm test inicial importa más de lo que parece: si la base ya falla, el agente no puede distinguir sus errores de los heredados.
Tres detalles que se comparten sin que lo esperes
- Permisos: la documentación indica que, desde la v2.1.211, responder "Yes, and don't ask again" a un comando en un worktree guarda la regla en el
.claude/settings.local.jsondel checkout principal, y se aplica a todos los worktrees. - Hooks:
${CLAUDE_PROJECT_DIR}sigue apuntando al checkout principal; si un hook necesita la ruta del worktree, debe leer el campocwdde su JSON de entrada. - Git LFS: si lo configuraste con
git lfs install --local, el worktree contendrá punteros; ejecutagit lfs pulldentro.
Paso 4: revisa cada rama como si fuera una PR ajena
Como las ramas se comparten, puedes revisar el trabajo de cada agente desde tu checkout principal sin entrar en su carpeta. Trata cada rama worktree-* como una PR de alguien que no conoces.
Estos comandos listan los worktrees activos, muestran los commits de la rama del agente y el resumen de archivos tocados respecto a main:
git worktree list
git log --oneline main..worktree-feature-auth
git diff --stat main...worktree-feature-auth
git diff main...worktree-feature-auth -- src/auth/Los tres puntos en main...rama comparan contra el ancestro común, así que ves solo lo que ha hecho el agente, aunque main haya avanzado mientras tanto. Ten en cuenta que esto solo muestra lo que el agente ha commiteado: lo que tenga sin commit sigue únicamente en su directorio.
Cuando la rama te convenza, fusiónala o, mejor, pídele al agente dentro de su sesión que abra una PR. Si dos agentes han tocado los mismos archivos, el conflicto aparecerá aquí, en la fusión, que es el sitio correcto: con contexto y con tiempo para resolverlo, no en mitad de una ejecución.
Paso 5: limpia sin borrar trabajo por accidente
Al salir de una sesión interactiva, Claude Code decide por ti solo si no hay nada que perder. Según la documentación, si el worktree está limpio y la sesión no tiene nombre, lo elimina junto con su rama; si tiene cambios, archivos sin seguimiento o commits nuevos, te pregunta si conservarlo o borrarlo. Borrar elimina también la rama y todo su trabajo, así que no pulses esa opción sin haber fusionado antes.
Las ejecuciones no interactivas con claude -p --worktree no tienen ese diálogo y no se limpian solas. Para esos casos, o para worktrees que creaste tú, esta es la secuencia de limpieza manual:
git worktree list
git worktree remove .claude/worktrees/feature-auth
# Si git responde que está bloqueado:
git worktree unlock .claude/worktrees/feature-auth
# Borra la rama solo si ya está fusionada (-d se niega si no lo está)
git branch -d worktree-feature-auth
# Limpia metadatos de worktrees cuya carpeta borraste a mano
git worktree pruneSegún la referencia de git, git worktree remove solo elimina worktrees limpios; con cambios pendientes exige --force. Usa git branch -d y no -D: la minúscula te protege de borrar una rama sin fusionar.
Lo mismo en Codex y Cursor
El concepto es idéntico en las tres herramientas; cambian la ubicación, el mecanismo de preparación y la política de limpieza. Si alternas herramientas, conviene saber dónde acaba cada worktree para no llenar el disco:
| Herramienta | Dónde crea el worktree | Cómo prepara el entorno | Limpieza automática |
|---|---|---|---|
| Claude Code | .claude/worktrees/<nombre>/, rama worktree-<nombre> | .worktreeinclude para archivos ignorados; dependencias a mano o por el agente | Al salir si está limpio; barrido periódico para subagentes y sesiones en segundo plano |
| Codex app | $CODEX_HOME/worktrees, en HEAD separado (detached) | Scripts de setup del entorno local elegido | Conserva los 15 más recientes por defecto, con snapshot antes de borrar |
| Cursor | Checkout separado por agente en el Agents Window | .cursor/worktrees.json con claves setup-worktree | Límite de 25 por máquina por defecto (cursor.worktreeMaxCount) |
En Codex el worktree arranca en HEAD separado para no ensuciar tus ramas, así que antes de fusionar tendrás que crear una rama o usar su función de "Hand off" hacia tu checkout local.
Cuándo no merece la pena usar worktrees
Los worktrees resuelven colisiones de archivos, no de diseño. No los uses por defecto en estos casos:
- Las dos tareas tocan los mismos archivos. Evitas pisarte durante la ejecución, pero pagas el conflicto entero al fusionar. Mejor hazlas en serie.
- La segunda tarea depende de la primera. Si el bug solo se puede arreglar sobre la nueva autenticación, un worktree en paralelo parte de una base que no la tiene.
- Tu app depende de recursos únicos. Un puerto fijo, una base de datos local o un contenedor con nombre fijo se comparten entre worktrees; dos agentes lanzando tests de integración pueden romperse el uno al otro.
- La tarea es de cinco minutos. Instalar dependencias en un worktree nuevo puede costar más que la tarea. Como referencia práctica, no como dato: si no vas a tener dos agentes trabajando a la vez durante un buen rato, una rama normal basta.
- Vas justo de disco. Cada worktree duplica los archivos del proyecto y, en proyectos con muchas dependencias, también su carpeta de dependencias.
Checklist antes de abrir el segundo agente
Copia esta lista en las notas de tu proyecto y repásala cada vez que vayas a paralelizar:
- El repo tiene al menos un commit y
.claude/worktrees/está en.gitignore. - Las dos tareas tocan zonas distintas del código y ninguna depende de la otra.
- Existe
.worktreeinclude(o su equivalente en tu herramienta) con los.envnecesarios. - Sabes desde qué base arranca el worktree:
mainremoto ("fresh") o tu HEAD local ("head"). - Cada worktree tiene un nombre que describe la tarea.
- La primera instrucción al agente incluye instalar dependencias y pasar los tests base.
- Ningún servidor o test de integración usa un puerto o una base de datos que el otro agente también use.
- Revisas cada rama con
git diff main...worktree-<nombre>antes de fusionar. - Limpias con
git worktree removeygit branch -d, nunca borrando la carpeta a mano singit worktree prunedespués.
Preguntas frecuentes
¿Puedo usar worktrees con un agente que no los gestiona de forma nativa?
Sí. Crea el worktree con git worktree add ../proyecto-tarea -b tarea, entra en esa carpeta y abre allí el agente que uses. Para él es un directorio de proyecto normal; la preparación del entorno y la limpieza corren de tu cuenta.
¿Y si quiero paralelizar dentro de una sola sesión?
En Claude Code puedes añadir isolation: worktree al frontmatter de un subagente personalizado para que cada invocación trabaje en un worktree temporal. Según la documentación, se elimina solo si el subagente termina sin cambios; si los hay, queda en disco hasta que el barrido periódico pueda borrarlo sin perder trabajo.
¿Qué pasa si reanudo una sesión que estaba en un worktree?
Claude Code la devuelve a ese worktree, tanto en modo interactivo como con --continue o --resume. Si borraste la carpeta, la sesión continúa en el directorio desde el que la lanzaste y te avisa de que el worktree ya no existe, así que ya no trabajará aislada.