Saltar al contenido principal
InicioTutorialesGit

Tutorial de Git Revert y Git Reset para principiantes

Una guía tutorial para principiantes que muestra cómo utilizar los comandos Git Revert y Reset.
Actualizado feb 2024  · 10 min leer

Imagen del Tutorial de Git Revert y Git Reset

Motivación

En el pasado se consideraba que Git era una herramienta hecha a medida de los desarrolladores de software por su capacidad para permitir el control de versiones de los códigos fuente. 

Esta realidad está cambiando porque la mayoría de los científicos de datos e ingenieros de machine learning también están adoptando estas buenas prácticas. 

En este tutorial, te proporcionaremos una comprensión clara de Git. A continuación, realizaremos un tutorial práctico de Git Revert vs Reset, desde la inicialización de un proyecto hasta el seguimiento de los cambios.

¿Qué es Git?

Git es una herramienta de control de versiones de código abierto creada en 2005 por Linus Torvalds. Se utiliza principalmente para realizar un seguimiento eficaz de los cambios en los archivos del proyecto, de modo que los miembros del proyecto puedan tener un registro de todos los cambios y fusionarlos sin perder información valiosa. Nuestro curso de introducción a Git te dará más información sobre cómo y por qué utilizar Git, al tiempo que cubre los pasos más comunes del flujo de trabajo de Git.

Además, el curso Conceptos de Github te proporcionará las claves para utilizar las distintas funciones de Github, navegar por la interfaz y realizar con éxito las tareas colaborativas cotidianas. 

Git Revert vs. Reset 

Estos dos comandos se utilizan en Git para deshacer cambios en el código y el historial de un proyecto, pero de formas distintas. En esta sección, tendremos una visión general de cómo utilizarlos. Antes de sumergirnos en el proceso, empecemos por crear un proyecto Git.

Crear un proyecto Git

A continuación encontrarás las instrucciones para crear un proyecto git e inicializarlo con algunos archivos:

mkdir git_revert_reset
cd git_revert_reset
git init .
  • mkdir git_revert_reset crea una carpeta llamada git_revert_reset
  • cd git_revert_reset se desplaza a la carpeta. 
  • git init . inicializa la carpeta como repositorio git.

Considerando esto como un proyecto de Ciencia de datos, podemos crear los siguientes archivos para la adquisición de datos, el preprocesamiento de datos y el entrenamiento del modelo utilizando este comando touch:

touch data_acquisition.py data_preprocessing.py model_training.py

Este es el contenido final de la carpeta del proyecto.

git_revert_reset
      |---------- data_acquisition.py
      |---------- data_preprocessing.py
      |---------- model_training.py

Git Reset 

Diagrama de antes y después de Git Reset

Diagrama de Git Reset(Fuente)

El comando git reset se utiliza para deshacer los cambios en tu directorio de trabajo y volver a un commit concreto, descartando todos los commits realizados después de ese. 

Por ejemplo, imagina que has hecho diez commits. Usar git reset en el primer commit eliminará los nueve commits, devolviéndote al momento del primer commit.

Antes de utilizar git reset, es importante tener en cuenta el tipo de cambios que piensas hacer; de lo contrario, crearás más caos que mejoras. 

Puedes utilizar múltiples opciones junto con git reset, pero éstas son las principales. Cada uno se utiliza en función de una situación concreta: git reset --soft, git reset --mixed, y git reset --hard

git reset --soft

El --soft pretende cambiar la referencia HEAD (donde está el último commit en tu máquina local) a un commit concreto. Por ejemplo, si nos damos cuenta de que hemos olvidado añadir un archivo al commit, podemos retroceder utilizando la opción --soft con respecto al formato siguiente:

  • git reset --soft HEAD~n para volver al commit con una referencia específica (n). git reset --soft HEAD~1 vuelve al último commit.
  • git reset --soft vuelve a la cabeza con el

Veamos algunos ejemplos.

git add data_acquisition.py data_preprocessing.py

git add data

git commit -m "added data acquisition and preprocessing scripts"

Este es el resultado del comando anterior. 

[master (root-commit) faf864e] added python scripts and data folder
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 data_acquisition.py
create mode 100644 data_preprocessing.py

Podemos comprobar el estado del commit del siguiente modo:

git status

On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
model_training.py

nothing added to commit but untracked files present (use "git add" to track)

Pero, nos olvideamos de añadir el script model_training.py al commit.

Como el último commit se encuentra en el HEAD, podemos solucionar este problema ejecutando las tres sentencias siguientes. 

  • Vuelve a la fase de precommit usando git reset --soft HEAD permitiendo el archivo git reset.
  • Añade el archivo olvidado con git add 
  • Realiza los cambios con un commit final git commit.
