Guía

git stash: cómo guardar cambios temporalmente y recuperarlos

Actualizado: · Skillaria.Top

git stash guarda los cambios sin commit en un almacén aparte y devuelve el directorio de trabajo al último commit para que puedas cambiar de tarea. Los cambios se recuperan con git stash pop (aplicar y borrar del almacén) o git stash apply (aplicar y conservar); no existe un comando git unstash.

Para qué sirve git stash

Una situación típica: estás a mitad de una tarea, tienes archivos modificados, aún es pronto para el commit, y te piden corregir con urgencia un bug en otra rama. No puedes cambiar de rama o te da miedo perder los cambios. git stash guarda «en el bolsillo» todos los cambios sin commit y devuelve el directorio de trabajo al estado del último commit.

$ git stash
Saved working directory and index state WIP on feature/login: 3f2a1c4 Formulario de acceso

$ git status
On branch feature/login
nothing to commit, working tree clean

Ahora puedes cambiar de rama, corregir el bug, volver y sacar lo guardado. Cada guardado es una entrada en la pila de stash; internamente Git la almacena como un commit especial, así que los datos son fiables y no dependen de la rama.

Cómo guardar cambios: opciones principales

Con una descripción clara

La descripción estándar «WIP on rama» no te dirá nada dentro de una semana. Ponle nombre:

git stash push -m "validación del formulario, falta el e-mail"

git stash sin argumentos es la forma abreviada de git stash push. La forma antigua git stash save "mensaje" aún funciona, pero en los casos nuevos usa push -m.

Incluyendo archivos nuevos

Por defecto, stash solo se lleva los archivos con seguimiento: modificados y añadidos al índice. Los archivos nuevos que nunca pasaron por git add se quedan en el directorio de trabajo. Es una sorpresa frecuente.

git stash -u        # --include-untracked: más los archivos sin seguimiento
git stash -a        # --all: más los archivos de .gitignore

Cuidado con -a: al bolsillo irán también node_modules, los builds y las configuraciones locales. Normalmente basta con -u.

Solo una parte de los cambios

git stash push -m "config" src/config.js   # solo los archivos indicados
git stash -p                                # elegir fragmentos de forma interactiva
git stash --staged                          # solo lo que está en el índice (Git 2.35+)
git stash --keep-index                      # guardar todo, pero dejar el índice en el directorio

--keep-index es útil antes de un commit: dejas en el directorio de trabajo solo lo que vas a incluir, pasas los tests y compruebas que el commit es autosuficiente.

Cómo recuperar los cambios (git unstash)

El comando git unstash no existe en Git; así suele buscarse la forma de sacar lo guardado. Para ello hay dos comandos.

ComandoQué haceEntrada en la pila
git stash popAplica los últimos cambios guardadosSe borra si se aplicó sin conflictos
git stash applyAplica los últimos cambios guardadosSe conserva
git stash pop stash@{2}Aplica una entrada concretaSe borra
git stash apply --indexRestaura también la separación entre índice y directorio de trabajoSe conserva
$ git stash pop
On branch feature/login
Changes not staged for commit:
        modified:   src/auth.js
        modified:   src/form.js
Dropped refs/stash@{0} (8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d)

Ojo: por defecto, incluso lo que estaba en el índice al hacer stash vuelve como cambios normales. Si te importa conservar el índice preparado, añade --index.

¿pop o apply?

Para el día a día es cómodo pop: lo sacas y te olvidas. Elige apply cuando quieras aplicar los mismos cambios en varias ramas o no estés seguro de que todo vaya a salir bien: la entrada se queda como seguro y luego puedes borrarla con git stash drop.

Trabajar con la lista de stash

$ git stash list
stash@{0}: On feature/login: validación del formulario, falta el e-mail
stash@{1}: WIP on main: 9b7e0d2 Actualizar dependencias
stash@{2}: On feature/api: experimento con la caché

La pila funciona según «el último en entrar es el primero en salir»: stash@{0} es siempre la entrada más reciente, y los números se desplazan tras cada push y drop.

ComandoPara qué sirve
git stash showEstadística resumida de los cambios de la última entrada
git stash show -p stash@{1}Diff completo de una entrada concreta
git stash drop stash@{1}Borrar una entrada
git stash clearBorrar todas las entradas de golpe
git stash branch nombre stash@{0}Crear una rama desde el commit en el que se hizo el stash, aplicar la entrada y borrarla

Para que git stash show muestre por defecto el diff completo en vez de la estadística, e incluya los archivos sin seguimiento, existen los ajustes stash.showPatch y stash.showIncludeUntracked.

Paso a paso: un bug urgente en mitad de una tarea

  1. Guarda el trabajo actual junto con los archivos nuevos: git stash push -u -m "login: borrador".
  2. Cambia a la rama principal y crea una rama para la corrección: git switch main, git pull, git switch -c hotfix/null-email.
  3. Corrige el error, haz commit y envíalo a revisión.
  4. Vuelve a la tarea: git switch feature/login.
  5. Recupera los cambios: git stash pop. Comprueba git status: todo está en su sitio.

Hoy muchos usan git worktree para este escenario: un segundo directorio de trabajo del mismo repositorio permite no guardar nada. Pero para un cambio rápido de cinco minutos, stash sigue siendo más sencillo.

Conflictos al aplicar un stash

