Git stash vs commit vs worktree: dónde guardar tu trabajo a medias
Stash, commit WIP, cambiar de rama o git worktree: qué conserva cada opción, dónde vive y cuál usar cuando entra un bug urgente a mitad de tarea.
Si tienes trabajo a medias y entra algo urgente, en Git tienes cuatro salidas: cambiar de rama tal cual, git stash para limpiar el árbol un rato, un commit WIP en tu rama para guardarlo en el historial, o git worktree add para abrir otra rama en una carpeta aparte sin tocar la tuya. Las cuatro funcionan. Lo que cambia es cuánto dura la interrupción y qué estás dispuesto a arriesgar.
Necesitas saber hacer add, commit y git switch. Si nunca has usado git stash, empieza por la guía de git stash para guardar cambios sin hacer commit; aquí solo lo comparo.
Las cuatro opciones de un vistazo
Un commit WIP (“work in progress”) es un commit normal con el trabajo a medias, que sabes que reharás después. git worktree es un segundo directorio de trabajo conectado al mismo repositorio: otra carpeta y otra rama, con el mismo historial.
| Opción | Cuándo usarla | Qué conserva | Dónde vive | Cómo vuelves | Riesgo |
|---|---|---|---|---|---|
| Cambiar de rama sin más | Tus cambios no chocan con la rama de destino | Todo, porque los cambios viajan contigo | En tu directorio de trabajo | git switch de vuelta | Mezclar tu trabajo a medias con el arreglo urgente |
git stash | Interrupción corta, de minutos | Cambios en archivos ya trackeados y el staging; los nuevos solo con -u | En tu repo local (refs/stash) | git stash pop | Olvidarte de -u o del propio stash |
| Commit WIP | El trabajo tiene que durar, o quieres subirlo al remoto | Todo lo que añadas con git add -A | En el historial de tu rama | git reset --soft HEAD~1 o seguir encima | Que el WIP acabe tal cual en main |
git worktree add | Vas a alternar entre dos tareas durante horas o días | Tu carpeta original intacta, sin tocar nada | En otra carpeta del disco | Cambiar de carpeta (cd) | Carpetas huérfanas y dependencias duplicadas |
La columna que más decide es la de riesgo, y se ve mejor con un caso concreto.
El mismo caso con las cuatro opciones
Estás en feature/login, has modificado src/login.ts y has creado src/login.test.ts sin añadirlo. Entra un bug urgente en main, que ya tiene un commit que toca login.ts. Cada opción parte del mismo punto, y la salida de cada comando es real, de un repo de prueba con git 2.43.0.
Cambiar de rama sin más
Es lo primero que hace todo el mundo, y a veces sale bien. Git solo te frena si tus cambios se perderían al cambiar de rama[3]:
# Intentas saltar a main con login.ts modificado
$ git switch main
error: Your local changes to the following files would be overwritten by checkout:
src/login.ts
Please commit your changes or stash them before you switch branches.
Aborting
Lo traicionero es el caso contrario. Si main no hubiera tocado login.ts, el switch habría funcionado y Git te habría avisado con un escueto M src/login.ts: tus cambios a medias se vienen contigo a main. Si no te das cuenta, acaban dentro del commit del hotfix.
git stash: árbol limpio en segundos
El stash guarda tus cambios en una pila local y deja el directorio como en el último commit[1]. Aquí está la primera trampa de la tabla:
# Sin -u, el archivo nuevo se queda fuera del stash
$ git stash push -m "wip login"
Saved working directory and index state On feature/login: wip login
$ git status --short
?? src/login.test.ts
login.test.ts sigue ahí y viajará contigo si cambias de rama. Con git stash push -u -m "wip login" el status sale vacío. Y el stash vive en refs/stash de tu repo local. Al hacer push de main y feature/login, en el remoto aparecieron solo esas dos ramas: el stash se quedó en mi máquina.
Commit WIP: el trabajo pasa al historial
El commit WIP es la opción aburrida y segura. Tus cambios quedan en un commit de tu rama, igual que cualquier otro:
# Guarda TODO, incluidos los archivos nuevos
$ git add -A && git commit -m "WIP: login a medias"
[feature/login 3f709d0] WIP: login a medias
2 files changed, 2 insertions(+)
create mode 100644 src/login.test.ts
$ git switch main
Switched to branch 'main'
Al volver, sigues encima y limpias antes de la PR con git rebase -i para ordenar tus commits, o deshaces el commit sin perder los cambios:
# Quita el commit WIP; los cambios quedan preparados en el staging
$ git reset --soft HEAD~1
$ git status --short
A src/login.test.ts
M src/login.ts
A diferencia del stash, este commit sí lo puedes subir con git push. Si tu portátil muere esta noche, el trabajo sigue en el remoto.
git worktree add: otra carpeta, otra rama
El worktree resuelve el problema por otro lado: no limpias nada, abres una segunda carpeta con la rama que necesitas[2].
# Crea la rama hotfix/pago desde main en la carpeta ../app-hotfix
$ git worktree add -b hotfix/pago ../app-hotfix main
Preparing worktree (new branch 'hotfix/pago')
HEAD is now at 927cde5 Ajusta login en main
# Lista todos los directorios de trabajo del repo
$ git worktree list
/tmp/wip-demo/app d6c75d3 [feature/login]
/tmp/wip-demo/app-hotfix 927cde5 [hotfix/pago]
Haces el arreglo y el commit en ../app-hotfix, y en la carpeta original git status --short sigue mostrando M src/login.ts y ?? src/login.test.ts. Nada se ha movido. La restricción: una rama solo puede estar abierta en un worktree a la vez.
$ git worktree add ../app-otra feature/login
Preparing worktree (checking out 'feature/login')
fatal: 'feature/login' is already used by worktree at '/tmp/wip-demo/app'
git worktree vs git branch: qué cambia por dentro
Todos los worktrees comparten las mismas ramas y el mismo stash, pero cada carpeta sabe en qué rama está (técnicamente, cada una tiene su propio HEAD)[2]. En la práctica, el commit que haces en ../app-hotfix aparece al instante en git branch de la carpeta original, marcado con un + porque esa rama está abierta en otro worktree.
Con una sola carpeta trabajas en una rama cada vez. Con worktrees tienes dos abiertas a la vez, cada una con sus archivos y su propio npm install. Cómo se reparte el disco entre ellas y cómo montar varios agentes de IA en paralelo lo tienes en git worktrees con Claude Code para agentes en paralelo.
Qué opción elegir: la regla de decisión
Hazte estas preguntas en orden y quédate con la primera que diga sí:
- ¿Tus cambios no tocan nada de la rama de destino y vas a volver enseguida? Cambia de rama, pero mira el
Mque te imprime Git antes de hacer el commit del arreglo. - ¿La interrupción es de minutos?
git stash push -u -m "...", ypopal volver. - ¿El trabajo a medias tiene que sobrevivir a la noche o a un cambio de ordenador, o quiere verlo un compañero? Commit WIP y push de tu rama.
- ¿Vas a saltar entre las dos tareas varias veces, o necesitas tener la app arrancada en las dos ramas? Worktree.
Entre stash o rama con commit WIP, la duda real es si volverás hoy. Para minutos gana el stash. Si no lo sé, elijo el commit WIP: sobrevive a lo que pase con el portátil y no ensucia nada si lo deshago antes de la PR.
Errores comunes
Usar stash para una interrupción de días
Al cabo de unos días tu rama ha cambiado, el pop choca y ya no recuerdas qué había dentro. Si la interrupción se alarga, pasa a un commit WIP. La mecánica del stash (el -u, pop frente a apply) está en la guía de git stash.
Abrir un worktree para un arreglo de cinco minutos
Un worktree te cobra una carpeta nueva, una instalación de dependencias y acordarte de quitarlo con git worktree remove (o git worktree prune si borraste la carpeta a mano). Para cinco minutos, un stash basta.
Cambiar de rama arrastrando el M al hotfix
Si creas la rama del arreglo sin limpiar antes, tu cambio a medias se viene con ella:
$ git switch -c hotfix/pago
Switched to a new branch 'hotfix/pago'
$ git status --short
M src/login.ts
Un git commit -a aquí mete tu login a medias en el hotfix. Antes de crear la rama, decide dónde va ese M.
Dejar que el commit WIP llegue a main
El WIP es perfecto en tu rama y feo en el historial compartido. Antes de la PR, deshazlo como en el ejemplo de arriba o júntalo con otros commits en un git rebase -i, y rehaz el commit con un mensaje de verdad.
Practica el flujo con ejercicios guiados
Estas decisiones se asientan con las manos. En el curso Git de cero a profesional practicas el flujo de ramas, commits y guardar trabajo a medias en ejercicios guiados.
Fuentes
- git-stash, documentación oficial de Git (fuente en el repositorio git/git): qué guarda el stash,
-u/--include-untrackedyrefs/stash. - git-worktree, documentación oficial de Git (fuente en el repositorio git/git): una rama por worktree,
list/remove/pruney refs compartidas. - git-switch, documentación oficial de Git (fuente en el repositorio git/git): cambiar de rama solo se aborta si perderías cambios locales.
Preguntas Frecuentes
¿Qué diferencia hay entre git branch y git worktree?
Una rama es un puntero a un commit; un worktree es una carpeta donde una rama está en checkout.
¿Un stash creado en una carpeta se ve desde otro worktree?
Sí. El stash vive en refs/stash, que se comparte entre todos los worktrees del mismo repositorio. Lo comprobé creando un stash en la carpeta original y ejecutando git stash list en el worktree del hotfix: aparecía como stash@{0}: On feature/login: probando compartir.
¿Y si el hook de pre-commit no me deja hacer el commit WIP?
Un trabajo a medias rara vez pasa el lint. git commit --no-verify -m "WIP: login a medias" se salta los hooks de pre-commit y commit-msg solo para ese commit; los vuelves a pasar cuando rehaces el commit de verdad.
¿Cómo abro un worktree sobre una rama que ya existe?
Pasa la rama al final, sin -b:
$ git worktree add ../app-main main
Preparing worktree (checking out 'main')
HEAD is now at 3d728ac init
Funciona siempre que esa rama no esté ya sacada en otro worktree. Si lo está, Git se niega con fatal: 'main' is already used by worktree at ....