Cómo cambió mi flujo en git cuando trabajo con agentes IA
git worktree fue una función de power user que ignoré por diez años. Correr agentes en paralelo la convirtió en el comando nativo de git que más uso. Acá está su flujo real.
Dioni
Updated:

Hoy en día ejecuto varios agentes al mismo tiempo sobre el mismo proyecto, no creo que sea el único, algunos arreglando bugs, otros construyendo distintas features, cada uno metido en su propio mundo... para mi así es como trabajo en el día a día.
El problema es que todos quieren escribir archivos al mismo tiempo y cuando eso pasa , ahi empiezan los dolores de cabeza con las colisiones en los archivos. No es el modelo ni la calidad del código el problema que nace inmediatamente... sino que todos comparten un solo directorio de trabajo, y apenas dos agentes tocan el repo en paralelo, empiezan a pisarse los cambios entre ellos.
La era agéntica cambió el workflow, y ante eso hemos tenido que adaptarnos, sobre todo el flujo de git, más de lo que uno habría esperado... Cuando hay más de un agente editando en distintas features, aislar el trabajo deja de ser un lujo y pasa a ser la condición para que nada se solape... lo que resuelve justo este problema ya lo teníamos en git desde hace mucho y acá explicó por que es importante y lo necesario de los worktree, ya que converso con colegas, miro sus flujos de trabajo de los devs y me sorprende que son pocos los que lo están adoptándolo como parte de su flujo.
Un git worktree te deja tener varios directorios de trabajo conectados al mismo repositorio: la misma historia, la misma base de objetos, una rama distinta en cada uno, todos al mismo tiempo.
Shirei, mi cockpit para correr agentes, es donde vivo este flujo todos los días. Ahora mismo tengo la rama feat/web-viewer-pane corriendo en su propia carpeta .worktrees/web-viewer-pane, justo al lado de mi checkout principal, que se mantiene limpio mientras un agente trabaja ahí.
Antes eso era un lujo prescindible. Con agentes hoy en día, se volvió el un must completamente.
Acá te muestro el flujo que uso y por qué creo que dejó de ser opcional.
Las ramas simplemente ya no bastan
Durante casi toda mi carrera, cambiar de contexto fue un problema resuelto. Estoy metido en una feature, entra un bug, hago git stash, cambio de rama, lo arreglo, vuelvo y hago git stash pop. Es torpe, pero funciona, porque hay un solo par de manos escribiendo código, un solo árbol de trabajo y una sola cosa pasando a la vez. El árbol nunca estaba en disputa, simplemente porque yo era el único parado encima.
Esta suposición se sostuvo por mucho tiempo. En esta nueva era, ya no.
Cuando corres un agente de IA, el árbol de trabajo pasa a tener un segundo ocupante: el agente lee tus archivos, ejecuta comandos y escribe cambios mientras lo miras o mientras te alejas a hacer otra cosa. Ahora imagina dos o más sobre dos tareas que no tienen nada que ver entre sí. Uno está agregando el web viewer pane, el otro arreglando el permiso de screencast en macOS (funcionalidades de Shirei que estoy desarrollando), ambos comparten el mismo set de archivos. El primer git checkout para cambiar de rama les saca el piso a los dos al mismo tiempo.
El problema es que un solo directorio de trabajo es un recurso compartido, sin darme cuenta había empezado a correr varios agentes concurrentes sobre él.
Qué es realmente un worktree ?
La mecánica es más simple de lo que sugiere su fama. Un repositorio tiene un worktree principal, el que te dio el git clone, y puede tener todos los worktrees enlazados que quieras. Todos comparten la misma base de objetos .git y las mismas referencias de ramas. Lo que cada worktree guarda solo para sí es poco pero decisivo: su propio HEAD, su propio index y sus propios archivos checkeados en disco, y por eso es importante hoy en día.
Déjame destripar esto… porque acá es donde se va toda duda, lo que sigue lo saqué de Shirei, corriendo un flujo de verdad sobre la rama feat/web-viewer-pane)
Lo primero que sorprende es que el .git dentro de un worktree no es una carpeta, es un archivo de una sola línea.
$ cat .worktrees/web-viewer-pane/.git
gitdir: project/shirei/.git/worktrees/web-viewer-paneEse puntero es todo lo que conecta al worktree con el repositorio real. El estado propio de cada worktree vive dentro del repo principal, en .git/worktrees/<nombre>/, y ahí está exactamente lo que NO se comparte.
$ ls .git/worktrees/web-viewer-pane/
HEAD ORIG_HEAD commondir gitdir index logs/ refs/HEAD e index son de ese worktree y de nadie más. El archivo commondir apunta de vuelta al .git compartido, donde viven los objetos y las ramas de verdad. Y no tienes que adivinar nada, git te lo dice directo.
$ git rev-parse --git-dir
project/shirei/.git/worktrees/web-viewer-pane
$ git rev-parse --git-common-dir
project/shirei/.gitEl primero es privado de este worktree, el segundo lo comparten todos. La regla mental que me funciona: todo lo que cuelga de refs/ se comparte, y los pseudo-refs como HEAD son privados de cada worktree. Por eso git rev-parse --git-path HEAD resuelve a una ruta adentro del worktree, mientras que refs/heads/main cae en el .git común. La excepción fina, por si algún día la necesitas: refs/bisect, refs/worktree y refs/rewritten tampoco se comparten, y gracias a eso puedes correr un git bisect o un rebase en un worktree sin ensuciarle el estado al otro.
Así que un repo, una historia compartida, muchos directorios, cada uno en su propia rama y con su propio HEAD. Sin re-clonar, sin volver a hacer fetch, sin el juego de los stashs para moverse entre ellos.
Hay un mito que prefiero matar aquí mismo, porque a mí me dejó un modelo mental equivocado por un buen rato... Los worktrees no ahorran disco compartiendo archivos. Comparten la base de objetos y las referencias, no el directorio de trabajo, y por eso cada worktree es un checkout completo. Tus node_modules, tu dist, tus artefactos de build, tu .env, nada de eso se comparte. Barato en historia, valor completo en el checkout. Guarda esa idea, porque importa más adelante.
Una restricción real que conviene conocer de inmediato: no puedes tener la misma rama checkeada en dos worktrees a la vez... git se niega, y es lo correcto, porque cada worktree tiene su propio HEAD pero comparten la misma referencia de la rama, así que dos worktrees sobre la misma rama terminarían pisándose los commits. Si de verdad necesitas dos árboles sobre el mismo commit, usa detach: git worktree add --detach <ruta> <commit>. Lo que tiene que ser único es la rama, no el commit.
git worktree vs una rama normal
La pregunta que siempre aparece es por qué no usar simplemente más ramas. La respuesta es que una rama y un worktree resuelven mitades distintas del mismo problema.
Una rama es una etiqueta sobre un commit, y cambiarte a ella muta el único directorio de trabajo que tienes. Un worktree es un directorio de trabajo entero y aparte, que además está sobre su propia rama. La rama te da aislamiento lógico. El worktree te da aislamiento físico. Cuando lo que escribe tus archivos es autónomo y hay dos de ellos, lo lógico no alcanza, porque quieres que los archivos vivan en lugares distintos.
Mi opinion... si eres de hacer una sola cosa a la vez, las ramas con git stash siguen siendo la herramienta correcta, y sacar un worktree es over engineering... El worktree se gana su lugar en el momento en que tienes multiples flujos de trabajo en un mismo proyecto, o uno corriendo largo mientras tú sigues trabajando en otra parte. Y esa es exactamente la forma que toma el trabajo con agentes.
La mejor prueba de que esto es real y no una manía mía, es que las herramientas top hoy en día lo incorporaron por default... Claude Code y Cursor lanzaron soporte nativo de worktrees en 2026, y nadie le agrega una primitiva a su producto si sus users no estuvieran chocando contra el muro que ella resuelve. Las ramas no alcanzaban... así que los agentes aprendieron a levantar worktrees por su cuenta.
Mi flujo con git worktree
Este es el flujo que sale de mi propio documento de trabajo.
Primero creo el worktree sobre una rama corta, partiendo desde un main actualizado.
git fetch origin
git worktree add .worktrees/web-viewer-pane -b feat/web-viewer-pane origin/main
cd .worktrees/web-viewer-panegit worktree add hace dos cosas en un solo paso: crea la carpeta .worktrees/web-viewer-pane con un checkout completo, y crea ahí la rama. El flag -b feat/web-viewer-pane es la rama nueva, y origin/main es el punto de partida limpio. Cuando entras a esa carpeta ya estás parado en tu rama, aislado de todo lo demás.
Después preparo el entorno. Cada worktree nace sin node_modules, así que instalo los paquetes.
pnpm installY acá viene el trabajo en sí… edito, el agente edita, commiteo, todo adentro de este árbol. Mi checkout principal ni se entera.
git add -A
git commit -m "feat(web-viewer): renderiza la pane de vista web"La parte que más me cambió el día a día es cómo se salta entre tareas. Antes era git stash, git checkout otra-rama, trabajar, devolverse. Con worktrees no hay checkout ni stash: cambias de carpeta. Cada worktree ya está en su rama, esperándote tal como lo dejaste.
cd ../screencast-permission-fix # o abres otra terminal, u otra sesión de agenteCuando la rama está lista, la integro como cualquier otra: push y PR, o merge local a main.
git push -u origin feat/web-viewer-paneY al terminar, cierro el worktree. Acá hay tres comandos que vale la pena entender por separado, porque es donde la gente se equivoca.
git worktree list # muestra todos tus worktrees y en qué rama está cada uno
git worktree remove .worktrees/web-viewer-pane # borrado seguro: se niega si hay cambios sin commitear
git worktree prune # limpia metadata huérfana si es que borraste a manogit worktree list es tu mapa: te dice qué árboles tienes abiertos y dónde está parado cada uno. git worktree remove es la forma correcta de borrar uno, porque elimina el checkout Y la metadata interna que git guarda en .git/worktrees/, y de paso te protege negándose si todavía hay trabajo sin commitear.
Lo que nunca hago, ni hay que hacer es rm -rf sobre la carpeta. Si borras el worktree a mano, el checkout desaparece pero la metadata queda colgando, y git sigue creyendo que ese worktree existe. Ahí entra git worktree prune, que recoge esos pedazos huérfanos. Es el plan de recuperación, no el flujo normal. Una regla que sigo siempre: salgo del directorio del worktree antes de removerlo.
Hay un par de cosas que aprendí que siempre tengo que hacer.
Los mantengo a todos en una carpeta .worktrees/ al lado del repo, y agrego esa carpeta al gitignore, junto con .claude/worktrees/, que es donde Claude Code deja los suyos. Los worktrees no son contenido, son checkouts de trabajo, y meterlos al repo sería solo ruido.
Si vives dentro de Claude Code, el camino nativo es un solo flag. claude --worktree web-viewer-pane crea un worktree bajo .claude/worktrees/web-viewer-pane y arranca una sesión adentro. Un detalle que los blogs repiten mal: la rama que crea se llama worktree-web-viewer-pane, con el prefijo, no sólo el nombre que le pasaste.
Los secrets no viajan por defecto, porque están en el gitignore, así que un archivo .worktreeinclude (misma sintaxis que .gitignore) le dice cuáles copiar a cada worktree nuevo. Y si apuntas un agente a su propio árbol aislado con isolation: worktree, recibe un worktree temporal que se limpia solo cuando termina sin dejar cambios atrás.
Comandos que no uso a diario, pero conviene tener mapeados
El flujo de arriba cubre el 90% de los días. El resto del command surface existe para cuando algo se sale de lo normal, y vale la pena conocerlo para que no te agarre desprevenido.
git worktree list --porcelain te da la misma lista que list, pero en un formato estable y parseable, ideal si quieres scriptear sobre tus worktrees en vez de leerlos a ojo.
$ git worktree list --porcelain
worktree project/shirei
HEAD 0e1fdbf8a2a7e26a40932a7a0ad3fca0658ab90f
branch refs/heads/maingit worktree lock y unlock son para cuando un worktree vive en un disco externo o un share de red que no siempre está montado. El lock evita que prune borre su metadata creyendo que el árbol desapareció. Si trabajas todo en local, probablemente nunca los toques.
git worktree move reubica un worktree a otra ruta sin romper sus punteros, con una salvedad importante: no mueve el worktree principal, ni uno que tenga submódulos.
git worktree repair es el botón de pánico. Si moviste carpetas a mano y los punteros quedaron apuntando a la nada, lo corres desde el repo principal y reconstruye las conexiones, en vez de andar editando los archivos gitdir a mano.
Y el --force: varios subcomandos lo piden una vez para saltarse una protección, y dos veces para los casos más delicados. Para remover un worktree con cambios sin commitear, va remove --force. Para remover uno que además está locked, --force dos veces. La regla de las dos veces es literal, y conviene tenerla presente antes de pelearte con git pensando que no funciona.
El costo de node_modules, y cómo se paga
Acuérdate de "precio completo en el checkout". Aquí es donde llega la cuenta.
Cada worktree es un checkout completo, así que cada worktree requiere su propio node_modules. Abre dos worktrees sobre un proyecto real y de pronto lo más pesado en tu disco son tres copias de las mismas dependencias. Esta es la razón número uno por la que la gente prueba los worktrees una vez y se da media vuelta y nunca más se acordaron de ellos, y es un reclamo justo.
La solución llega del gestor de paquetes, pnpm tiene un global virtual store, y activarlo significa que el node_modules de cada worktree son apenas symlinks hacia un único store.
# pnpm-workspace.yaml
enableGlobalVirtualStore: trueCon esto encendido, levantar un worktree fresco y correr pnpm install es instantáneo y no cuesta nada de disco. El costo de dependencias es la objeción real contra los worktrees, y esta es la solución a esa objeción.
Ahora, hay un costo que no se ha resuelto, o por lo menos yo aún no lo resuelvo, son los puertos y los servicios locales... ojo con esto y es que el aislamiento de filesystem no es aislamiento de servicios. Cada worktree que levanta un dev server va a pelear por el mismo puerto, y si todos hablan con una sola base de datos, también chocarán ahí. No hay flag mágico para esto :( , así que la parametrización de los puertos por worktree hay que hacerla a mano. Vale la pena saberlo antes de.
Cuándo un worktree es demasiado
No voy a pretender que esto es para todo y siempre lo ejecuto igual, como todo siempre hay que tener critero, un worktree es demasiado para una edición de un archivo que resuelves en 30 segundos, es demasiado cuando trabajas en serie, una tarea terminada del todo antes de empezar la siguiente. Para esos casos, el uso normal y git stash con una rama son más livianos y más rápidos, sacar un worktree solo te agrega carpetas que después tendrás que limpiar.
La regla a la que he llegado es esta: un worktree siempre cuando tengo dos o más agentes sobre tareas genuinamente separadas, o uno corriendo largo mientras yo sigo trabajando en otra parte. Fuera de eso, una rama es suficiente. Lo importante no es "usar worktrees siempre", lo importante es saber en cuál momento hay que ocuparlo para no tener problemas y perder trabajo/complicar el trabajo.
La parte a la que siempre vuelvo
Hoy corro muchos agentes y mi workflow ha mutado en los últimos meses. Algunas semanas el cuello de botella no es el modelo, soy yo siendo el único trabajando xD
Si estás ejecutando agentes y nunca configuraste uno, esta es la hora de mayor retorno que puedes invertir, porque la función ya viene instalada, es propia de git y no hay una herramienta nueva que aprender más allá de cinco comandos.
Por que el árbol de trabajo dejó de ser solo mío… y los worktrees son la forma en que cada agente tiene el suyo...

