Become a member!

Git worktree: trabajar en paralelo sin volverse loco (y por qué los agentes de IA los adoran)

Qué son los git worktree, qué problema resuelven y cómo los uso cada día para cambiar de contexto sin stash, sin volver a clonar y sin que el IDE reindexe todo.
🌐
Este artículo también está disponible en otros idiomas:
🇮🇹 Italiano  •  🇬🇧 English  •  🇩🇪 Deutsch  •  🇧🇷 Português

Una sola copia del repositorio, muchos directorios de trabajo independientes: la función de Git que cambió mi forma de cambiar de contexto.

Hay un momento en el día de cualquier desarrollador que te sabes de memoria. Estás metido de lleno en una feature complicada: doce archivos modificados, el IDE que por fin ha reindexado todo, el depurador detenido en un breakpoint, la cabeza sosteniendo un castillo mental fragilísimo. Y en ese preciso instante llega el mensaje: “Hay un bug crítico en producción, necesitamos un fix ya.”

¿Qué haces? Las opciones clásicas son tres, y las tres duelen. Puedes hacer git stash y rezar para acordarte de qué tenías entre manos. Puedes commitear un trabajo a medias con un mensaje del tipo WIP todavía no funciona que ensuciará el historial para siempre. O puedes clonar de nuevo el repositorio en otra carpeta, esperar la descarga, reconfigurar el entorno y reconstruirlo todo desde cero. En cualquier caso, ese castillo mental se derrumba.

Existe una cuarta opción, y desde que la descubrí la uso casi cada día: los git worktree. Y aquí llego a la verdadera razón por la que escribí este post: los worktree llevan años en Git, y sin embargo sigo viendo a montones de desarrolladores, incluso muy buenos, que no los usan y ni siquiera saben que existen. Cada vez que se los muestro a alguien la reacción es la misma: "¿cómo he podido trabajar sin esto hasta hoy?". Así que dejemos las cosas claras de una vez por todas: de dónde vienen, qué problema resuelven de verdad, cómo se usan y por qué, hoy, se han convertido en una herramienta fundamental también para los agentes de codificación basados en IA.

En resumen: un git worktree es un directorio de trabajo adicional enlazado al mismo repositorio. En lugar de tener una única carpeta de trabajo que salta de rama en rama con git checkout, puedes tener varias carpetas, cada una situada en una rama distinta, todas compartiendo el mismo historial y los mismos objetos dentro de .git. Cambias de contexto cambiando de carpeta, no haciendo stash. Introducidos en Git 2.5 (julio de 2015).

De dónde vienen

El comando git worktree llegó con Git 2.5, publicado el 27 de julio de 2015. Antes de eso, la regla implícita era de hierro: un repositorio, un directorio de trabajo. Si querías trabajar en dos ramas al mismo tiempo en dos carpetas distintas, la única vía oficial era un git clone repetido, con todo el desperdicio que conlleva: espacio en disco duplicado, objetos descargados de nuevo, remotes que reconfigurar y ningún vínculo entre las copias.

Los worktree rompieron esa restricción. La idea de fondo es elegante: el historial de un repositorio (commits, ramas, tags, objetos) vive una sola vez dentro de .git, mientras que los directorios de trabajo que lo materializan en disco pueden ser muchos. Una única fuente de verdad, muchos escritorios de trabajo asomados a ella.

Gran árbol baniano con un único tronco y muchas ramas y raíces aéreas que se ramifican, metáfora de los git worktree: un solo repositorio compartido, muchos directorios de trabajo independientes.
Un único tronco (el historial compartido en .git) del que se ramifica una copa de directorios de trabajo independientes. Así funcionan exactamente los git worktree.

El problema que resuelven de verdad

