El comando git reset es el comando git que nos permite deshacer cambios que hemos introducido por error o antes de tiempo.
Hay varias opciones de uso para este comando, pero una de ellas sirve para devolver el repositorio git a un estado concreto del histórico de git, deshaciendo los cambios posteriores. El comando es
git reset <mode> <commit>
mode indica a qué partes del repositorio queremos afectar. Hay tres posibles
- Histórico de commit: Tu repositorio local con sus cambios.
- Área de Staging: El índice de tu git local, donde git guarda qué archivos tienen que añadirse en el próximo commit. Es decir, ficheros de los que has hecho git add.
- Directorio de trabajo: Tu copia local de los ficheros, donde editas y ves tu código y que tiene los cambios que todavía no están en el respositorio.
Para que el comando afecte a cada una de las áreas, mode tiene tres posibles valores:
- –soft : Con este flag, sólo se afecta al histórico de commit, sin tocar tu directorio de trabajo ni el área de staging.
- –mixed: Es la opción por defecto, afecta al histórico de commit y al área de staging. No toca tu directorio de trabajo, es decir, mantiene los cambios que hayas hecho localmente.
- –hard: Esta opción toca los tres niveles, por lo que es peligrosa. Puedes perder tus cambios, ya que desaparecen tanto de git como de tu copia local.
Imagina que hemos modificado un fichero (modificado.txt) y creado un nuevo (nuevo.txt) al que hemos hecho el git add. Si ejecutamos el comando git status, tendremos esto.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: nuevo.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: modificado.txt
Veamos como afectan cada una de las tres opciones
git reset –soft
La opción –soft sólo afecta al repositorio. Así que ese comando sin más git reset –soft no hace nada. El motivo es que por defecto resetea a HEAD, que es el úlitmo commit en el repositorio y en el que habitualmente estamos. Otra cosa es que deshagamos el último commit con el comando git reset –soft HEAD~. Esto borra el último commit del repositorio, pero no toca el área de staging. Seguiremos teniendo el fichero añadido pendiente de commit y el fichero modificado pendiente de commit, además de pendientes los cambios que hicieramos en el commit anterior que se han borrado
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: nuevo.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: modificado.txt
modified: modificado-commit-anterior.txt
git reset –mixed
La opción –mixed, que es la de defecto, nos limpia el staging área. Así, el comando git reset, que por defecto es equivalente a git reset –mixed HEAD, símplemente límpia los ficheros marcados con git add.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: modificado.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
nuevo.txt
El fichero pendiente de commit sigue pendiente de commit, pero el fichero nuevo dice que no está trackeado, que le hagamos un add si queremos incluirlo.
git reset –hard
Finalmente, la opción más heavy es –hard. Deshace todos nuestros cambios locales. Deshará nuestros cambios locales en el fichero modificado y borrará de nuestro disco el fichero recién creado.
nothing to commit, working tree clean