Joaquin Martinez

Depura tus errores y construye la mejor versión de ti, cada línea cuenta.

Viajes en el tiempo con git: Cómo usar git reset y git reflog

08-01-2025
Git y GitHub
Git
Cover Post

Viajes en el tiempo con Git: Controlando el historial de tu proyecto

Git es una herramienta fundamental en el desarrollo de software, ya que permite mantener un seguimiento detallado del ciclo de vida de un proyecto. Una de sus características más interesantes es la capacidad de hacer regresiones o “viajar en el tiempo” dentro de nuestro proyecto. Aunque trabajar con ramas es el método más común en equipos de desarrollo, entender cómo manipular el historial de commits es crucial para tener un control total. Este post se enfoca en esa funcionalidad, explorando los comandos git reset y git reflog.

Viajes en el tiempo con Git: comandos y uso

La regresión o el “viaje en el tiempo” en Git nos permite deshacer cambios y volver a un estado anterior de nuestro proyecto. Esto es útil para corregir errores, reestructurar el historial de commits o simplemente experimentar con cambios sin alterar la rama principal. A continuación, exploraremos las opciones del comando git reset para lograrlo.

git reset --soft

El comando git reset –soft es ideal para deshacer un commit manteniendo todos los cambios en el staging area listos para ser confirmados de nuevo. Es útil cuando te das cuenta de que un commit que acabas de hacer contiene un error y necesitas agregar más cambios antes de volver a confirmarlo.

Ejemplo práctico:
Supongamos que acabas de hacer un commit con un pequeño error en el archivo heroes.md. Queremos agregar una modificación a ese commit.

Primero, realizas un cambio en el fichero heroes.md y lo guardas. alt text

Luego, usamos el comando git reset –soft seguido del hash del commit al que queremos regresar.

git reset --soft [hash del commit al que queremos regresar]

En este caso, usaremos el hash 969bf35 para regresar al penúltimo commit.

git reset --soft 969bf35

alt text

Como se observa, el commit relacionado con “Linterna Verde” ha desaparecido del historial. Al mismo tiempo, si revisamos el estado del proyecto con git status, veremos que los cambios que acabamos de guardar en heroes.md siguen ahí, listos para ser añadidos al stage.

alt text

Con los cambios en su lugar, ahora podemos hacer un nuevo commit que englobe las modificaciones que se realizaron.

alt text

El historial ahora refleja los cambios combinados en un único y nuevo commit.

git reset --mixed
A diferencia de –soft, git reset –mixed no solo deshace el commit, sino que también mueve los archivos modificados del staging area al working directory. Los cambios se conservan, pero tendrás que volver a agregarlos con git add si quieres incluirlos en un nuevo commit. Este es el comportamiento por defecto de git reset.

Ejemplo práctico:
Supongamos que queremos regresar a un commit más antiguo, específicamente al commit donde agregamos el fichero ciudades.md.

git reset --mixed [hash del commit]

Usaremos el hash del commit de ciudades.md.

git reset --mixed 57ee539

alt text

Al ejecutar este comando, Git nos indica que el último commit ahora es el de ciudades.md. En nuestro editor de código, veremos que heroes.md y la carpeta historia ahora aparecen con estado modified y untracked respectivamente. Esto nos indica que los archivos están listos para ser agregados al stage y confirmados en un nuevo commit.

alt text

git reset --hard
El comando git reset –hard es el más radical de los tres. Elimina completamente los cambios del working directory y del staging area, restaurando el proyecto exactamente al estado del commit especificado. ¡Úsalo con extrema precaución, ya que perderás los cambios de forma permanente si no los tienes respaldados!

Ejemplo práctico:
Continuando con el ejemplo anterior, si en lugar de conservar los cambios, quisiéramos eliminarlos por completo y volver al estado exacto del commit de ciudades.md, usaríamos –hard.

git reset --hard 57ee539

alt text

Al ejecutar el comando, Git nos informa que la rama HEAD se ha movido al commit especificado. Si revisamos los archivos, veremos que heroes.md ya no tiene los cambios que habíamos agregado, y la carpeta historia ha desaparecido.

alt text

Lo mismo ocurre si regresamos a un commit aún más antiguo, como el de heroes.md.

git reset --hard 7f3c04f

alt text

alt text

El archivo ciudades.md se elimina, ya que en ese commit no existía. Esto demuestra cómo git reset –hard borra archivos que se crearon después del commit de destino.

alt text

Si ejecutamos git log, veremos que el historial también se ha “acortado”, mostrando solo los commits hasta el punto al que regresamos.

alt text

Por último, haremos otra regresión al commit de “misiones”.

git reset --hard 67b4163

alt text

Como podemos observar, en el momento en que nosotros hacemos una regresión, la rama HEAD se mueve respecto a la regresión.

Recuperando commits perdidos con git reflog

¿Qué pasa si te arrepientes de un git reset –hard? ¡No te preocupes! Git mantiene un registro de todas las acciones de la rama HEAD a través del comando git reflog. Este “registro de referencias” es tu salvavidas.

git reflog

alt text

El reflog muestra un historial completo y cronológico de cada movimiento de la rama HEAD, incluyendo los hashes de todos los commits a los que has apuntado, incluso aquellos que ya no están visibles en el git log.

Para recuperar un commit, simplemente buscamos el hash del estado al que queremos volver y usamos git reset –hard de nuevo.

Ejemplo práctico:
Si queremos regresar al punto donde agregamos a Linterna Verde y Robin, buscamos ese hash en el reflog.

alt text

Una vez encontrado el hash (9a2f345), lo usamos para volver a ese estado.

git reset --hard 9a2f345

alt text

¡Y listo! Todos los ficheros que habíamos eliminado, como ciudades.md y la carpeta historia, están de vuelta. Si ejecutamos git log, veremos que el historial de commits también se ha restaurado por completo.

alt text

alt text

Conclusiones y buenas prácticas

La capacidad de “viajar en el tiempo” con git reset y git reflog es una de las características más poderosas de Git. Te permite corregir errores y experimentar con tu proyecto sin miedo a perder trabajo. Sin embargo, es vital recordar que estas operaciones modifican el historial de commits.

En un contexto de desarrollo en equipo, el uso de git reset en ramas compartidas puede causar problemas para otros colaboradores. Por esta razón, se recomienda encarecidamente trabajar con ramas independientes. El uso de ramas te permite experimentar, desarrollar nuevas funcionalidades y corregir errores en un entorno aislado, sin afectar a la rama principal (main o master) hasta que el código esté listo. Más adelante, exploraremos este tema a profundidad.

Post Siguiente

Renombrar y eliminar archivos en git: Guía con git mv y git rm

Post Anterior

Cómo crear un repositorio de prueba para practicar comandos de git