El modelo clásico de Git tiene un cuello de botella concreto: el directorio de trabajo es uno solo, así que solo puede estar en una rama a la vez. git checkout (o el más moderno git switch) es una operación destructiva sobre tu espacio de trabajo: reescribe los archivos en disco para reflejar la rama de destino. De ahí salen todas las molestias que conoces.

  • Los cambios sin commitear estorban. Si tienes archivos sucios, Git se niega a cambiar de rama, o te obliga a hacer stash. El stash es una pila oculta en la que es facilísimo olvidarse de las cosas.
  • Cambiar de rama invalida el trabajo de build. Cambias de rama y los timestamps de los archivos cambian: el IDE reindexa, el compilador reconstruye media solución, la caché de tests se vacía. En un proyecto Delphi de cierto tamaño, o en cualquier codebase grande, eso significa minutos perdidos en cada salto.
  • No puedes mirar dos ramas en el mismo momento. ¿Quieres comparar el comportamiento de la feature con el de main lado a lado? Con un único directorio de trabajo no puedes: tienes que saltar adelante y atrás, reconstruyendo cada vez.

Los worktree eliminan el cuello de botella de raíz. Cada contexto de trabajo obtiene su carpeta, con sus archivos, su estado de build, independiente de los demás. Cambiar de contexto se convierte en un cd, no en un git stash seguido de una reconstrucción.

Cómo se usan: los cuatro comandos que necesitas

Toda la API de los worktree cabe en un puñado de comandos. Partamos de que estás dentro de un repositorio ya clonado.

Crear un worktree en una rama existente, en una carpeta junto a la del proyecto:

# Crea ../app-hotfix como directorio de trabajo situado en la rama hotfix/login
git worktree add ../app-hotfix hotfix/login

Crear un worktree y una rama nueva juntos, de una sola vez:

# Crea la rama feature/export partiendo de main y le da su propia carpeta
git worktree add -b feature/export ../app-export main

Listar todos los worktree activos, con su ruta y la rama en la que están:

git worktree list
# /home/daniele/app           a1b2c3d [main]
# /home/daniele/app-hotfix    e4f5g6h [hotfix/login]
# /home/daniele/app-export    i7j8k9l [feature/export]

Eliminar un worktree cuando has terminado, y limpiar las referencias huérfanas que queden:

git worktree remove ../app-hotfix
git worktree prune   # limpia los metadatos de worktree borrados a mano

Una nota que conviene tener en cuenta desde el principio: Git no te deja hacer checkout de la misma rama en dos worktree al mismo tiempo. Es una protección deliberada, no un límite arbitrario. Dos carpetas modificando la misma rama serían la receta perfecta para liarse y pisarse los commits mutuamente. Si de verdad lo necesitas, existe --force, pero en el 99% de los casos ese mensaje de error te está salvando de un problema.

También hay algunos comandos más que usarás con menos frecuencia, pero que conviene saber que existen: git worktree move para mover un directorio de trabajo a otra ruta, git worktree lock / unlock para impedir que un worktree (por ejemplo en un disco extraíble o un recurso de red) se limpie automáticamente, y git worktree repair para reparar las referencias cuando has movido carpetas a mano y Git se ha perdido. Para el uso diario, sin embargo, los cuatro comandos anteriores lo cubren todo.

Y si prefieres el ratón al teclado, no te quedas fuera: las herramientas gráficas más maduras exponen los worktree con la misma naturalidad. En Git Extensions, por ejemplo, hay todo un submenú dedicado bajo Repository, Worktrees, con las opciones para crear uno nuevo y para gestionar los existentes.

Menú de Git Extensions abierto en Repository, Worktrees, con las opciones Create a worktree y Manage worktrees.
Crear y gestionar worktree desde Git Extensions: sin línea de comandos, solo un menú.

Un layout que se mantiene ordenado solo

Si los worktree se vuelven parte estable de tu flujo, un pequeño truco de organización los hace todavía más limpios. En lugar de esparcir carpetas al azar por el disco, una convención muy extendida es clonar el repositorio como bare dentro de una carpeta .bare, y mantener todos los worktree como subcarpetas junto a ella, una por rama:

git clone --bare git@github.com:usuario/app.git app/.bare
cd app
echo "gitdir: ./.bare" > .git
# checkout de las ramas existentes, cada una en su carpeta
git worktree add main main
git worktree add feature-export feature/export

