Introducción
Aprende a deshacer cambios y commits en Git con checkout, restore, reset, revert, clean y amend, con ejemplos claros y cuándo usar cada comando.

A diferencia de la mayoría de los editores, Git no tiene un botón único de "deshacer". En su lugar, ofrece un conjunto pequeño de comandos, cada uno dirigido a un lugar diferente donde vive tu trabajo: el directorio de trabajo (los archivos en disco), el índice de preparación (los cambios marcados para el próximo commit) y el historial de commits (las instantáneas ya registradas). Elegir el comando correcto depende de cuál de esas tres áreas quieres revertir y de si el cambio ha sido compartido con alguien más.
Esta página cubre el kit de herramientas completo: revisar el historial, restaurar archivos y deshacer uno o varios commits — con git checkout, git restore, git reset, git revert, git clean y git commit --amend.
Elegir el comando correcto
Antes de cualquier comando específico, conviene saber qué área toca cada uno y si reescribe el historial:
| Objetivo | Comando | ¿Seguro para compartir? |
|---|---|---|
| Descartar ediciones en un archivo rastreado | git restore <file> (o git checkout -- <file>) | sí |
| Quitar un archivo del área de preparación | git restore --staged <file> (o git reset HEAD <file>) | sí |
| Eliminar archivos sin rastrear | git clean | sí |
| Corregir el commit más reciente | git commit --amend | solo si no se ha enviado |
| Mover la rama a un commit anterior | git reset | solo en local |
| Cancelar un commit añadiendo uno inverso | git revert | sí |
La regla más importante: reset y amend reescriben el historial, así que úsalos únicamente en commits que no hayas enviado. Para cualquier cosa ya compartida, usa revert.
Revisar commits anteriores
No puedes deshacer lo que no puedes encontrar. La mejor herramienta para revisar el historial es git log. Cada commit tiene un hash identificador que usas para referenciarlo:
git log --oneline
a3b2a21 Crossword solver with Vue.js
c54ce02 New logic for crossword game
3acb8d0 Some changes in crossword logic
de32112 Styling crossword table areaPor defecto, git log muestra solo los commits accesibles desde la rama actual. Para ver commits de todas las ramas, añade --all. Usa git checkout o git switch para visitar otras ramas.
Ver una revisión antigua
Para inspeccionar el proyecto tal como lucía en un momento anterior, primero encuentra el hash de la revisión que deseas:
git log --oneline
b7119f2 Changes in Scrabble Solver
234be24 Fixing search input bug
b235bf4 Make some changes to solver.php
256a81c Create solver.php
3243e12 Initial changesLuego extrae ese commit por su hash:
git checkout b235bf4Ahora puedes explorar archivos, ejecutar pruebas e incluso editar cosas. Nada de lo que hagas aquí se registra en una rama, por lo que tu trabajo actual está a salvo. Este estado temporal se llama HEAD desconectado — HEAD apunta directamente a un commit en lugar de al extremo de una rama. Regresa a tu rama cuando hayas terminado:
git switch - # or: git checkout masterUna vez de vuelta en tu rama, usa git revert o git reset para deshacer cualquier cambio que desees.
Deshacer una instantánea confirmada
Hay varias formas de deshacer un commit. La correcta depende de si el commit ha sido compartido. Imagina que nuestro historial tiene este aspecto:
git log --oneline
863fa8e Making some improvements
b235bf4 Make some changes to solver.php
256a81c Create solver.php
3243e12 Initial changesLas secciones siguientes deshacen el commit 863fa8e Making some improvements de tres formas distintas.
Con git checkout (inspeccionar sin cambiar la rama)
Hacer checkout del commit anterior, b235bf4, pone el repositorio en el estado anterior al commit de mejoras:
git checkout b235bf4Este es un desvío de solo lectura, no una reversión real: aterrizas en un estado de HEAD desconectado. Cualquier commit nuevo que hagas aquí quedará huérfano en cuanto regreses a una rama establecida, y el recolector de basura de Git podría eliminarlo con el tiempo. Para conservar el trabajo realizado desde este estado, crea una rama a partir de él:
git checkout -b improvements-removedAhora tienes una nueva rama, improvements-removed, cuya línea de tiempo nunca incluyó 863fa8e. Checkout es mejor para observar un estado antiguo; los dos comandos siguientes deshacen el commit de verdad.
Con git revert (la reversión segura y compartible)
git revert HEAD crea un nuevo commit que aplica el inverso del commit objetivo. Nada se borra — el historial avanza hacia adelante:
git revert HEADTras ejecutarlo, el registro tiene este aspecto:
git log --oneline
23a4b42 Revert "Making some improvements"
863fa8e Making some improvements
b235bf4 Make some changes to solver.php
256a81c Create solver.php
3243e12 Initial changesEl efecto de 863fa8e queda cancelado, aunque el commit sigue en el historial; 23a4b42 simplemente revierte sus cambios. Como nada se reescribe, permaneces en la misma rama y nunca rompes el clon de nadie más. Este es el método correcto para deshacer commits que ya han sido enviados o compartidos públicamente.
Con git reset (reescribir el historial local)
git reset mueve el puntero de la rama actual a un commit elegido. Ejecutar git reset --hard b235bf4 rebobina la rama a ese commit y descarta todo lo que hay después:
git reset --hard b235bf4
git log --oneline
b235bf4 Make some changes to solver.php
256a81c Create solver.php
3243e12 Initial changesEl commit 863fa8e ha desaparecido del historial de esta rama. Esto es limpio y directo, pero como reescribe el historial, debes hacerlo únicamente en commits que no hayas enviado. git reset acepta un indicador de modo que controla hasta dónde llega la reversión:
--soft— mueve solo el puntero de la rama; mantiene los cambios preparados.--mixed(predeterminado) — mueve el puntero y retira los cambios del área de preparación, pero los conserva en el directorio de trabajo.--hard— mueve el puntero y descarta los cambios tanto del área de preparación como del directorio de trabajo.
git reset --hard descarta permanentemente el trabajo no confirmado del directorio de trabajo. No hay ningún paso de preparación desde el que recuperarlo. Usa --soft o --mixed cuando solo quieras rehacer el commit pero conservar las ediciones.
Deshacer el último commit
A veces no quieres eliminar el commit más reciente — simplemente confirmaste demasiado pronto o escribiste un mensaje poco claro. Prepara los cambios adicionales con git add y luego modifica el commit:
git add forgotten-file.txt
git commit --amendGit abre el editor configurado para que puedas editar el mensaje del último commit, y los cambios recién preparados se integran en ese mismo commit. Para cambiar solo el mensaje en una línea:
git commit --amend -m "A clearer message"Modificar el commit reemplaza el commit anterior por uno nuevo (con un nuevo hash), así que trátalo como reset: solo modifica commits que no hayas enviado.
Deshacer cambios no confirmados
Antes de que un cambio sea confirmado, vive en el directorio de trabajo y en el índice de preparación, por lo que puedes deshacerlo desde cualquiera de esas áreas sin tocar el historial. El comando moderno es git restore:
# Discard edits to a tracked file (working directory)
git restore <file>
# Unstage a file but keep its edits
git restore --staged <file>Los equivalentes más antiguos siguen funcionando y aparecen en mucha documentación:
# Discard changes in the working directory
git checkout -- <file>
# Unstage a file
git reset HEAD <file>Eliminar archivos sin rastrear
git restore y reset solo afectan a los archivos que Git ya conoce. Para eliminar archivos nuevos sin rastrear, usa git clean. Siempre previsualiza primero con -n (ejecución en seco):
git clean -n # list what would be removed
git clean -f # actually remove untracked filesCómo se relacionan las tres áreas
Vale la pena tener claras las tres áreas, porque cada comando de reversión apunta a una específica:
- Directorio de trabajo — los archivos en disco que modifica tu editor.
git restore <file>ygit cleanactúan aquí. - Índice de preparación — la instantánea que estás construyendo para el próximo commit.
git addcoloca los cambios aquí;git restore --staged(un reset--mixed) los devuelve al directorio de trabajo. - Historial de commits — instantáneas registradas.
git resetlo reescribe;git revertle añade.
Recuperarse de una reversión errónea
Un reset o una rama eliminada pueden parecer aterradores, pero Git raramente pierde nada de inmediato. El git reflog registra dónde ha apuntado HEAD, por lo que puedes encontrar el hash de un commit "perdido" y hacer reset hasta él:
git reflog
1a2b3c4 HEAD@{0}: reset: moving to b235bf4
863fa8e HEAD@{1}: commit: Making some improvementsRecupéralo con git reset --hard 863fa8e (o crea una rama a partir de él). Si solo quieres apartar trabajo temporalmente en lugar de deshacerlo, considera usar git stash en su lugar.
Deshacer cambios públicos
Una vez enviado un commit, otras personas pueden tenerlo. Usa git revert para los cambios públicos, nunca git reset. Reset elimina commits del historial, por lo que reescribir una rama compartida obliga a todos los demás a reparar sus clones. Revert deja el commit original en su lugar y registra un nuevo commit que lo revierte — seguro para todos los que ya han descargado los cambios.