Introducción a Git Worktrees
Los worktrees te permiten descargar múltiples ramas al mismo tiempo, cada una en su propio directorio, todas compartiendo un repositorio subyacente. Sin más danzas de git stash cuando necesitas saltar entre contextos.
Receta
Tarjeta de referencia rápida -- lista para copiar y pegar.
# Añadir un worktree en una rama existente
git worktree add ../feature-branch feature-branch
# Añadir un worktree y crear una rama nueva en un paso
git worktree add ../new-feature -b new-feature
# Añadir un worktree en un commit o tag específico (HEAD desacoplado)
git worktree add ../hotfix abc1234
# Listar todos los worktrees vinculados a este repositorio
git worktree list
# Eliminar un worktree (después de commit o stash de cambios)
git worktree remove ../feature-branch
# Limpiar entradas obsoletas después de que una carpeta fue eliminada manualmente
git worktree pruneCuándo usarlo: Cualquier momento en que de otra forma harías stash, clonarías el repositorio una segunda vez, o cambiarías de contexto entre ramas múltiples veces por hora.
Ejemplo Práctico
# 1. Comienza una característica en su propio directorio
git worktree add ../my-feature -b my-feature
# 2. Trabaja y haz commit dentro de ese worktree
cd ../my-feature
# ...edita archivos, ejecuta tests...
git commit -am "feat: scaffold new feature"
# 3. Regresa al worktree principal para fusionar
cd ../main-repo
git switch main
git merge my-feature
# 4. Limpia
git worktree remove ../my-feature
git branch -d my-featureLo que esto demuestra:
- Un repositorio, dos directorios de trabajo simultáneos con archivos independientes.
- El nuevo commit de la característica es inmediatamente visible desde el worktree principal -- comparten historial.
- El worktree principal es donde ocurre el merge; el worktree de la característica es solo un lugar para escribir código.
- Los worktrees están diseñados para ser temporales: crear, trabajar, fusionar, eliminar.
Exploración Profunda
El modelo mental: un gabinete, muchos escritorios
Piensa en un repositorio de Git como la casa de un escritor. En la habitación trasera está un gabinete de acero -- este es el directorio .git, que contiene cada commit, cada rama, cada fragmento de historial. En el estudio está tu escritorio de trabajo, donde una versión del manuscrito está dispuesta para que puedas leerla y editarla.
Durante la mayor parte de la historia de Git, solo tenías un escritorio. Cambiar de rama significaba recoger las páginas del escritorio, archivarlas, y disponer una versión diferente. Si estabas a mitad de una característica y necesitabas reparar un bug en producción, tenías que hacer stash de tu trabajo incompleto, limpiar el escritorio, reparar el bug, y luego revertir todo el proceso.
Los worktrees te dan un segundo escritorio. Y un tercero. Y un cuarto. Cada escritorio sostiene una rama diferente, con sus propios archivos visibles y editables, mientras los otros continúan sosteniendo lo que tenías dispuesto antes. Todos los escritorios comparten el mismo gabinete -- el mismo historial, los mismos commits, la misma configuración remota. Pero los archivos en la parte superior, los árboles de trabajo, son independientes.
Eso es lo que es un worktree: una segunda vista al mismo repositorio.
Qué se comparte, qué se separa
Cuando añades un worktree, Git hace algo elegante. En la nueva carpeta, crea los archivos del árbol de trabajo para la rama que solicitaste, exactamente como si hubieras clonado el proyecto fresco. Pero no clona nada. La nueva carpeta contiene un pequeño archivo .git (no un directorio) que apunta al directorio .git del repositorio original. Cada operación en el nuevo worktree -- commit, push, pull, log -- lee y escribe en ese único gabinete compartido.
| Compartido entre todos los worktrees | Separado por worktree |
|---|---|
| Base de datos de objetos (commits, blobs, árboles) | Archivos del directorio de trabajo |
| Ramas y tags | Índice (área de staging) |
| Configuración remota | Referencia HEAD |
| Stashes | Cambios sin commit |
| La mayoría de configuración | Checkouts de submódulos (iniciar por worktree) |
| Hooks | Artefactos de construcción (node_modules, etc.) |
La consecuencia maravillosa: no hay duplicación de historial. Si tu repositorio es gigabytes de objetos, añadir un worktree añade apenas nada al disco -- solo pagas por los archivos descargados, no el historial detrás de ellos.
La regla de una rama por worktree
Git obliga una única regla que atrapa a todos una vez: una rama dada solo puede estar descargada en un worktree a la vez. Intenta descargar main en dos worktrees, y Git se rehúsa. La razón es simple -- si ambos escritorios sostienen el mismo borrador y escribes cambios diferentes en cada uno, ¿qué conjunto de cambios aceptaría eventualmente el gabinete? La restricción te protege de una pregunta que no tiene buena respuesta.
La solución es lo que esperarías: ramifica. Si quieres un segundo worktree basado en main, crea una rama nueva desde main (git worktree add ../scratch -b scratch main) y úsala.
Los metadatos administrativos
Dentro de tu carpeta .git original, un subdirectorio worktrees/ sostiene una pequeña carpeta para cada worktree vinculado. Cada una contiene su propio HEAD, índice, logs, y algunos otros archivos. El repositorio original siempre sabe dónde vive cada worktree, qué rama tiene descargada, y si la carpeta aún existe en disco.
git worktree list las imprime todas, incluyendo el worktree principal -- que es solo el primer escritorio entre iguales.
El worktree principal está estructuralmente privilegiado
Los worktrees vinculados se sienten como iguales al principal en el uso diario, pero el worktree principal es donde vive el directorio .git actual. Si eliminas la carpeta del worktree principal mientras los worktrees vinculados aún existen, todos se rompen -- el gabinete del cual dependen ha desaparecido. Trata el worktree principal como la base. Muévelo con cuidado (usa git worktree repair después si es necesario).
Cuándo usar worktrees
El cambio mental es de "las ramas son lugares que visito, uno a la vez" a "las ramas son lugares que puedo ocupar simultáneamente, cada uno en su propia sala." Los worktrees brillan cuando:
- Te interrumpen por un hotfix y no quieres perturbar tu característica en progreso.
- Quieres revisar el PR de un compañero de equipo ejecutando su rama en una carpeta separada.
- Necesitas ejecutar una suite de tests larga en una rama mientras continúas el desarrollo en otra.
- Estás comparando dos implementaciones lado a lado, ambas ejecutándose, ambas editables.
- Mantienes un worktree "main" como referencia limpia y haces todo el trabajo en worktrees de características.
Los worktrees no son un sustituto para ramas. No siempre son un sustituto para stashing -- un cambio de contexto rápido de 30 segundos es aún más rápido con stash. Sí son casi siempre un sustituto para clonar el repositorio dos veces, ya que evitas el costo de almacenamiento y el dolor de cabeza de mantener dos clones sincronizados vía el remoto.
Gotchas
Cosas que te atraparán. Cada gotcha incluye qué sale mal, por qué sucede, y la solución.
-
Intentar descargar una rama que ya está en otro worktree -- Git se rehúsa con
fatal: '<branch>' is already checked out at .... Solución: Trabaja en el worktree existente, crea una rama nueva desde ese (git worktree add ../scratch -b scratch <branch>), o elimina el otro worktree primero. -
Eliminar una carpeta de worktree manualmente con
rm -rf-- Los metadatos de Git aún apuntan a la carpeta faltante, ygit worktree listcontinúa mostrándola. Solución: Ejecutagit worktree prunepara limpiar referencias huérfanas. -
Eliminar el worktree principal mientras existen worktrees vinculados -- El directorio
.gitcompartido desaparece y cada worktree vinculado está roto. Solución: Nunca elimines la carpeta del worktree principal. Si necesitas reubicar el repositorio, mueve el worktree principal primero, luego ejecutagit worktree repairdesde dentro para actualizar los enlaces. -
Los submódulos no se inicializan automáticamente en un worktree nuevo -- Los directorios de submódulos aparecen vacíos. Solución: Ejecuta
git submodule update --init --recursivedentro de cada worktree nuevo que necesite submódulos. -
node_modulesy artefactos de construcción duplicados por worktree -- Cada worktree tiene sus propios archivos descargados, así quenpm installen tres worktrees significa tres directoriosnode_modules. Solución: Usa un caché de paquetes compartido (el almacén direccionable por contenido de pnpm maneja esto naturalmente) o acepta el costo de disco como el precio del paralelismo. -
Los hooks se activan en cada worktree -- Los hooks viven en el directorio compartido
.git/hooks, así que un hook pre-commit se ejecuta sin importar desde qué worktree hagas commit. Solución: Usualmente es lo que quieres, pero si un hook necesita comportamiento diferente por worktree, ramifica engit rev-parse --git-common-dirvs--git-dirdentro del hook. -
Los IDEs abren la carpeta incorrecta después de cambiar de worktree -- Las ventanas del editor atadas al camino antiguo continúan mostrando archivos obsoletos. Solución: Abre cada worktree como su propio proyecto/ventana en tu editor; trátalos como espacios de trabajo separados.
-
Olvidar hacer commit antes de
git worktree remove-- Git se rehúsa a eliminar un worktree con cambios sin commit (¡bien!), pero puedes quedarte atrapado si la carpeta tiene archivos sin rastrear que olvidaste. Solución: Haz commit, stash, o usagit worktree remove --forcesi estás seguro de que los cambios son desechables.
Alternativas
Otras formas de resolver el mismo problema -- y cuándo cada una es la mejor opción.
| Alternativa | Usa Cuando | No Uses Cuando |
|---|---|---|
git stash | Un cambio de contexto de 30 segundos -- arregla una línea en otra rama y vuelve | La interrupción es larga, o necesitas ambas ramas ejecutándose lado a lado |
| Clonar el repositorio dos veces | Necesitas directorios .git completamente aislados (por ej., experimentar con git filter-repo destructivo) | Quieres historial compartido, ramas y remotos -- los worktrees son estrictamente mejores aquí |
| Cambio de rama en su lugar | Flujo de rama única sin trabajo en progreso para preservar | Tienes cambios sin commit, o quieres mantener dos contextos abiertos |
git worktree | Dos o más ramas necesitan coexistir -- revisión + característica, hotfix + WIP, comparación A/B | Un simple stash-y-cambio haría el mismo trabajo en menos tiempo |
FAQs
¿Cuál es la diferencia entre un worktree y un clone?
- Un clone duplica el directorio
.gitcompleto, historial y todo -- dos repositorios independientes. - Un worktree comparte el directorio
.gitoriginal, así que los commits y fetches en uno son inmediatamente visibles en otros. - Los worktrees son dramáticamente más baratos en disco y evitan el dolor de cabeza de "mantener dos clones sincronizados vía el remoto".
¿Puedo tener dos worktrees en la misma rama?
- No. Git obliga una rama por worktree para prevenir commits conflictivos a la misma referencia de rama.
- La solución es ramificar:
git worktree add ../scratch -b scratch maincrea una rama nueva comenzando desdemainy la descarga en el nuevo worktree.
¿Dónde debo poner mis directorios de worktree?
- Fuera de tu carpeta de repositorio principal. Patrones comunes: una carpeta hermana (
../my-feature) o un padre de worktrees dedicado (~/projects/myrepo-worktrees/feature-x). - Evita anidar un worktree dentro del worktree principal -- Git tratará los archivos internos como sin rastrear y la experiencia se vuelve confusa.
¿Los worktrees comparten mis stashes?
- Sí. Los stashes viven en el directorio
.gitcompartido, así quegit stash listmuestra las mismas entradas desde cualquier worktree. - Esto significa que puedes hacer stash en un worktree y pop en otro -- ocasionalmente útil, a menudo sorprendente.
¿Qué sucede con mis worktrees cuando hago push o pull?
- Un
git fetchen cualquier worktree actualiza las referencias remotas compartidas, así que todos los worktrees ven los nuevos commits inmediatamente. - Un
git pullsolo actualiza la rama descargada en el worktree donde lo ejecutaste -- los otros worktrees permanecen en cualquier commit que tenían.
¿Cómo muevo un worktree a una ubicación nueva?
git worktree move ../old-path ../new-path- Git actualiza los metadatos así que el worktree continúa trabajando desde su ubicación nueva.
- Si moviste la carpeta manualmente con
mv, ejecutagit worktree repair ../new-pathdesde dentro del worktree principal.
¿Los hooks se ejecutan en cada worktree?
- Sí. Los hooks viven en
.git/hooksy ese directorio se comparte, así que un hookpre-commitse activa en cualquier worktree donde hagas commit. - Esto es usualmente lo que quieres -- aplicación consistente -- pero ten cuidado si un hook depende de caminos absolutos.
¿Puedo usar worktrees con submódulos?
- Sí, pero los submódulos no se inicializan automáticamente en un worktree nuevo. Ejecuta
git submodule update --init --recursivedespués de crear uno. - Versiones recientes de Git manejan esto más elegantemente, pero la inicialización manual es el default seguro.
¿Cómo listo cada worktree y la rama en la que está?
git worktree list- La salida muestra la ruta, el SHA del commit, y la rama (o
(detached HEAD)). - Usa
--porcelainpara un formato estable, legible por máquina.
¿Hay un costo de rendimiento al tener muchos worktrees?
- Disco: cada worktree tiene sus propios archivos descargados, así que el uso de disco escala con el tamaño del árbol de trabajo (no historial).
node_modulesy artefactos de construcción se duplican. - CPU/memoria: negligible. Operaciones como
git statussolo escanean el worktree actual. - Un puñado de worktrees está bien. Cientos sería inusual pero técnicamente soportado.
Relacionados
- Ejemplos de Worktree -- Ejemplos completos del ciclo de vida para checkout, merge, rebase, y limpieza
- Comandos de Git Esenciales -- Los comandos fundamentales en los que se construye cada flujo de trabajo de worktree
- Fusión y Rebase -- Cómo integrar trabajo entre ramas (y entre worktrees)
- Lista de Verificación de Resolución de Conflictos de Merge -- Guía paso a paso cuando un merge de worktree entra en conflicto