Así tu proyecto se convierte en una carpeta app/ que contiene main/, feature-export/ y demás, cada una lista para usar, con el historial compartido escondido en .bare. Fíjate en que siempre paso la rama como segundo argumento: si lo omites, Git usa solo el último segmento de la ruta como nombre de la rama (de feature/export tomaría export) y a menudo acaba creando una rama nueva, rara vez la que querías. No es un setup obligatorio, pero cuando trabajas con muchos worktree te lo agradeces a ti mismo.

Ejemplos de la vida real

La teoría es breve, la utilidad es enorme. Estos son los escenarios en los que abro un worktree sin pensarlo siquiera.

El hotfix mientras una feature está a medias

Volvamos a la escena del principio. Estás a mitad de feature/nuevo-informe, directorio de trabajo lleno de cambios. Llega la emergencia. En lugar de hacer stash:

git worktree add -b hotfix/crash-pdf ../app-hotfix main
cd ../app-hotfix
# aquí arreglas el bug, commiteas, haces push, abres la PR
# mientras tanto tu feature sigue intacta en la otra carpeta

Apagado el incendio, haces cd de vuelta a la carpeta de la feature y encuentras todo exactamente como lo dejaste: archivos abiertos, estado de build, breakpoints. Cero stash, cero reconstrucciones.

La code review sin molestar tu propio trabajo

Un compañero te pide que revises su PR. Quieres ejecutarla de verdad, no solo leer el diff en una página web. Con un único directorio de trabajo tendrías que interrumpir tu trabajo. Con un worktree, no:

git worktree add ../app-review feature/companero-pr
cd ../app-review
# compilas, ejecutas, pruebas la feature del compañero
# tu rama personal ni siquiera se toca

Una build larga en paralelo

El caso clásico de los proyectos grandes: la build completa o la suite de tests tarda minutos. En lugar de quedarte de brazos cruzados, lanzas la build pesada en un worktree y sigues escribiendo código en otro. Dos carpetas, dos estados de build independientes, ninguna interferencia.

La comparación lado a lado de dos versiones

¿Necesitas entender por qué un comportamiento cambió entre main y la rama de release? Abre dos worktree, uno para cada uno, y ponlos literalmente uno al lado del otro en dos ventanas del editor. Nada de saltar adelante y atrás: los miras en el mismo instante.

Por qué los agentes de IA los usan tantísimo

Aquí los worktree pasan de comodidad personal a habilitadores de toda una forma de trabajar. Los agentes de codificación basados en IA, como Claude Code y similares, tienen un apetito natural por el trabajo paralelo: ejecutar varias tareas al mismo tiempo, cada una modificando archivos, lanzando builds y commiteando por su cuenta.

El problema es que varias instancias trabajando en el mismo directorio de trabajo se pisarían entre sí: un agente cambia un archivo mientras otro lo está compilando, las ramas se sobrescriben, el estado se vuelve incoherente. La solución que adoptan estas herramientas es precisamente el git worktree: a cada agente, o a cada tarea paralela, se le asigna un worktree aislado. Cada uno tiene su carpeta, su rama, su estado de build, pero todos comparten la misma base de datos de objetos, así que no hay duplicación del historial y los resultados se reintegran en el repositorio principal con un merge normal.

Es exactamente el mismo patrón que uso a mano para el hotfix, llevado a escala industrial y automatizado. Un agente trabaja en la feature A en ../app-feature-a, otro en la feature B en ../app-feature-b, un tercero está ejecutando los tests en ../app-tests, y ninguno de los tres sabe siquiera de la existencia de los otros. El aislamiento que hace cómodos los worktree para nosotros es la misma propiedad que los hace indispensables para orquestar varios agentes en paralelo.

Algunas precauciones