Si después del stash cambiaron en la rama las mismas líneas, la aplicación terminará en conflicto:

$ git stash pop
Auto-merging src/auth.js
CONFLICT (content): Merge conflict in src/auth.js
The stash entry is kept in case you need it again.

En ese caso la entrada no se borra, ni siquiera con pop. Resuelve el conflicto en el archivo como de costumbre, luego ejecuta git add para marcarlo como resuelto (o git restore --staged si no quieres dejar los cambios en el índice) y borra la entrada que ya no necesitas con git stash drop.

Si el conflicto es complicado, hay un atajo más cómodo: git stash branch tmp-login. Git creará una rama a partir del mismo commit en el que hiciste el stash; allí los cambios se aplicarán sin conflictos, y luego los integrarás con la rama principal mediante un merge normal.

Cómo recuperar un stash borrado por error

¿Has ejecutado git stash drop o clear por error? No está todo perdido. La entrada era un commit y, mientras el recolector de basura no lo elimine, se puede encontrar entre los objetos «colgantes»:

git fsck --no-reflog | grep "dangling commit"
git show 8c1d2e3        # comprobar que es el stash correcto
git stash apply 8c1d2e3

Si acabas de borrar la entrada con drop o pop, el hash aparece directamente en la salida del comando, en la línea Dropped refs/stash@{0} (...). Basta con pasárselo a git stash apply.

Cómo funciona stash por dentro

Entender cómo funciona quita el miedo a perder datos. Cada entrada de stash es un commit normal al que apunta la referencia refs/stash. Tiene dos padres: el commit HEAD en el que estabas y un commit aparte con el estado del índice. Con -u se añade un tercer padre con los archivos sin seguimiento. La lista stash@{N} no es más que el registro (reflog) de la referencia refs/stash.

De ahí salen varias consecuencias prácticas. Puedes pasar un stash a cualquier comando que acepte un commit: git diff stash@{0}, git show stash@{0}:src/auth.js (el contenido de un archivo de la entrada) o git checkout stash@{0} -- src/auth.js para sacar un solo archivo sin aplicar toda la entrada. Y una entrada borrada sigue en la base de objetos hasta que la elimine la recolección de basura.

Stash y otros comandos de Git

Algunos comandos saben guardar los cambios por sí solos. git rebase --autostash y git pull --rebase --autostash apartan los cambios sin commit antes de empezar y los devuelven al terminar. Puedes activar este comportamiento de forma permanente con los ajustes rebase.autoStash true y merge.autoStash true. Si al devolverlos surge un conflicto, Git guardará la entrada en la pila de stash normal y te avisará.

Cambiar de rama con git switch tampoco siempre requiere stash: si tus cambios no afectan a archivos que difieren entre las ramas, Git simplemente se los lleva contigo. Stash hace falta cuando Git responde «Your local changes would be overwritten by checkout» o cuando no quieres llevar los cambios a otra rama.

Errores habituales

  • Los archivos nuevos «no se guardaron». No tienen seguimiento; hace falta -u.
  • Usar stash como almacén a largo plazo. Al cabo de un mes hay en la lista diez «WIP on main» sin nombre y nadie recuerda qué contienen. Para trabajos largos haz un commit en una rama aparte: al menos se puede subir al servidor.
  • Olvidar que la entrada se quedó tras un conflicto y aplicarla otra vez tiempo después. Tras resolver el conflicto, haz siempre drop.
  • Stash no se sincroniza con el servidor. Solo se guarda en tu repositorio local; git push no lo envía. Si borras la carpeta del proyecto, el stash desaparece.
  • Aplicar la entrada equivocada. Antes de pop, revisa git stash list y git stash show -p.

Conclusión

git stash es una forma rápida de liberar el directorio de trabajo sin perder los cambios sin commit: git stash push -u -m "descripción" para guardarlos y git stash pop para recuperarlos. Usa apply cuando quieras un seguro, git stash list y show -p para no perderte, y no conviertas stash en un trastero: para todo lo que dure más están los commits y las ramas. Cambiar de tarea con stash se practica en el curso de Git.

Preguntas frecuentes

¿Se puede aplicar un stash en otra rama?

Sí, stash no está ligado a una rama: cambia a la que necesites y ejecuta git stash pop o apply. Si los cambios no encajan, aparecerá un conflicto normal.

¿git stash guarda los cambios del índice?

Los guarda, pero con un pop o apply normal todo vuelve como cambios sin preparar. Para restaurar también el índice, usa git stash apply --index.

¿Cuántas entradas se pueden guardar en stash?

No hay un límite estricto, pero las entradas más antiguas que el plazo de retención del reflog pueden eliminarse en la recolección de basura. En la práctica, no tengas en la pila más de un par de entradas recientes.

¿Cómo hacer stash de un solo archivo?

Indica la ruta tras dos guiones o directamente después de push: git stash push -m descripción -- src/config.js. Solo ese archivo irá al stash; el resto de cambios se quedan en el directorio de trabajo.

¿En qué se diferencia stash de un commit temporal?

Un commit vive en una rama, se puede subir al servidor y corregir después con amend o rebase. Stash se guarda solo en local, en una pila aparte, y es cómodo para cambios de tarea breves.

Aprende este tema en vídeo

Este tema se explica a fondo y con práctica en el curso «Git desde cero hasta desarrollador seguro».

Ir al curso