git stash: guarda cambios sin hacer commit
Aprende a usar git stash para guardar cambios a medias, cambiar de rama sin perder trabajo y recuperarlo después con pop y apply.
Estás a media tarea. Llevas veinte minutos con un formulario de login medio escrito y tu compañero te escribe: «¿puedes mirar un bug urgente en main?». Haces git switch main para cambiar de rama y Git te frena en seco con un your local changes would be overwritten. No quieres hacer un commit con la mitad del trabajo hecho, pero necesitas cambiar de rama ya. Aquí es donde entra git stash: guarda tus cambios sin confirmar, te deja el directorio limpio y te devuelve el trabajo cuando vuelves.
Para seguir este post necesitas saber hacer add, commit y cambiar de rama con git switch. Poco más. Si quieres el mapa completo de cómo gestionar cambios en Git, tienes la guía general para deshacer y mover cambios.
¿Qué es git stash y cuándo lo necesitas?
git stash es un cajón temporal para el trabajo que tienes a medias. Coge todos los cambios sin confirmar de tu rama, los aparta a un lado y te deja el directorio de trabajo como estaba en el último commit. El código no se pierde: queda guardado, listo para que lo recuperes cuando quieras.
La escena típica es la del principio. Estás con una tarea y aparece algo más urgente en otra rama. Git no te deja saltar de rama si los cambios que llevas encima pisarían archivos de la rama de destino. Tienes dos salidas malas y una buena. La mala rápida es hacer un commit con el trabajo a medias, que ensucia el historial con un «wip a medias» que luego tienes que deshacer. La mala lenta es copiarte los archivos a mano en otra carpeta. La buena es git stash.
# Estás a media tarea en la rama feature/login
$ git status
On branch feature/login
Changes not staged for commit:
modified: src/login.ts
# Intentas cambiar a main para revisar el bug urgente
$ 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.
Fíjate en la última línea del error: el propio Git te sugiere stash them. El caso de uso número uno es exactamente ese, cambiar de rama con cambios sin guardar. Si aún no tienes claro cómo van las ramas, te vendrá bien el post sobre ramas en Git: crear, cambiar y fusionar antes de seguir.
¿Cómo guardo mis cambios con git stash?
Guardas los cambios con git stash a secas, o mejor con git stash push -m "mensaje" para ponerle un nombre. Ambos hacen lo mismo: apartan lo que tienes modificado y dejan el árbol limpio. La diferencia es que con -m le pones una etiqueta para reconocerlo después.
# Guarda lo que tienes a medias y le pone un nombre
$ git stash push -m "wip formulario de login"
Saved working directory and index state On feature/login: wip formulario de login
# Ahora el directorio está limpio, como en el último commit
$ git status
On branch feature/login
nothing to commit, working tree clean
Con el árbol limpio, ya puedes cambiar de rama sin que Git proteste. Revisas el bug en main, haces lo que tengas que hacer y vuelves a tu rama.
# Con el árbol limpio, cambias de rama sin problemas
$ git switch main
# ...revisas el bug urgente, arreglas lo que sea...
# Y cuando terminas, vuelves a tu rama de siempre
$ git switch feature/login
Una cosa importante: git stash guarda tanto lo que tienes en el staging area (lo que ya habías hecho git add) como lo que solo tienes modificado sin añadir. Recupera ambos estados. Lo que no guarda por defecto son los archivos nuevos que Git todavía no conoce, pero eso lo vemos más abajo porque es el error más común.
¿Cómo recupero lo que guardé? pop vs apply
Para recuperar el trabajo tienes dos comandos y la diferencia entre ellos es la que más lía a la gente. git stash pop aplica el último stash y lo borra de la lista. git stash apply aplica el mismo estado pero deja el stash guardado.
# Recupera lo último que guardaste Y lo borra de la lista
$ git stash pop
On branch feature/login
Changes not staged for commit:
modified: src/login.ts
Dropped refs/stash@{0} (3f2a9c1d8b4e5f6a7c9d0e1f2a3b4c5d6e7f8a9b)
pop es el que usarás casi siempre: recuperas el trabajo y limpias el stash de una vez. Usa apply cuando quieras aplicar el mismo trabajo en varios sitios, por ejemplo probar los mismos cambios en dos ramas distintas, porque así el stash sigue disponible para volver a aplicarlo.
Hay un detalle que conviene saber antes de que te muerda: si al hacer pop aparece un conflicto de merge, Git no borra el stash. Se queda en la lista para que no pierdas nada mientras resuelves el conflicto a mano. Después tendrás que borrarlo tú con git stash drop.
¿Cómo veo todo lo que tengo guardado?
git stash list muestra todos los stashes que tienes, del más reciente al más antiguo. Cada uno tiene un identificador con el formato stash@{n}, donde stash@{0} es siempre el último que guardaste.
$ git stash list
stash@{0}: On feature/login: wip formulario de login
stash@{1}: WIP on main: 9cc0589 Ajusta el README
Ahí ves por qué merece la pena el -m. El primero tiene un nombre que entiendes de un vistazo. El segundo es el mensaje automático que pone Git cuando guardas sin etiqueta, con el hash del commit y su título. Cuando tienes tres o cuatro stashes, el de arriba es oro.
Si quieres recuperar uno que no es el último, le pasas su identificador al comando:
# Aplica un stash concreto (no el último) sin borrarlo
$ git stash apply stash@{1}
# Cuando ya no lo necesites, lo borras tú
$ git stash drop stash@{1}
Dropped stash@{1} (a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0)
Aquí tienes de un vistazo qué hace cada comando y si toca o no la lista de stashes:
| Comando | Qué hace | ¿Borra el stash? |
|---|---|---|
git stash apply | Aplica los cambios guardados sobre tu directorio actual | No, lo mantiene en la lista |
git stash pop | Aplica los cambios y borra ese stash de la lista | Sí, salvo que haya un conflicto |
git stash list | Muestra todos los stashes guardados | No, solo lee |
git stash drop stash@{n} | Borra un stash concreto sin aplicarlo | Sí |
La trampa de los archivos sin trackear
Un archivo sin trackear es un archivo nuevo que has creado pero al que nunca le has hecho git add. Git sabe que existe, pero todavía no lo controla. Y aquí está la trampa oculta de git stash: por defecto no guarda esos archivos[1].
Imagina que además de modificar login.ts has creado un login.test.ts nuevo que aún no habías añadido. Si haces git stash normal, login.ts se guarda y desaparece del directorio, pero login.test.ts se queda ahí, a la vista, sin guardar. La primera vez que pasa asusta, porque parece que el stash se ha «dejado» algo.
La solución es la opción -u, abreviatura de --include-untracked:
# -u incluye también los archivos nuevos sin trackear
$ git stash push -u -m "wip login con tests nuevos"
Saved working directory and index state On feature/login: wip login con tests nuevos
Regla mental sencilla: si has creado archivos nuevos y quieres apartarlos también, usa -u. Si solo has tocado archivos que Git ya controlaba, el git stash normal te vale.
Ya tienes todas las piezas: guardar, cambiar de rama y recuperar. Antes de repasar los errores típicos, prueba el flujo completo con tus propias manos en este ejercicio interactivo:
Cargando ejercicio...
Errores comunes al usar stash
Esperar que el stash guarde tus archivos nuevos
Es el que acabamos de ver y el que más sustos da. Guardas con git stash, cambias de rama, vuelves, haces pop… y ese componente nuevo que habías empezado no estaba en el stash porque nunca hiciste git add. No se ha perdido, sigue en tu directorio, pero no viajó contigo. Cuando dudes, git stash push -u.
Acumular stashes anónimos hasta perderte
Si guardas siempre con git stash a pelo, sin mensaje, acabas con una lista de WIP on ... todos iguales y no tienes ni idea de cuál es cuál. Coge la costumbre de usar git stash push -m "algo descriptivo" desde el principio. Tu yo de dentro de dos días te lo agradecerá cuando abra git stash list y lea «wip formulario de login» en vez de líneas idénticas.
Usar pop cuando querías apply
Si vas a aplicar el mismo stash en más de un sitio, pop te lo borra a la primera y te quedas sin él. Y si pop te da un conflicto y lo resuelves mal, puedes acabar con un lío difícil de recuperar. Cuando no lo tengas claro, usa git stash apply, comprueba que todo está bien y solo entonces borra el stash con drop.
Tratar el stash como almacén a largo plazo
El stash es un cajón temporal para pasar de una tarea a otra, no un sitio donde dejar trabajo durante semanas. Cuanto más tiempo pasa, más cambia la rama por debajo y más probable es que al recuperarlo tengas conflictos. Si algo tiene que durar, va en una rama o en un commit. Y si lo que buscas es deshacer cambios en lugar de aparcarlos, ese es otro terreno: lo cubre el post sobre las diferencias entre reset, revert y restore.
Checklist rápido de git stash
- Guardas con
git stash push -m "mensaje"para poder reconocerlo después - Usas
-ucuando tienes archivos nuevos sin trackear que también quieres apartar - Compruebas el estado con
git status(limpio) antes de cambiar de rama - Recuperas con
git stash poppara el caso normal (recuperar y borrar) - Usas
git stash applycuando quieres conservar el stash tras aplicarlo - Revisas
git stash listpara no acumular stashes olvidados - No dejas trabajo importante en el stash durante días: para eso, una rama o un commit
Practica el flujo de Git en un curso guiado
git stash se asienta cuando lo usas con las manos, no solo leyéndolo. En el curso Git de cero a profesional practicas stash, ramas, commits y el resto del flujo diario con ejercicios interactivos, sin miedo a romper nada en un repositorio de verdad.
Si prefieres ir a tu ritmo, apúntate abajo y te aviso cuando publique más guías de Git como esta.
Un concepto nuevo cada semana
Fuentes
- Documentación oficial de git stash (git-scm.com): comportamiento por defecto, opciones
-u/--include-untracked, y diferencia entrepop,apply,listydrop.
Preguntas Frecuentes
¿git stash borra mis cambios?
No. git stash aparta tus cambios y limpia el directorio, pero los guarda para que los recuperes con git stash pop o git stash apply. Sí hay comandos que borran un stash: git stash drop (o git stash clear, que los borra todos) lo elimina sin aplicarlo, y git stash pop también lo borra, pero solo después de aplicarlo con éxito (si hay conflicto, no lo borra).
¿El stash se comparte cuando hago push?
No. El stash es local a tu repositorio y git push no lo sube a ninguna parte. Solo se transfieren commits, así que si necesitas compartir un trabajo a medias con alguien, tienes que hacer un commit en una rama y subir esa rama.
¿Puedo tener varios stash a la vez?
Sí, puedes tener tantos como quieras. Cada git stash nuevo se apila encima y git stash list te los muestra numerados como stash@{0} (el más reciente), stash@{1}, y así sucesivamente. Por eso conviene ponerles nombre con -m, para no perderte entre varios.
¿Qué pasa con el stash si cambio de rama?
Nada, el stash no está atado a la rama en la que lo creaste: puedes guardar en una, cambiar a otra y hacer git stash pop allí para llevarte esos cambios sin pasar por un commit.
¿Cómo borro un stash que ya no necesito?
Con git stash drop stash@{n}, poniendo el identificador del stash que ves en git stash list. Si quieres vaciar el cajón entero de una vez, git stash clear los borra todos. Ojo, un stash borrado es difícil de recuperar, así que asegúrate antes de que ya no lo necesitas.