git reset --soft HEAD

git add model_training.py

git commit -m "added all the python scripts"

El siguiente resultado hizo que git se restableciera a master después de todos los pasos anteriores: 

[master (root-commit) faf864e] added all the python scripts
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 data_acquisition.py
create mode 100644 data_preprocessing.py
create mode 100644 model_training.py

git reset --mixed

Este es el argumento por defecto de git reset. Ejecutar este comando tiene dos efectos: (1) uncommit de todos los cambios y (2) deshacerlos. 

Imagina que hemos añadido accidentalmente el archivo model_training.py, y queremos eliminarlo porque el entrenamiento del modelo aún no ha terminado. 

He aquí cómo proceder: 

  • Quita los archivos que estaban en el commit con git reset HEAD
  • Añade sólo los archivos que necesitamos para el commit
git reset HEAD

git status

On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
model_training.py
data_acquisition.py
data_preprocessing.py

nothing added to commit but untracked files present (use "git add" to track)

Ahora podemos añadir sólo los dos últimos archivos a confirmar y hacer commit.

git add data_acquisition.py data_preprocessing.py

git commit -m "Removed the model_training.py from the commit"

git reset --hard

Esta opción puede ser peligrosa. Por tanto, ¡ten cuidado al utilizarla! 

Básicamente, al utilizar el hard reset en un commit concreto, fuerza al HEAD a volver a ese commit y borra todo lo demás después de él.

Antes de ejecutar el hard reset, echemos un vistazo al contenido de la carpeta.

ls
data_acquisition.py data_preprocessing.py model_training.py

git reset --hard
HEAD is now at 97159bc added data acquisition and preprocessing scripts

Ahora vamos a comprobar el contenido de la carpeta:

ls
data_acquisition.py data_preprocessing.py

Observamos que se elimina el archivo no rastreado model_training.py. De nuevo, asegúrate de entender lo que estás haciendo con la sentencia reset, ¡porque puede conllevar graves consecuencias!

Git Revert

Diagrama de reversión - Antes y después

Antes y después de la reversión(Fuente)

Git revert es similar a git reset, pero el enfoque es ligeramente diferente. En lugar de eliminar todos los commit a su paso, la reversión SÓLO deshace un único commit, devolviéndote a los archivos organizados antes del commit.

Así, en lugar de eliminar un commit, git revert invierte los cambios introducidos por el commit original creando un nuevo commit con el contenido inverso subyacente. Esta es una forma segura de revocar un commit porque evita que pierdas tu historial. 

Es importante saber que la reversión no tendrá efecto a menos que se especifique el hash o la referencia del commit. 

Exploremos algunas opciones comunes de git revert.

git revert --no-edit <commit ID>

La opción --no-edit permite al usuario no cambiar el mensaje utilizado para el commit que desea revertir, y esto hará que git revierta el archivo a la rama maestra.

Para ilustrar este escenario, vamos a crear dos nuevos archivos para añadir. 

touch model_monitoring.py data_monitoring.py

Después de crear esos archivos, tenemos que añadirlos al área de preparación de la versión modificada.

git add model_monitoring.py

Antes de continuar, echemos un vistazo al estado ejecutando el siguiente comando.

git status
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file:   data_monitoring.py
new file:   model_monitoring.py


Podemos observar que se han añadido los dos archivos, ahora, podemos confirmar los cambios.

git commit -m "Added the monitoring script files"
[master (root-commit) eae84e7] Added the monitoring script files
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 data_monitoring.py
create mode 100644 model_monitoring.py


Entonces se puede generar el hash de commit mediante el siguiente comando. Esto es beneficioso cuando se intenta realizar una acción a este commit específico. 

git reflog
eae84e7 (HEAD -> master) HEAD@{0}: commit (initial): Added the monitoring script files

Ahora imaginemos que el commit anterior no fue intencionado y queremos deshacernos de él.

git revert --no-edit eae84e7

[master c61ef6b] Revert "Added the monitoring script files"
Date: Sat Nov 12 20:14:17 2022 -0600
2 files changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 data_monitoring.py
delete mode 100644 model_monitoring.py

Echemos un vistazo al registro de los commits:

git log

commit c61ef6b4e86f41f47c8c77de3b5fca3945a7c075 (HEAD -> master)
Author: Zoumana Keita <keitnekozou@gmail.com>
Date:   Sat Nov 12 20:14:17 2022 -0600

  Revert "Added the monitoring script files"
 
  This reverts commit eae84e7669af733ee6c1b854f2fcd9acfea9d4a3.

commit eae84e7669af733ee6c1b854f2fcd9acfea9d4a3
Author: Zoumana Keita <keitnekozou@gmail.com>
Date:   Sat Nov 12 20:05:57 2022 -0600

  Added the monitoring script files

