Deshaciendo Cambios en Git: Reset, Restore, Revert Explicados
Comprende git restore, reset y revert para poder deshacer archivos, descartar ediciones locales, deshacer commits y evitar reescribir el historial compartido.
Deshaciendo Cambios en Git: Reset, Restore, Revert Explicados
Deshacer cambios en Git es seguro cuando sabes qué capa estás cambiando: el árbol de trabajo, el área de preparación o el historial de commits. Los comandos comunes son git restore, git reset y git revert, y resuelven diferentes problemas.
La regla principal es simple: usa restore para archivos, reset para cambios en el historial local y revert para deshacer commits que otras personas ya puedan tener.
Comprendiendo los Conceptos Clave
Mantén claras estas áreas:
- Árbol de trabajo: los archivos que editas.
- Área de preparación, también llamada índice: los cambios seleccionados para el próximo commit.
- Historial de commits: los commits ya registrados.
HEAD: el commit actual al que apunta tu rama.
Ejecuta git status antes de deshacer cualquier cosa. Te indica si los cambios están sin preparar, preparados o ya confirmados.
git restore: Para Descartar Cambios en el Directorio de Trabajo y el Área de Preparación
Usa git restore cuando quieras cambiar archivos en el árbol de trabajo o el área de preparación sin mover el historial de la rama.
Deshaciendo Archivos del Área de Preparación
Si preparaste un archivo por error, deshazlo con --staged:
git restore --staged <archivo>
Para deshacer todo:
git restore --staged .
Tus ediciones en el archivo permanecen en el árbol de trabajo. Simplemente se eliminan del próximo commit.
Descartando Cambios en el Directorio de Trabajo
Para descartar ediciones sin preparar en un archivo:
git restore <archivo>
Esto hace que la copia del árbol de trabajo coincida con el índice. Si el archivo no está preparado, generalmente significa que vuelve a HEAD. Revisa git diff primero porque esto descarta ediciones locales.
Para descartar cambios tanto preparados como sin preparar para un archivo y restaurarlo desde HEAD:
git restore --source=HEAD --staged --worktree <archivo>
Restaurando un Archivo desde un Commit Específico
También puedes recuperar un archivo de un commit anterior:
git restore --source=<commit> -- ruta/al/archivo
Esto cambia el archivo en tu árbol de trabajo. Haz commit si la versión anterior es lo que quieres a futuro.
git reset: Reescribiendo el Historial
Usa git reset cuando quieras mover el puntero de la rama actual. También puede cambiar el área de preparación y el árbol de trabajo dependiendo del modo.
Comprendiendo los Modos (--soft, --mixed, --hard)
Los tres modos comunes son:
git reset --soft HEAD^
Mueve HEAD un commit atrás y mantiene los cambios del commit deshecho preparados.
git reset --mixed HEAD^
Mueve HEAD un commit atrás y mantiene los cambios del commit deshecho sin preparar. --mixed es el predeterminado, así que git reset HEAD^ hace lo mismo.
git reset --hard HEAD^
Mueve HEAD un commit atrás y descarta los cambios correspondientes del área de preparación y el árbol de trabajo. Esto es destructivo. No lo ejecutes a la ligera.
Patrones útiles de reset:
git reset --soft HEAD^ # rehacer el último commit local, mantener cambios preparados
git reset HEAD^ # deshacer el último commit local, mantener cambios sin preparar
git reset # deshacer todos los cambios preparados
git reset --hard origin/main # descartar cambios locales y coincidir con origin/main
Restableciendo un Commit Antiguo
Para mover tu rama dos commits atrás mientras mantienes los cambios en tu árbol de trabajo:
git reset --mixed HEAD~2
Solo restablece commits que sean locales o que tu equipo haya acordado reescribir. Si los commits ya están en una rama compartida, prefiere git revert.
git revert: Creando un Nuevo Commit para Deshacer Cambios
git revert crea un nuevo commit que aplica la inversa de un commit anterior. No elimina ni mueve el commit original, por lo que es seguro para ramas compartidas.
Revertir un commit:
git revert <hash-del-commit>
Revertir un rango:
git revert HEAD~3..HEAD
Si aparecen conflictos, resuélvelos, prepara los archivos y continúa:
git add <archivos-arreglados>
git revert --continue
Revertir un commit de fusión requiere cuidado adicional porque Git debe saber qué padre debe tratarse como la línea principal:
git revert -m 1 <commit-de-fusión>
Haz esto solo cuando entiendas lo que introdujo la fusión. Para ramas de producción, solicita una revisión antes de revertir fusiones.
Eligiendo el Comando Correcto
Usa esta guía rápida:
- Deshacer un archivo del área de preparación:
git restore --staged <archivo>. - Descartar ediciones sin preparar en un archivo:
git restore <archivo>. - Deshacer el último commit local y mantener cambios preparados:
git reset --soft HEAD^. - Deshacer el último commit local y mantener cambios sin preparar:
git reset HEAD^. - Descartar cambios locales y commits destructivamente:
git reset --hard <commit>. - Deshacer un commit enviado de forma segura:
git revert <hash-del-commit>.
Conclusión Práctica
Antes de deshacer cualquier cosa, ejecuta git status y decide qué estás cambiando. Usa restore para limpieza a nivel de archivos, reset para cambios locales no enviados y revert para historial compartido. Cuando un comando incluya --hard, pausa y revisa git diff primero.