junio 2026 · git · agentes · 6 min

¿Worktrees o clones?

Cuando compartí mi workflow de agentes autónomos, esta fue la pregunta que más se repitió: "¿por qué clones reales y no git worktrees?". Respuesta corta: con un agente, worktrees andan. Con varios agentes autónomos en paralelo, se rompen — y se rompen feo.

Ilustración en tinta: de un árbol madre bajo campana de vidrio, un jardinero toma esquejes y los planta en macetas separadas atendidas por pequeños robots; al fondo, varios jardineros forcejean con un solo árbol enredado

El día que entendí el problema

Arranqué como cualquiera: git worktree add por tarea. Liviano, rápido, sin duplicar el repo. Hasta que empecé a correr varios agentes a la vez y aparecieron archivos corruptos y cruces de rama que no podía explicar. El problema de fondo no era ningún bug exótico: los worktrees comparten el mismo .git. Todo lo que un agente hace sobre ese estado compartido les pasa a todos.

  • Un agente que se manda un git gc --prune, un reset --hard, un branch -D o reescribe historia puede afectar a todos los worktrees a la vez.
  • Git no permite la misma rama checkouteada en dos worktrees. Suena menor, pero cuando dos agentes autónomos deciden trabajar sobre la misma base, los casos borde son feos: uno de los dos arranca en un estado que no esperaba.
  • Config y hooks se heredan del padre. Un agente que toca .git/config o instala un hook afecta a todos los demás.

Con un solo agente, nada de esto duele: vos coordinás. Con agentes autónomos, nadie coordina — la estructura tiene que hacerlo.

La salida: clones reales desde un mirror bare

La objeción obvia a los clones es el costo: clonar un repo grande por cada tarea es lento. La pieza que lo arregla es un mirror bare local: clonás una vez del remoto, y después cada tarea clona del mirror — local, instantáneo, sin red.

# una vez por repo: el mirror local
git clone --mirror git@github.com:org/web.git ~/.mirrors/web.git

# por cada tarea: clon real desde el mirror (instantáneo)
git clone ~/.mirrors/web.git tasks/checkout-v2/web
cd tasks/checkout-v2/web
git checkout -b checkout-v2 origin/staging

# refrescar el mirror cuando haga falta
git --git-dir ~/.mirrors/web.git fetch --prune

Cada tarea queda 100% aislada: archivos, ramas, config y hooks propios. Una macana solo rompe su tarea. Y como cada clon tiene su .git, le instalo a cada uno un hook anti-push a staging/main sin ensuciar a los demás — el agente trabaja libre en su rama, lo importante queda protegido.

La capa fina de helpers

Nada de framework pesado: bash + git. Un comando (task-new) que en una pasada: clona del mirror, ramea desde la base, hace el pull/render del env, asigna un bloque de puertos propio (para que dos agentes no se pisen ni los puertos), instala el hook y crea la carpeta de reportes E2E. El teardown (task-rm) aborta si hay cambios sin commitear — nunca tirás trabajo por accidente.

Cuándo los worktrees siguen ganando

No es dogma. Para un fix rápido en un solo repo, con un solo agente (o vos solo), un worktree sigue siendo la herramienta correcta: más liviano, más rápido de crear, y el riesgo de cruce no existe porque no hay concurrencia. Yo mantengo las dos cosas: worktrees para fixes puntuales, clones aislados para features con agentes corriendo en paralelo.

La regla que me quedó: el aislamiento no es para vos — es para que dos procesos autónomos nunca tengan que coordinar a través de estado compartido.

El patrón completo — workspaces, puertos, loop de E2E auto-correctivo — está explicado interactivo en ship.alonsogrimaldo.com.