Deshacer commits en git

Cómo borrar los últimos cambios


Resulta que realizamos unos cambios y nos damos cuenta que hay un error o que no queríamos realizar esas modificaciones y buscamos dar marcha atrás. Lo que parece una inocente acción, se puede complicar o hacer de una forma diferente dependiendo de nuestras necesidades en ese momento.

Formas de deshacer un commit

En este artículo vamos a analizar las diferentes formas de deshacer un commit. En realidad hay más formas, pero las restantes las veremos más adelante, vamos a centrarnos en las que necesitaremos en este momento.

Esta sería una tabla donde podemos ver las principales formas (más abajo las explicamos en detalle):

Comando Descripción
git commit --amend Elimina el último commit y añade uno nuevo con lo del anterior más lo nuevo.
Útil para hacer ligeras modificaciones que olvidaste añadir.
git reset --soft Deshace los cambios y mantiene los cambios en staging.
Útil para mantener cambios y hacer ligeras modificaciones.
git reset --mixed Deshace los cambios y mantiene los cambios en la carpeta pero no en staging.
Útil para mantener cambios y rehacer commit.
git reset --hard Deshace los cambios y se pierden los cambios.
Útil para descartar todo lo posterior al punto de control.
git revert Añade un nuevo commit que deshace los cambios.
Útil cuando ya se han hecho cambios.

En nuestro ejemplo, vamos a añadir un nuevo archivo robots.txt vacío y vamos a añadirlo con un commit nuevo (concretamente, el commit 6586b43):

$ touch robots.txt
$ git add robots.txt
$ git commit -m "Commit que queremos deshacer"
$ git log --online
6586b43 Commit que queremos deshacer
5d1c91b Añadimos cambios en la estructura, funcionalidad JS y el README
3178f03 Añadimos la estructura y el estilo de la web.

Ahora imaginemos que nos damos cuenta que ese fichero no debía «commitearse» estando vacío, sino con información en su interior. ¿Cómo deshacemos el último commit? Hay varias formas.

El comando git commit --amend

Este comando es útil si olvidaste alguna cosa en el último commit. Con este comando lo que estás haciendo es:

  • 1️⃣ Añadir los cambios que olvidaste
  • 2️⃣ Se borra el último commit
  • 3️⃣ Se hace un nuevo commit donde tenemos los cambios del commit borrado, más los que añadiste
$ vim robots.txt
$ git add robots.txt
$ git commit --amend --no-edit
$ git log --online
ed3c8fd Commit que queremos deshacer
5d1c91b Añadimos cambios en la estructura, funcionalidad JS y el README
3178f03 Añadimos la estructura y el estilo de la web.

Observa que el hash del último commit ha cambiado. Eso es así porque se ha borrado el original, y se ha vuelto a crear uno con los cambios del anterior y los del nuevo.

El comando git reset --soft

Este comando es útil si queremos deshacer el commit y modificarlo ligeramente. Con este comando lo que estás haciendo es:

  • 1️⃣ Elimina el último commit
  • 2️⃣ Los cambios de ese commit pasan al area de staging (están añadidos)

Ahora puedes hacer los cambios sobre tus archivos y volver a hacer el commit cuando hayas terminado:

$ git reset --soft HEAD~1

Igual que tenemos el --soft, tenemos el --mixed. La diferencia es que con --mixed los cambios no se quedan en staging, sino en la estructura de carpetas, pendientes a que nosotros decidamos que hacer con ellos.

Recuerda que HEAD es un acceso directo al último commit, HEAD~1 al penúltimo, y así. También podemos utilizar el hash del commit para identificarlo.

El comando git reset --hard

Este comando es útil si queremos deshacer el commit y descartar sus cambios para continuar haciendo algo diferente. Hay que tener mucho cuidado con este comando, ya que los cambios se pierden.

$ git reset --hard HEAD~1

Utilizalo cuando quieras abandonar una aproximación en la que estabas trabajando pero ya no es válida y quieres descartarla.

El comando git revert

Este comando es útil si quieres deshacer un commit, pero mantenerlo el historial. Con este comando lo que estás haciendo es:

  • 1️⃣ No se elimina el último commit
  • 2️⃣ Se hace un nuevo commit pero negando los cambios introducidos, es decir, volviendo a la situación anterior al último commit.

De esta forma, el commit se mantiene en el historial de commits, algo que puede ser interesante en algunos casos:

$ git log --oneline
d126697 Commit que queremos deshacer
5d1c91b Añadimos cambios en la estructura, funcionalidad JS y el README
3178f03 Añadimos la estructura y el estilo de la web.

$ git revert d126697
$ git log --oneline
cf13543 Revert "Commit que queremos deshacer"
d126697 Commit que queremos deshacer
5d1c91b Añadimos cambios en la estructura, funcionalidad JS y el README
3178f03 Añadimos la estructura y el estilo de la web.

Observa que el commit indicado a deshacer, con hash d126697 no se ha eliminado del historial, lo que se ha hecho es un nuevo commit donde se deshacen los cambios de d126697 y se crea un commit nuevo, en cf13543, que sería prácticamente igual al commit 5d1c91b.

Más adelante veremos algunos otros casos que tendrán más que ver con el repositorio remoto.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev