Categorías
- Redes (10)
- Git y GitHub (23)
- Desarrollo de software (21)
- Sistemas operativos (28)
Viajes en el tiempo con git: Cómo usar git reset y git reflog
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.

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

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.

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

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

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.

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

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.

Lo mismo ocurre si regresamos a un commit aún más antiguo, como el de heroes.md.
git reset --hard 7f3c04f


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.

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

Por último, haremos otra regresión al commit de “misiones”.
git reset --hard 67b4163

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

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.

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

¡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.


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.
Agregados recientemente
- Guía para la gestión de permisos en Linux con chmod
- Comprendiendo los permisos de archivos y directorios en Linux
- Aprende a escribir scripts en Linux: De la línea de comandos a la automatización
- El comando Grep: Búsqueda y filtrado de patrones en Linux
- Introducción al manejo de procesos en Linux (foreground, background, kill y más)
- Pipes en Linux: El poder de encadenar comandos
- Comandos esenciales para la administración de usuarios en Linux
