Deshacer git add: quitar un archivo del staging sin miedo
Aprende a deshacer git add y sacar un archivo del staging sin perder tu trabajo. git restore --staged y git reset HEAD explicados paso a paso.
Acabas de escribir git add . sin pensarlo mucho. Miras git status y ahí está, en verde: un config.local.js con tu clave de API dentro, o la carpeta node_modules entera. Nada de eso debería acabar en el próximo commit. Y entonces llega la pregunta que aprieta de verdad: si lo saco de ahí, ¿pierdo lo que llevo escrito?
La respuesta corta es no. Deshacer un git add (lo que en inglés se llama unstage) no toca ni una línea de tu código. Aquí te enseño las dos formas de hacerlo, la moderna y la de siempre, y sobre todo cómo no confundirte con el único comando de esta familia que sí puede borrarte el trabajo.
Para seguir esto solo necesitas dos ideas. Una: un commit es una foto guardada de tu proyecto en un momento concreto. Dos: antes de sacar esa foto, tú eliges qué archivos entran en ella. Ese “elegir” es justo lo que hace git add.
¿Qué significa deshacer “git add”?
Deshacer git add es sacar un archivo del staging para que no entre en el próximo commit, sin tocar el archivo que estás editando. Ese es el punto que casi nadie te explica bien la primera vez.
Cuando ejecutas git add config.local.js, Git no mueve tu archivo a ningún sitio. Copia una instantánea de su estado actual a una zona intermedia que se llama staging area, o área de preparación. Piensa en el staging como la caja donde vas metiendo lo que quieres que salga en la próxima foto.
Deshacer ese git add es sacar la copia de la caja. El archivo original, el que tienes abierto en el editor, ni se entera. Sigue en tu carpeta con todos tus cambios dentro. Por eso unstage es una operación segura: cambia qué entrará en el próximo commit, nunca lo que hay en tu disco.
Si quieres el modelo mental completo de esta zona intermedia, lo desarrollo en qué es el área de staging de Git y cómo funciona.
Las tres zonas donde vive tu código
Git guarda tu trabajo en tres sitios distintos, y ubicarlos te ahorra casi todos los sustos. No hace falta que te los aprendas de memoria, solo que sepas dónde vive “staging”.
El working directory es tu carpeta de trabajo: los archivos que ves y editas. Cuando la IA te genera código o tú tecleas, vive aquí.
El staging area es la caja de la que hablábamos. Lo que hayas marcado con git add espera aquí a ser fotografiado en el próximo commit.
El repositorio es el historial de commits ya guardados, la sucesión de fotos que forman tu proyecto a lo largo del tiempo.
Con eso, el recorrido es fácil de leer. git add copia del working directory al staging. git commit guarda el staging en el repositorio. Deshacer un git add es solo el primer paso hacia atrás: del staging a la nada, porque tu archivo nunca salió del working directory. Lo único que quitas es la copia que habías metido en la caja.
La forma moderna: git restore —staged
Desde Git 2.23 (agosto de 2019) existe un comando pensado justo para esto: git restore --staged. Le dices qué archivo sacar del staging y lo saca, sin tocar nada más.
# Saca config.local.js del staging.
# Tus cambios dentro del archivo NO se tocan.
git restore --staged config.local.js
La mejor forma de convencerte es mirar el antes y el después con git status. Antes de deshacer nada, el archivo aparece bajo “Changes to be committed”, listo para entrar en el commit:
$ git status
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: config.local.js
modified: src/index.js
Fíjate en que el propio Git te chiva el comando entre paréntesis. Después de ejecutar git restore --staged config.local.js, ese archivo baja a la sección de cambios sin preparar:
$ git status
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
modified: config.local.js
El mismo archivo, con los mismos cambios dentro. Lo único que ha cambiado es que ya no entrará en el próximo commit. El flag --staged es la palabra clave: le dice a git restore que trabaje sobre el staging y no sobre tu carpeta. Guárdate ese detalle, porque dentro de un momento vas a ver qué pasa cuando se te olvida.
La forma de siempre: git reset HEAD
Antes de que existiera git restore, la manera de quitar algo del staging era git reset HEAD <archivo>, y sigue funcionando en cualquier versión de Git que te encuentres por delante.
# Misma operación, sintaxis clásica.
git reset HEAD config.local.js
HEAD es simplemente el nombre del último commit, tu punto de referencia. Le estás diciendo a Git: “vuelve a poner el staging como estaba en el último commit para este archivo”. El resultado es idéntico al de git restore --staged: el archivo sale del staging y tus ediciones se quedan donde están.
Verás un mensaje parecido a este:
$ git reset HEAD config.local.js
Unstaged changes after reset:
M config.local.js
Esa M significa “modified”. Git te está confirmando que el archivo sigue modificado en tu working directory. Justo lo que buscabas.
Puedes acortarlo a git reset config.local.js: si no dices desde dónde, Git asume HEAD. Y aquí va lo importante: git reset sin la palabra --hard no toca nunca tu working directory. Solo mueve lo que hay en el staging. Ese --hard es el que da miedo, y volvemos a él en un par de secciones.
Si te lías con cuándo toca reset, revert o restore, comparo los tres en las diferencias entre git reset, revert y restore.
Vaciar el staging entero de una vez
¿Y si hiciste git add . y quieres sacarlo todo de golpe, no un archivo suelto? Cambias el nombre del archivo por un punto, o no pones ninguno.
# Las dos vacían el staging completo.
git restore --staged . # forma moderna
git reset # forma clásica
git restore --staged . saca del staging todo lo que hubiera dentro. git reset a secas hace exactamente lo mismo. Ninguna de las dos borra una coma de tu código: después de ejecutarlas, git status te mostrará todos tus archivos otra vez como “changes not staged”, esperando a que decidas cuáles añadir de verdad.
Este es el patrón que más uso cuando un git add . se me va de las manos: vacío el staging entero y vuelvo a añadir solo los archivos que quiero, uno a uno. Cuesta diez segundos y evita el commit con basura dentro.
El comando que SÍ borra tu trabajo
Toda esta familia de comandos es segura menos una variante, y es justo la que más se parece a lo que acabas de aprender. Presta atención, porque un carácter separa “quitar del staging” de “perder una hora de trabajo”.
git restore config.local.js, sin --staged, no deshace un git add. Descarta los cambios sin preparar de tu working directory: restaura el archivo al contenido que hay en el staging (o, si no habías preparado nada, al del último commit) y sobrescribe la versión que estás editando. Todo lo que hubieras escrito y no estuviera ya en el staging desaparece, sin papelera y sin preguntar.
La única diferencia está en tres letras. Con --staged trabajas sobre el staging, y eso es seguro. Sin --staged trabajas sobre tu carpeta, y eso es destructivo. Léelo dos veces antes de dar a Enter.
| Comando | Qué hace | ¿Toca tus cambios en el archivo? | Cuándo usarlo |
|---|---|---|---|
git restore --staged <archivo> | Lo saca del staging | No, quedan intactos | Te equivocaste al hacer git add y quieres seguir editando |
git reset HEAD <archivo> | Lo saca del staging (forma clásica) | No | Lo mismo, en Git antiguos o por costumbre |
git restore <archivo> | Descarta tus cambios y restaura el archivo al contenido preparado en staging (o al último commit si no hay nada preparado) | Sí, los borra | Solo cuando quieres tirar a la basura lo que escribiste en ese archivo |
git reset --hard | Descarta staging y working directory de golpe | Sí, borra todo lo no guardado | Casi nunca; solo si estás seguro de perder todo lo no commiteado |
Errores comunes al deshacer git add
Confundir git restore con git restore --staged
Es el error de esta lista que de verdad duele. Los dos comandos empiezan igual, se autocompletan casi igual, y hacen cosas opuestas: uno protege tu trabajo, el otro lo borra. Antes de ejecutar cualquier git restore, comprueba que llevas el --staged si lo que quieres es sacar algo del staging.
Creer que unstage borra el archivo del disco
No lo borra. Sacar algo del staging no elimina el archivo de tu carpeta ni cierra tu editor. Sigue ahí, con tus cambios. Lo único que cambia es si entra o no en el próximo commit.
Usar git reset --hard para “limpiar” el add
Buscas “deshacer git add”, encuentras un git reset --hard en alguna respuesta antigua de un foro y lo pegas en la terminal. git reset --hard no quita archivos del staging con cuidado: arrasa el staging y el working directory hasta dejarlos como el último commit. Todo lo que no habías guardado, incluido lo que sí querías conservar, se va. Para deshacer un git add nunca necesitas --hard.
Lanzar git checkout . en modo pánico
El viejo git checkout . descarta cambios igual que git restore sin --staged. Si no sabes exactamente qué hace, no lo uses para “arreglar” un add. Mira primero git status: siempre te ofrece el comando seguro entre paréntesis.
Practica el flujo hasta que deje de asustar
La forma de que esto deje de darte respeto es hacerlo con las manos unas cuantas veces, en un repositorio de prueba donde no pase nada si te equivocas. Eso es exactamente lo que trabajas en el curso de Git de cero a profesional: staging, commits y cómo deshacer cada paso sin sudar.
Si quieres, te aviso cuando publique guías nuevas como esta:
Un concepto nuevo cada semana
Preguntas Frecuentes
¿Pierdo mis cambios si deshago un git add con git restore —staged?
No. git restore --staged <archivo> solo saca la copia del staging. Tus ediciones siguen exactamente igual en el working directory, listas para que las vuelvas a añadir cuando quieras. Es una de las operaciones más seguras de Git.
¿Es peligroso git reset a secas?
No, mientras no le pongas --hard. git reset sin más vacía el staging entero y deja tu working directory intacto. El único reset que borra trabajo sin guardar es git reset --hard, que sí toca tu carpeta.
¿Cuál uso para deshacer git add, restore o reset?
git restore --staged es más claro y difícil de confundir, porque el nombre del comando dice justo lo que hace. Úsalo si tienes Git 2.23 o superior, que es casi seguro. git reset HEAD hace lo mismo y funciona en cualquier versión, así que también sirve si tu equipo va con un Git antiguo o simplemente te sale de memoria.
Hice git add . y solo quiero sacar un archivo, ¿puedo?
Sí. Nombra el archivo concreto en vez de usar el punto: git restore --staged config.local.js saca ese y deja el resto del staging tal cual. El punto significa “todo”, así que solo lo usas cuando quieres vaciar el staging entero.
¿Y si ya hice el commit, no solo el git add?
Eso ya es otro problema. Deshacer un commit no es lo mismo que deshacer un git add: el commit ya guardó la foto en el historial, mientras que el add solo la tenía en la caja. Tienes el mapa completo de cómo revertir casi cualquier cosa en Git, incluidos los commits, en la guía para deshacer cambios en Git.