Los worktree son sólidos, pero un par de cosas conviene saberlas antes de quemarse.

  • Misma rama, un solo worktree. Ya lo dijimos: es una protección, no un defecto. Para probar la misma rama en dos sitios, crea una rama auxiliar.
  • La configuración es compartida, el directorio de trabajo no. Los worktree comparten config, los objetos y las ramas, pero cada uno tiene su propio HEAD, su propio index y sus propios archivos. El stash, ojo, es compartido a nivel de repositorio: no lo imagines atado a un worktree concreto.
  • Haz limpieza. Cuando borras una carpeta de worktree a mano en lugar de con git worktree remove, quedan metadatos huérfanos: git worktree prune los limpia. git worktree list es tu panel de control para no perder la cuenta.
  • Los submódulos requieren atención. Si el proyecto usa submódulos, acuérdate de inicializarlos también en el nuevo worktree; no se materializan por sí solos.

Puntos clave

  • Un repositorio, muchos directorios de trabajo. Los git worktree, introducidos en Git 2.5 (julio de 2015), te dan varias carpetas de trabajo desde el mismo .git, cada una en una rama distinta.
  • Cambiar de contexto se vuelve un cd. Se acabó el git stash y volver a clonar para atender un hotfix urgente: abres un worktree, trabajas, lo cierras, y el trabajo original sigue intacto.
  • El estado de build sobrevive. Cada worktree mantiene su propia indexación y caché de compilación: cambiar de contexto no obliga al IDE a empezar de cero.
  • Pocos comandos. git worktree add, git worktree list, git worktree remove, git worktree prune: prácticamente es todo.
  • Son el motor del trabajo paralelo de los agentes de IA. Asignar un worktree aislado a cada agente o tarea es el patrón que permite a varios agentes trabajar sobre el mismo repositorio sin chocar.
  • Una protección que recordar. La misma rama no puede estar en dos worktree a la vez: es deliberado, y es bueno.

Preguntas frecuentes

¿En qué versión de Git llegaron los worktree?

El comando git worktree se introdujo en Git 2.5, publicado el 27 de julio de 2015. Desde entonces es una función estable y está disponible en cualquier instalación moderna de Git.

¿Qué diferencia hay entre git worktree y volver a clonar el repositorio?

Un clon nuevo crea una copia completamente separada: base de datos de objetos duplicada, el doble de espacio en disco, remotes que reconfigurar y ningún vínculo con el original. Un worktree, en cambio, solo añade un directorio de trabajo: el historial, las ramas y los objetos quedan compartidos en un único .git. Es mucho más ligero, y las ramas creadas en un worktree son inmediatamente visibles para los demás.

¿Puedo hacer checkout de la misma rama en dos worktree?

No, y a propósito. Git impide situar la misma rama en dos worktree a la vez para evitar que dos carpetas reescriban su estado de forma incoherente. Si de verdad lo necesitas, puedes forzarlo con --force, pero casi siempre la solución correcta es crear una rama auxiliar.

¿Por qué los agentes de codificación con IA usan worktree?

Porque habilitan el trabajo paralelo sin conflictos. Al asignar a cada agente o tarea un worktree aislado, varios agentes pueden modificar archivos, compilar y commitear al mismo tiempo sobre el mismo repositorio sin pisarse, compartiendo aun así un único historial en el que se reintegran los resultados.

¿Cómo elimino un worktree cuando he terminado?

Usa git worktree remove <ruta> para borrarlo de forma limpia. Si en cambio borraste la carpeta a mano, ejecuta git worktree prune para limpiar los metadatos huérfanos. Con git worktree list puedes comprobar en cualquier momento qué worktree están activos.

¿Quieres dominar Git de verdad?

Los worktree son solo una de las muchas cosas que Git sabe hacer

Los worktree son una de las funciones que separan a quien usa Git de quien lo sufre. Y aquí hay algo que veo pasar continuamente: muchísima gente está convencida de conocer Git, y luego asiste al curso que BitTime Professionals dedica a Git y a los sistemas de control de versiones y se da cuenta de que, hasta ese momento, lo había usado "a ojo", a base de comandos memorizados sin entender de verdad qué pasa por debajo. Si quieres que tu equipo conozca Git a fondo, desde el modelo de objetos hasta los flujos de branching, pasando por las situaciones de emergencia en las que hay que saber exactamente qué se está haciendo, el curso es práctico, denso y pensado para equipos reales. Encontrarás todos los detalles aquí: bittimeprofessionals.com/formazione/git.

Comments

comments powered by Disqus