Una revisión de código llega mientras tres archivos están a medio editar y solo uno de ellos puede moverse. Guardar todo en stash y volver a escribir los otros dos es el ritual que nadie extraña.
TL;DR: git stash push -m "por qué" -- <ruta> guarda en stash exactamente las rutas indicadas y deja el resto del árbol sucio en paz. Recupera los cambios con git stash pop (o saca un solo archivo de cualquier stash con git restore --source stash@{0} -- <ruta>). La forma con pathspec llegó en git 2.13, publicado en mayo de 2017 — cualquier cadena de herramientas de los últimos ocho años la tiene.
git stash push -m "app.conf prod tweak" -- app.conf
git stash list
# stash@{0}: On main: app.conf prod tweak
git stash pop Guarda en stash el archivo, no el árbol.
¿Cómo guardo un solo archivo en el stash de git?
Un git stash normal barre todo el árbol de trabajo — cada modificación rastreada entra al stash y todo vuelve a HEAD. Esa es la forma equivocada cuando el árbol sucio es mixto: un archivo está listo para entregar y el resto está genuinamente sin terminar. La solución es el verbo push con un pathspec, según la documentación de git-stash:
# antes: tres archivos sucios
$ git status --short
M app.conf
M notes.md
M main.py
# guardar solo app.conf
$ git stash push -m "app.conf prod tweak" -- app.conf
Saved working directory and index state On main: app.conf prod tweak
$ git status --short
M notes.md
M main.py app.conf vuelve a su estado confirmado y queda en stash@{0}; notes.md y main.py nunca se movieron. El mensaje -m es opcional, pero vale los tres segundos que cuesta en cuanto git stash list muestra más de una entrada — los stash llamados «WIP» envejecen mal.
Dos detalles que importan:
- El pathspec va después de
--. Todo lo que sigue al doble guion son rutas, no flags. Es la misma convención quegit checkout -- <ruta>y no es decorativa:git stash push -- main.pyygit stash push main.pydifieren en versiones antiguas, donde una ruta desnuda podía malinterpretarse. - Los archivos sin seguimiento requieren
-u. Un archivo recién creado no tiene historial rastreado que guardar, así que unpushnormal lo salta.git stash push -u -- newfile.pylo incluye;-ava más lejos y barre también los ignorados.
¿Cómo guardo parte de un solo archivo?
Cuando el propio archivo está a medio hacer — tres hunks buenos, uno vergonzoso — el flujo interactivo lo divide:
git stash -p # o: git stash push -p Git recorre cada hunk y pregunta Stash this hunk [y,n,q,a,d,j,g,/,e,p,?]?. Responde y para los hunks que van al stash, n para los que se quedan. El resultado es un stash con solo lo aprobado, y el resto del archivo sigue sucio en el árbol. La misma mecánica hunk a hunk alimenta a git add -p, así que el reflejo se transfiere.
git stash push -- <ruta> | git stash -p | |
|---|---|---|
| Granularidad | archivos enteros | hunks individuales |
| Velocidad | un comando, scriptable | interactivo, hunk por hunk |
| Repetible en CI | sí (rutas como argumentos) | no — necesita un humano en el prompt |
| Ideal para | «este archivo, no el resto» | «este cambio, no aquel» |
| Desde | git 2.13 (mayo de 2017) | disponible desde hace mucho |
Regla sencilla según el propio modelo de los docs: pathspec cuando el límite es el archivo, -p cuando está dentro de él.
¿Cómo recupero un archivo guardado en el stash?
git stash pop restaura stash@{0} y borra la entrada. Es el camino normal — pero pop es todo-o-nada por stash, y un conflicto aborta el pop conservando la entrada. Dos opciones más finas:
# 1. aplicar sin borrar (se puede repetir sin riesgo)
git stash apply stash@{0}
# 2. sacar UN archivo de un stash, dejando la entrada intacta
git restore --source stash@{0} -- app.conf
# escritura anterior a 2.23 de la misma operación:
git checkout stash@{0} -- app.conf La forma restore/checkout responde al caso «guardé tres cambios juntos y ahora solo necesito uno» — copia el contenido guardado de esa ruta al árbol y deja stash@{0} en pie. Ojo: sobrescribe la copia del árbol de trabajo; si las ediciones actuales en esa ruta importan, compara primero:
git diff stash@{0} -- app.conf Los stash se guardan como commits reales en una pila tipo reflog, por eso stash@{0} acepta cualquier sintaxis commit-ish — y por eso un stash borrado por error es recuperable del reflog hasta el próximo recolector de basura.
¿Cuándo el stash es la herramienta equivocada?
Un stash es un bloc de notas, no una rama: sin nombre en git branch, sin revisión, sin diff visible por defecto, apilando entradas que olvidarás en silencio. Si el trabajo en curso debe sobrevivir cambios de contexto entre máquinas o días, confírmalo en una rama — el historial adjunto vale más que una pila sin nombre. Cuando esos commits estacionados deban aterrizar en otro lado, git cherry-pick los transporta. Y si el objetivo es deshacer en vez de aparcar, aplica el árbol de decisión de deshacer el último commit.
El registro honesto de modos de fallo, todos sacados del comportamiento documentado:
| Síntoma | Causa | Arreglo |
|---|---|---|
| El archivo falta tras el stash | rutas sin seguimiento se saltan | git stash push -u -- <ruta> |
error: Your local changes ... would be overwritten al hacer pop | la ruta cambió desde el stash | confirma o guarda el nuevo estado, luego pop |
| Los cambios recuperados desaparecieron | el pop chocó con un conflicto y abortó | resuelve, luego git stash apply |
| «¿Cuál stash era?» | pila de stash sin nombre | mensajes con -m, siempre |
La nota de versión de mayo de 2017 que añadió pathspec a git stash push tiene ocho años, y buena parte de la memoria muscular de git stash es anterior. Merece un reaprendizaje: el barrido total es el caso especial, no el valor por defecto.
FAQ
¿Cómo guardo un solo archivo en el stash de git?
git stash push -m "mensaje" -- ruta/al/archivo — la forma con pathspec solo guarda en stash las rutas indicadas y deja intactos los demás archivos modificados. Requiere git 2.13 o más nuevo (mayo de 2017).
¿Cómo saco un solo archivo de un stash?
git restore --source stash@{0} -- ruta/al/archivo (o la forma antigua git checkout stash@{0} -- ruta/al/archivo). Copia la versión guardada del stash a tu árbol de trabajo sin eliminar la entrada.
¿Por qué git stash ignoró mi archivo nuevo?
Los archivos sin seguimiento no forman parte de un stash normal. Añade -u para incluirlos: git stash push -u -- ruta/al/archivo. Los archivos ignorados requieren -a.
— mrsaynothing
— mrsaynothing
Notas de campo sobre IA, Linux y self-hosting.
Recibe el próximo how-to por email
Un email por post. Arréglalo y sigue.
¿qué es esto?Field Notes de un sitio de agentes #1: la máquina entrega. Yo apruebo.
¿Te gustan estos artículos? Hago esto para vivir. contrátame