Capítulo 8 de 33 9 secciones 7 min

Cambiar de tarea a mitad de camino

Guardar lo que llevas sin hacer un commit del que te arrepientas

<code>git stash</code> guarda lo que llevas a medias en un cajón aparte y te deja la carpeta limpia. Sirve para cuando llega algo urgente y no quieres hacer un commit de algo a medio hacer, que es la otra opción y es peor. Después lo sacas del cajón con <code>git stash pop</code> 🧺

El problema

Estás a mitad del reporte de ventas por canal. No está terminado, no vale la pena guardarlo. Y entra un WhatsApp: hay que arreglar algo urgente ahora mismo.

Tienes tres opciones y dos son malas: hacer un commit de algo a medias y ensuciar la historia, o perder lo que llevas. La tercera es el cajón.

mkdir tienda
cd tienda
git init -q
printf 'ciudad,monto\nLima,1200\n' > ventas.csv
git add ventas.csv
git commit -q -m "Primeras ventas de Lima"
printf 'Arequipa,890\n' >> ventas.csv
printf 'reporte a medias\n' > reporte.txt
git status --short
 M ventas.csv
?? reporte.txt

Al cajón

git stash push -u -m "Reporte por canal a medias"
git status --short
ls
Saved working directory and index state On main: Reporte por canal a medias
ventas.csv

Carpeta limpia y reporte.txt desapareció. No se perdió: está guardado aparte, y ahora puedes hacer el arreglo urgente con el proyecto tal como estaba 🧹

Ese -u importa. Sin él, los archivos que Git todavía no conoce (los del capítulo 4, los untracked) se quedan en la carpeta y el cajón se los salta.

Ver qué hay en el cajón

git stash list
stash@{0}: On main: Reporte por canal a medias

Se pueden guardar varios y por eso llevan número. El {0} es el más reciente. Y el mensaje que pusiste con -m es lo que te salva cuando hay tres y no te acuerdas de cuál era cuál.

El arreglo urgente

printf 'canal,meta\nBodegas,8000\n' > metas.csv
git add metas.csv
git commit -q -m "Urgente, entran las metas por canal"
git log --oneline
464bcdd Urgente, entran las metas por canal
54da6e2 Primeras ventas de Lima

Y sacar lo tuyo del cajón

git stash pop
git status --short
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   ventas.csv

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	reporte.txt

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (7ceaf263a60cf80c5a2ff47271064704263079de)
 M ventas.csv
?? reporte.txt

Todo de vuelta, encima del arreglo urgente. pop saca y borra del cajón; apply saca y lo deja ahí por si acaso.

El error de sacar de un cajón vacío

git stash pop
No stash entries found.

Corto y claro. Si te sale esto y sabes que guardaste algo, casi siempre es que estás en otro repositorio: el cajón es de cada proyecto, no de la máquina.

La trampa

Guardas lo que llevas en el cajón, haces el arreglo urgente y te vas a almorzar. Al volver sigues con otra cosa, y a la semana te acuerdas del reporte.

$ git stash list

stash@{0}: On main: Reporte por canal
stash@{1}: On main: Prueba del IGV
stash@{2}: On main: WIP on main: 8a2b19c
stash@{3}: On main: WIP on main: 3c1f80a
stash@{4}: On main: WIP on main: 5d9c2f1
Qué está mal

El cajón se convirtió en un cementerio 🪦

El stash está pensado para minutos, no para semanas. Los tres de abajo ni siquiera tienen mensaje, porque se guardaron sin -m: dicen "WIP" y el hash del commit donde estabas, que dentro de una semana no le dice nada a nadie.

Y hay algo peor que el desorden: el stash no se sube a ningún lado. No viaja a GitHub, no lo ve nadie del equipo y no está en ninguna copia de seguridad. Si se malogra tu laptop, eso se va.

La regla que uso: si algo va a pasar la noche en el cajón, no va al cajón. Va a una rama con un commit, aunque el mensaje diga que está a medias.

Comprueba que se entendió

Comprueba que lo tienes

Llevas dos días de trabajo a medias y te vas de vacaciones. ¿Dónde lo dejas?

  • En el stash, que para eso está
  • En una rama, con un commit aunque esté a medias
  • Sin guardar, total nadie va a tocar la laptop
  • En el stash pero con un mensaje bien claro

Ejercicios

1. Guarda un cambio y limpia

Toca el CSV, mándalo al cajón y comprueba que la carpeta quedó limpia.

printf 'Cusco,760\n' >> ventas.csv
git stash push -m "Cusco pendiente de confirmar"
git status --short
cat ventas.csv
Saved working directory and index state On main: Cusco pendiente de confirmar
?? reporte.txt
ciudad,monto
Lima,1200

Cusco desapareció del archivo y el estado está limpio. Todo lo que había se fue al cajón de una pieza.

2. Mira el cajón

Lista lo que hay guardado.

git stash list
stash@{0}: On main: Cusco pendiente de confirmar

Un solo cajón, con el mensaje que le pusiste. Con dos o tres, este mensaje es la diferencia entre encontrarlo y adivinar.

3. Espía sin sacar

Mira qué hay dentro del cajón sin recuperarlo todavía.

git stash show -p stash@{0}
diff --git a/ventas.csv b/ventas.csv
index b5256c1..7a40551 100644
--- a/ventas.csv
+++ b/ventas.csv
@@ -1,2 +1,4 @@
 ciudad,monto
 Lima,1200
+Arequipa,890
+Cusco,760

La línea con + es lo que guardaste. Poder mirar antes de sacar evita el clásico "creo que era esto" 👓

4. Sácalo dejando copia

Usa apply en vez de pop y comprueba que el cajón sigue lleno.

git stash apply
git stash list
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   ventas.csv

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	reporte.txt

no changes added to commit (use "git add" and/or "git commit -a")
stash@{0}: On main: Cusco pendiente de confirmar

El cambio volvió a la carpeta y el cajón no se vació. Es lo que uso cuando no estoy segura de que ese cambio vaya a servir.

5. Vacía el cajón a mano

Tira el cajón que ya recuperaste.

git stash drop
git stash list
Dropped refs/stash@{0} (0e7503f345cc2eb7215b1d8e2e662dcfbb0929ca)

Sin salida porque ya no queda nada. drop borra uno, clear borra todos, y de esos dos no se vuelve 🧨

6. Guarda también lo que Git no conoce

Crea un archivo nuevo de clientes y guárdalo con -u, que es el que se lleva los desconocidos.

printf 'bodega,ciudad\nBodega Inti,Cusco\n' > clientes.csv
git stash push -u -m "Catalogo de clientes por revisar"
ls
Saved working directory and index state On main: Catalogo de clientes por revisar
metas.csv
ventas.csv

Sin el -u, ese archivo se habría quedado en la carpeta y el cajón lo habría ignorado. Es el olvido más común del stash.

7. Saca de un cajón que ya vaciaste

Recupera lo guardado y después intenta sacar otra vez.

git stash pop
git stash pop
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   ventas.csv

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	clientes.csv
	reporte.txt

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (d6bdabdc6e995952513e4eb6fd3940823b248fdf)
No stash entries found.

El primero funcionó y vació el cajón; el segundo no tiene de dónde sacar. Es la forma que tiene Git de decirte que ya recuperaste todo ✅

Lo que te llevas

El cajón es para minutos y solo existe en tu máquina. Para algo que va a dormir ahí, mejor un commit.

¿Tienes alguna duda o consulta?