En el registro podemos observar que se ha creado un nuevo commit con el ID c61ef6b4e86f41f47c8c77de3b5fca3945a7c075 para anular el commit original con el ID eae84e7669af733ee6c1b854f2fcd9acfea9d4a3

En este ejemplo, como tenemos un único commit, podríamos utilizar simplemente git revert HEAD,, que tendría el mismo efecto al revertir el último commit.

git revert <commit hash>

Esto sólo eliminará los cambios asociados a este hash de commit y no afectará a ningún otro commit.

¿Qué git revert crees que tendrá efecto, teniendo en cuenta el ID generado previamente? 

Si tu respuesta ha sido c61ef6b4e86f41f47c8c77de3b5fca3945a7c075, entonces tienes razón. Considerar eae84e7669af733ee6c1b854f2fcd9acfea9d4a3 no tendrá ningún efecto, ya que se sustituye por uno nuevo. 

Veamos qué ocurrirá entonces al intentar realizar la reversión.

git revert c61ef6b4e86f41f47c8c77de3b5fca3945a7c075

[master aaead40] Revert "Revert "Added the monitoring script files""

 2 files changed, 0 insertions(+), 0 deletions(-)

 create mode 100644 data_monitoring.py

 create mode 100644 model_monitoring.py

Como puedes ver, ¡se han recuperado los dos archivos creados y confirmados inicialmente!

git revert --no-commit <commit ID>

El propósito de usar las opciones --no-commit o -n es evitar que git haga automáticamente el commit de revert. Esto puede ser beneficioso si quieres revisar los cambios realizados por la sentencia revertir antes de confirmarlos.

Consideremos el siguiente ejemplo: 

git revert --no-commit c61ef6b4e86f41f47c8c77de3b5fca3945a7c075

Esto revertirá los cambios realizados por el commit con el ID c61ef6b4e86f41f47c8c77de3b5fca3945a7c075, pero no creará automáticamente un nuevo commit para registrar la reversión. En su lugar, dejará los cambios sin procesar para que puedas revisarlos y decidir si quieres confirmar la reversión manualmente.

Cuándo usar Git Revert vs. Reset

Git Revert 

  • Usando git revert, tienes la posibilidad de volver a estados anteriores mientras creas un nuevo commit.
  • Opta por esta opción si quieres deshacer cambios en una rama pública, por seguridad.

Git Reset

  • Con git reset, puedes volver a los commits anteriores, pero no puedes crear un nuevo commit. 
  • Esta opción es mejor cuando se deshacen cambios en una rama privada.

Conclusión

En este tutorial, hemos visto cómo realizar un git reset y revertir los cambios en tu repositorio git. Recuerda que un reinicio completo puede ser muy peligroso, porque hará que pierdas tus archivos no rastreados en el proyecto. 

Entonces, ¿qué es lo siguiente? 

Múltiples tutoriales, como Tutorial sobre cómo resolver conflictos de fusión en Git, GitHub y Tutorial de Git para principiantes, podrían ser un buen paso para mejorar tus habilidades con Git.

Preguntas frecuentes sobre Git Reset y Revert

¿Cuál es la diferencia entre git reset y git revert?

git reset se utiliza para deshacer confirmaciones en el repositorio local moviendo el puntero de la rama a un commit anterior, descartando de hecho cualquier commit que se haya hecho después de ese punto.

git revert, por otro lado, se utiliza para deshacer los cambios que se han confirmado en el repositorio, creando un nuevo commit que deshace los cambios realizados por el commit específica.

¿Debes usar git reset hard?

Ten cuidado al utilizar git reset hard porque puede destruir completamente cualquier cambio y eliminarlo del directorio local. Antes de utilizarlo, asegúrate al 100 % de lo que estás haciendo.

¿Cuándo debo utilizar git reset?

git reset es útil cuando quieres deshacer confirmaciones que no se han enviado a un repositorio remoto. Puede utilizarse para eliminar confirmaciones que contengan errores o que ya no sean necesarias.

Es importante tener en cuenta que git reset es una operación local y no afecta al repositorio remoto. Si ya has enviado los commits que quieres deshacer, debes utilizar git revert en su lugar.

¿Cuándo debo utilizar git revert?

git revert es útil cuando quieres deshacer confirmaciones que ya se han enviado a un repositorio remoto. Es una opción segura porque no destruye ningún commit y deja un registro claro de los cambios realizados en el repositorio.

Es importante tener en cuenta que git revert sólo puede deshacer confirmaciones que no se hayan fusionado en otras ramas. Si quieres deshacer confirmaciones que forman parte de una rama fusionada, debes utilizar git reset u otro método para eliminar las confirmaciones.

Temas