Busca en todas las páginas de la documentación
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.
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.
# 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
Lo que esto demuestra:
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.
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.
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.
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.
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).
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:
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.
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, y git worktree list continúa mostrándola. Solución: Ejecuta git worktree prune para limpiar referencias huérfanas.
Eliminar el worktree principal mientras existen worktrees vinculados -- El directorio .git compartido 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 ejecuta git worktree repair desde 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 --recursive dentro de cada worktree nuevo que necesite submódulos.
node_modules y artefactos de construcción duplicados por worktree -- Cada worktree tiene sus propios archivos descargados, así que npm install en tres worktrees significa tres directorios node_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 en git rev-parse --git-common-dir vs --git-dir dentro 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. Haz commit, stash, o usa si estás seguro de que los cambios son desechables.
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 |
.git completo, historial y todo -- dos repositorios independientes..git original, así que los commits y fetches en uno son inmediatamente visibles en otros.git worktree add ../scratch -b scratch main crea una rama nueva comenzando desde main y la descarga en el nuevo worktree.../my-feature) o un padre de worktrees dedicado (~/projects/myrepo-worktrees/feature-x)..git compartido, así que git stash list muestra las mismas entradas desde cualquier worktree.git fetch en cualquier worktree actualiza las referencias remotas compartidas, así que todos los worktrees ven los nuevos commits inmediatamente.git pull solo actualiza la rama descargada en el worktree donde lo ejecutaste -- los otros worktrees permanecen en cualquier commit que tenían.git worktree move ../old-path ../new-pathmv, ejecuta git worktree repair ../new-path desde dentro del worktree principal..git/hooks y ese directorio se comparte, así que un hook pre-commit se activa en cualquier worktree donde hagas commit.git submodule update --init --recursive después de crear uno.git worktree list(detached HEAD)).--porcelain para un formato estable, legible por máquina.node_modules y artefactos de construcción se duplican.git status solo escanean el worktree actual.git worktree remove --force