Worktrees
Un worktree es una segunda carpeta del mismo repo, con su propia rama. Sirve para que dos sesiones trabajen a la vez sin pisarse. El precio es que nace sin nada de lo que git ignora, y que todo lo ignorado que se escriba adentro muere cuando se borra.
Qué es y cuándo conviene
git worktree add crea otra carpeta que comparte el mismo .git que
tu checkout. Cada carpeta tiene su rama y sus cambios sin commitear, así que una sesión
puede estar a mitad de una historia mientras otra arregla un bug en otra rama, y ninguna ve
el desorden de la otra.
Conviene cuando hay trabajo en paralelo: un worker supervisado por historia (cada worker de
/orca-orchestration trabaja en su propio worktree), un hotfix mientras una
feature está abierta, o un experimento que no quieres mezclar con lo que tienes en curso.
Para una tarea corta en la rama actual no hace falta.
Un worktree aparece de varias maneras: Orca lo crea para cada worker, Claude Code con
--worktree, la app de Codex con sus worktrees gestionados, o tú a mano con
git worktree add. La mecánica de git es la misma en todos los casos.
Qué le falta a un worktree nuevo
Un worktree recién creado tiene todo lo que git versiona y nada de lo que git ignora. Ese hueco nunca se presenta como lo que es: aparece disfrazado de otro problema.
| Falta | Cómo se nota |
|---|---|
.env |
En silencio: el loader de cada MCP no encuentra qué pasarle, el server arranca sin
valores y muere en su primera llamada autenticada (regla crítica 10 de
AGENTS.md).
|
node_modules/ |
Cannot find module, que parece un import roto. |
El alias .claude/skills |
En Claude Code, Unknown skill. OpenCode y Codex no lo necesitan. |
La caché de Jira (.context/PBI/) |
En silencio: el agente trabaja con el título del ticket y nada más. |
.session/ |
Los planes, el progreso y los handoffs no están. Y no se copian: se leen del checkout principal (ver Dos raíces). |
La tabla completa, con cómo se recupera cada fila, está en
.agents/skills/orca-orchestration/references/provisioning.md.
Prepararlo
bun run worktree:provision cierra los huecos reparables en una sola llamada:
copia desde el checkout principal los archivos ignorados que una sesión necesita
(.env, los ajustes del harness, .auth/, el spec de OpenAPI
sincronizado...), corre bun install y bun run agents:compat, que
crea el alias de skills. Sin argumento prepara la carpeta actual; con una ruta, esa ruta. Se
niega a correr sobre el checkout principal.
bun run worktree:provision # la carpeta actual
bun run worktree:provision /ruta/al/worktree # otra carpeta
bun run worktree:provision /ruta/al/wt --dry-run # muestra qué haría, sin tocar nada
Qué archivos copia lo dice .worktreeinclude, en la raíz del repo. Claude Code y
la app de Codex leen ese mismo archivo cuando crean sus propios worktrees, y un test
mantiene la lista igual a la del script. Si tu proyecto necesita otro archivo ignorado en
cada worktree, agrégalo debajo de las líneas que trae el boilerplate.
- En Orca, solo
-
orca.yamlestá versionado y declara dos hooks del repo:setupcorrebun run worktree:provisionen cada worktree nuevo yarchivecorrebun run worktree:audit --rescueantes de borrarlo. Nadie tiene que configurarlos en la app. - Credenciales
-
Cada MCP lee el
.envdel propio worktree a través de su loader, en cualquier harness y aunque el worker se lance sin terminal, así que basta con que el worktree tenga su.env. Después de cada cambio en.env, reinicia la sesión del agente, porque los MCPs lo leen al arrancar.
Dos raíces: el worktree y el checkout principal
Dentro de un worktree hay dos carpetas que importan, y el repo les da nombre con dos variables de sesión:
| Variable | Es | Se usa para |
|---|---|---|
<<REPO_ROOT>> |
Este checkout: el worktree, si hay uno. |
Lo versionado: código, skills, docs, configuración, los test-specs/.
|
<<PRIMARY_ROOT>> |
El checkout principal, el mismo valor desde cualquier worktree. |
El estado ignorado que tiene que sobrevivir: .session/ (planes,
progreso, handoffs), las carpetas evidence/ de la caché de Jira,
.context/reports/.
|
En el checkout principal las dos son la misma carpeta. En un worktree no, y por eso las
skills escriben y retoman su estado en <<PRIMARY_ROOT>> con ruta
absoluta. Una sesión que buscara su progress.md en el
.session/ del worktree no lo encontraría y volvería a empezar un trabajo que ya
estaba hecho. La definición está en .agents/README.md, sección "Checkout
roots".
Antes de borrarlo
Borrar un worktree (git worktree remove, la limpieza del harness, el borrado de
Orca) elimina todo lo ignorado que tenga adentro y termina con éxito. Nada te avisa que una
captura de evidencia o un reporte se fueron con él.
bun run worktree:audit lista lo que el worktree todavía guarda y git no, y lo
clasifica: estado (pertenece al checkout principal), caché (un comando lo reconstruye),
descartable (se puede perder) o desconocido (ninguna regla lo cubre: revísalo a mano). Con
--rescue copia el estado a la misma ruta en el checkout principal.
bun run worktree:audit # audita la carpeta actual, solo lectura
bun run worktree:audit --rescue # copia el estado al checkout principal
bun run worktree:audit --rescue --dry-run # muestra qué copiaría
bun run worktree:audit --json # para que lo lea un agente
-
--rescuenunca sobreescribe: si el archivo ya está en el principal con los mismos bytes cuenta como rescatado; con bytes distintos queda como conflicto para una persona. - Sale con 0 cuando no queda nada durable, con 1 cuando queda estado o algo desconocido, y con 2 si le pasas el checkout principal o algo que no es un checkout.
- Imprime rutas, nunca el contenido de los archivos.
El hook archive de orca.yaml corre cuando Orca borra el
worktree, y aunque falle Orca lo borra igual: por eso rescata en vez de solo avisar.
orca worktree rm se salta los hooks de archive salvo que le pases
--run-hooks.
El updater corre solo en el checkout principal
bun sync guarda dentro del checkout los backups que usa
--rollback, sus marcadores y los prompts de paridad. En un worktree todo eso se
perdería al borrarlo, y la siguiente corrida en el principal no vería nada. Por eso, en un
worktree, el updater se niega, te dice la ruta del checkout principal y sale sin tocar nada.
Trae las novedades del boilerplate desde el principal y después lleva los cambios a tus
ramas como cualquier otro commit.
Así lo hace este repo
| Pieza | Dónde vive |
|---|---|
| Qué falta en un worktree nuevo, fila por fila | .agents/skills/orca-orchestration/references/provisioning.md |
| Preparar un worktree |
bun run worktree:provision (scripts/provision-worktree.ts)
y la lista .worktreeinclude
|
| Auditar y rescatar antes de borrar |
bun run worktree:audit (scripts/worktree-audit.ts); las
clases salen de una sola tabla en cli/lib/worktree.ts
|
| Los hooks de Orca | orca.yaml |
| Las dos raíces | .agents/README.md, sección "Checkout roots" |
| Worktrees a mano, ciclo completo y reglas multi-sesión | .agents/skills/git-flow-master/references/worktrees.md |
Una regla vale con o sin worktrees: nunca un descarte global de git (git restore ., git reset --hard, un git stash sin rutas). Varias sesiones
pueden compartir un árbol, y un descarte global borra el trabajo sin commitear de otra sin
forma de recuperarlo (regla crítica 15 de AGENTS.md).