git-reflog

El salvavidas de Git reflog

  • 6 min

La herramienta git reflog (Reference Log) es un salvavidas interno de Git que mantiene un registro completo de todas las veces que el puntero local se ha actualizado en tu repositorio.

Hemos visto que el uso de comandos como git reset --hard conllevan un riesgo muy real de perder información.

Te vienes arriba. Piensas “voy a limpiar este historial” y ejecutas un git reset --hard. Entonces te das cuenta de que en ese commit que acabas de borrar había un archivo que no tienes en ningún otro sitio.

Haces git log y, efectivamente, el commit ha desaparecido. Ya no está. Al reescribir la historia, los commits eliminados desaparecen del historial estándar (git log),

Pero aún hay una herramienta que podría salvarte la situación. El Reference Log (Reflog). Puedes acceder a ella con git reflog.

¿Qué es el Reflog?

Lo normal es pensar que cuando haces un git reset, los commits “se borran”. No es del todo verdad. Git rara vez borra algo inmediatamente. Lo único que hace es ocultarlo.

Mientras que git log te muestra la historia “pública” de tu proyecto, el git reflog registra cada vez que se mueve el puntero HEAD en tu ordenador.

  • ¿Hiciste un commit? Se apunta en el reflog.
  • ¿Hiciste un reset? Se apunta en el reflog.
  • ¿Cambiaste de rama? Se apunta en el reflog.

El Reflog es un historial estrictamente local. No se sube a GitHub ni se comparte con tus compañeros. Es tu red de seguridad personal en tu máquina.

Simulando el desastre

Para entender cómo funciona, vamos a provocar un accidente.

Tenemos un proyecto con 3 commits (A, B y C).

Estamos en el commit C.

Ejecutamos un Hard Reset destructivo para volver al A

git reset --hard HEAD~2
Copied!

Si hacemos ahora un git log, solo vemos el commit A. Los commits B y C han “desaparecido”. Si intentamos buscarlos, no están en la lista. Aquí es donde entra el pánico.

El Rescate

Respira hondo y escribe en tu terminal:

git reflog
Copied!

Verás una lista algo diferente a la habitual:

a1b2c3d (HEAD -> main) HEAD@{0}: reset: moving to HEAD~2
98f1e2a HEAD@{1}: commit: Añadir funcionalidad C
76d5c4b HEAD@{2}: commit: Añadir funcionalidad B
a1b2c3d HEAD@{3}: commit: Inicio del proyecto
Copied!

¡Ajá! Ahí están. Fíjate en la primera línea (HEAD@{0}): Git ha registrado que acabas de hacer un “reset: moving to…”.

Pero fíjate en la segunda línea (HEAD@{1}): Ahí está el commit 98f1e2a con el mensaje “Añadir funcionalidad C”. El commit aún existe, solo que ninguna rama apunta a él.

Recuperando el commit perdido

Ahora que tenemos el identificador (el Hash) del commit “perdido” (98f1e2a), podemos viajar a él.

Podemos hacerlo de dos formas:

Crear una rama nueva apuntando a ese commit (La opción recomendada):

git branch rama-rescate 98f1e2a
Copied!

Esto crea una rama llamada rama-rescate que contiene todo tu trabajo hasta el commit C. ¡Salvado!

Hacer un reset hacia el futuro:

Si quieres deshacer tu error y volver a estar exactamente donde estabas antes del desastre:

git reset --hard 98f1e2a
Copied!

Sí, has leído bien. Has usado git reset para deshacer un git reset.

Ahora tu HEAD vuelve a apuntar al commit C. Tu carpeta vuelve a tener los archivos. El equilibrio del universo se ha restaurado.

Limitaciones del Reflog

Aunque Reflog puede salvarte el (…ya tu sabe’…) muchas veces, no es infalible. Es más bien el último recurso. Algunas cosas en las que no va a poder ayudarte:

Como dijimos, esto solo registra tus movimientos en tu disco duro. Si borras el repositorio de tu disco duro, el reflog se va con él.

Git no guarda la basura para siempre. Por defecto, las entradas del reflog y los commits “huérfanos” (que no pertenecen a ninguna rama) se eliminan pasados unos días (normalmente 30 días para referencias inalcanzables, o 90 días para las normales).

Es decir, si borras un commit hoy, puedes recuperarlo mañana. Pero no intentes recuperarlo dentro de seis meses.