Cómo Deshacer Cambios en Git: reset, revert y restore
Domina las técnicas de rectificación en Git: `git restore`, `git reset --soft/mixed/hard`, y por qué `git revert` es la única opción segura para ramas públicas colaborativas.
Git provee tres herramientas fundamentales para deshacer modificaciones según la fase en que se encuentre el error: `git restore` (para descartar cambios locales o sacar archivos de Staging), `git revert` (para crear un nuevo commit que anule un commit previo de forma segura en ramas compartidas) y `git reset` (para retroceder punteros y reescribir el historial local).
Equivocarse es inevitable al programar; dominar la diferencia crítica entre deshacer de forma segura (sin reescribir historia pública) y deshacer destructivamente evita pérdidas irreversibles de código y frustraciones de equipo.
Imagina escribir una carta oficial: 1. Si estás escribiendo con lápiz en el borrador y te equivocas, usas la goma de borrar (`git restore`). 2. Si ya enviaste la carta sellada a la junta directiva y debes anularla, emites una nueva carta formal que dice 'Esta carta deja sin efecto legal la decisión comunicada ayer' (`git revert`). 3. Si tienes una máquina del tiempo y decides viajar al pasado borrando la existencia de la carta como si nunca hubiera ocurrido, usas (`git reset`).
Explicación Paso a Paso del Tema
Deshacer cambios locales con git restore
Usa `git restore` para limpiar archivos antes de que lleguen a un commit.
Si modificaste código y decidiste que la idea no sirve, ejecuta `git restore <archivo>` para devolverlo a como estaba. Si ya habías hecho `git add` y el archivo está en Staging pero quieres sacarlo sin perder tus cambios, ejecuta `git restore --staged <archivo>`.
git restore --staged index.html && git restore index.html
| Parámetro / Flag | Tipo / Rol | Significado y Uso |
|---|---|---|
| --staged | Bandera de desacople | Saca el archivo del área de preparación devolviéndolo a estado simplemente modificado |
| git restore | Comando moderno | Sobrescribe el archivo de trabajo con el contenido registrado en HEAD |
Si tienes dudas de si vas a necesitar lo que estás por descartar con restore, haz un `git stash` preventivo antes.
Ejecutar `git restore .` sin haber guardado ideas útiles; destruirá todos los cambios no guardados en commit de todos los archivos sin confirmación previa.
Comprender los 3 niveles de git reset
Aprende a retroceder commits locales eligiendo qué pasa con tu código.
Al ejecutar `git reset HEAD~1` (retroceder un commit): 1. `--soft`: Deshace el commit pero deja todos tus archivos tal como estaban dentro de Staging (listos para volver a commitear). 2. `--mixed` (modo por defecto): Deshace el commit y saca los archivos de Staging, pero conserva tu código modificado en el disco. 3. `--hard`: Destruye el commit, vacía Staging y borra los cambios del disco.
git reset --soft HEAD~1
| Parámetro / Flag | Tipo / Rol | Significado y Uso |
|---|---|---|
| --soft | Modo seguro | Mueve el puntero de la rama al commit anterior conservando los cambios en Staging |
| HEAD~1 | Notación de puntero | Representa el commit inmediatamente anterior al actual |
Regla de oro: usa `git reset` únicamente para reorganizar tu historial personal local antes de hacer `git push`.
Usar `git reset --hard` en una rama compartida pública que ya tiene commits subidos a GitHub; causará un desastre de sincronización para todo tu equipo.
Deshacer commits públicos de forma segura con git revert
Aplica siempre `git revert` para corregir errores que ya fueron publicados.
`git revert <hash>` no reescribe la historia ni borra ningún commit del pasado. En su lugar, calcula exactamente lo opuesto de lo que hizo ese commit (si sumaste 10 líneas, las borra; si borraste una, la agrega) y crea una nueva confirmación limpia en la punta de la rama. Es la única forma segura y respetuosa de corregir código en producción.
git revert 8a1f2bc --no-edit && git push origin main
| Parámetro / Flag | Tipo / Rol | Significado y Uso |
|---|---|---|
| git revert | Comando de inversión | Genera una nueva confirmación que neutraliza matemáticamente los cambios de un commit previo |
| --no-edit | Flag de mensaje | Acepta el mensaje estándar generado por Git (ej. 'Revert "feat: ..."') de forma directa |
Si un día pierdes un commit accidentalmente por un reset extremo, usa el comando mágico `git reflog`: registra cada movimiento de la aguja HEAD y te permite recuperar cualquier commit huérfano de los últimos 30 días.
Intentar forzar un reset en una rama compartida usando `git push --force`. Esto sobrescribe el trabajo de tus compañeros y puede costar horas de recuperación.
Casos Prácticos Reales en Producción
Situaciones de ingeniería reales sin mención de presupuestos ficticios.
1Caso de Producción: Reversión Inmediata de un Despliegue Fallido en Viernes
Un cambio recién desplegado en la rama principal provocó que los usuarios no pudieran cerrar sesión en una plataforma de banca en línea. El commit causante ya estaba en GitHub y en el servidor.
El ingeniero de guardia no reescribió el historial con reset forzado; ejecutó `git revert HEAD --no-edit` y disparó un `git push origin main`. En menos de 90 segundos, la pipeline de despliegue continuo detectó el nuevo commit de reversión y restauró el código estable anterior.
Fichas Nemotécnicas de Conceptos Clave
Glosario rápido para recordar los términos fundamentales de la lección.
Descarta todas las modificaciones locales no preparadas de un archivo, devolviéndolo al estado del último commit.
Crea una nueva confirmación que aplica los cambios exactamente inversos a un commit anterior sin reescribir el historial.
Operación destructiva que borra el último commit, limpia Staging y destruye los cambios físicos en el disco duro.
Cómo Deshacer Cambios en Git: reset, revert y restore
Selecciona una opción para autoevaluarte al instante. La respuesta se califica de inmediato.
¿Cuál es el comando adecuado y seguro para deshacer un commit que ya fue empujado a un repositorio público compartido?
¿Qué efecto produce ejecutar 'git reset --soft HEAD~1'?
¿Qué comando permite sacar un archivo del Staging Area sin perder las modificaciones realizadas?
Preguntas Frecuentes (FAQ)
¿Cuál es la diferencia fundamental entre reset y revert?
`git reset` viaja al pasado y reescribe la historia (peligroso en ramas compartidas). `git revert` va hacia el futuro creando un nuevo commit que neutraliza los efectos del anterior (100% seguro para código compartido).
¿Qué es el comando 'git reflog'?
Es la red de seguridad definitiva de Git. Guarda un registro cronológico local de todos los cambios de puntero de HEAD, permitiéndote encontrar y resucitar commits que fueron borrados con `git reset --hard`.
¿Cómo puedo deshacer el último commit pero conservar todo el código que escribí?
Ejecutando `git reset --soft HEAD~1`. El commit desaparecerá del historial pero todo tu código modificado quedará intacto y listo en el área de preparación.