Introducción
Git proporciona varias formas de deshacer, dependiendo de si el cambio está en tu árbol de trabajo, en el index, en tu último commit o ya pusheado. Elegir la herramienta correcta previene accidentes.
Descartando ediciones del árbol de trabajo
Editaste un archivo pero quieres descartar los cambios:
git restore file.txt # moderno
git checkout -- file.txt # equivalente clásico
git restore sin --source usa el index, así que el archivo vuelve a su último estado de git add.
Quitando del staging
Ejecutaste git add pero quieres sacar un archivo del próximo commit (sin perder ediciones):
git restore --staged file.txt
git reset HEAD file.txt # sintaxis antigua
Enmendar el último commit
Hiciste commit pero quieres arreglar el mensaje o incluir otro archivo:
git commit --amend -m "Better message"
git add forgotten.txt
git commit --amend --no-edit
Solo enmienda commits que no has pusheado, o estate listo para hacer force-push.
Revirtiendo un commit público
Si un commit malo ya está pusheado, no reescribas el historial. Crea un nuevo commit que lo deshaga:
git revert <sha>
git push
git revert abre un editor con un mensaje generado; el resultado es un undo limpio que todos pueden hacer pull.
Reseteando
git reset mueve el puntero del branch actual. Tiene tres modos:
--soft: mover solo el branch; mantener index y árbol de trabajo.--mixed(predeterminado): mover branch y resetear index; mantener árbol de trabajo.--hard: mover branch, resetear index, resetear árbol de trabajo. Destructivo.
git reset --soft HEAD~1 # descommitear, mantener cambios staged
git reset HEAD~1 # descommitear, mantener cambios sin stagear
git reset --hard HEAD~1 # destruir el último commit y los cambios
Recuperando de --hard
git reflog
git reset --hard HEAD@{1}
El reflog recuerda cada movimiento de HEAD durante 90 días.
Eligiendo el undo correcto
Una matriz de decisión simple:
- Solo árbol de trabajo:
git restore <file> - Archivo staged:
git restore --staged <file> - Último commit no pusheado:
git commit --amendogit reset --soft HEAD~1 - Commit pusheado:
git revert <sha> - Punta del branch entera:
git reset --hard ORIG_HEAD(después de un merge/rebase malo)
git status
git diff
git log --oneline -5
Siempre ejecuta esos tres antes de cualquier undo destructivo. Muestran el árbol de trabajo, los cambios staged y el historial reciente; juntos te dicen qué undo es seguro.
Errores comunes
Confundir revert con reset. Revert añade; reset quita. Ejecutar git reset --hard con trabajo no commiteado, y luego darse cuenta de que lo necesitabas; busca el reflog inmediatamente, antes de que se ejecute la recolección de basura. Enmendar un commit pusheado y no coordinar el force-push con los compañeros. Usa git revert en historial compartido. Y finalmente, tratar git checkout file como seguro; en Git antiguo sobrescribe silenciosamente tus ediciones sin papelera de reciclaje. git restore moderno no es diferente; haz copia de seguridad si tienes dudas.