¿Qué es reflog?
Ya sabemos que git nos ayuda a hacer un seguimiento de todos las actualizaciones (“commits”) que realizamos. Este mecanismo para realizar el seguimiento de todas las actualizaciones se llama “reflog”. la información que recoge el “reflog” viene siendo la “misma” que la del git log
, pero presentada de manera diferente ya que es almacenada dentro de la misma carpeta .git/logs/
.
Como ya dijimos que “reflog” es el mecanismo para realizar seguimiento de todas las actualizaciones de nuestro proyecto, podemos afirmar en pocas palabras que nos permite visualizar “commits” perdidos. Puede ocurrir, que en algún momento, uno de los “commits” que hemos realizado se pierda, borremos una rama, o simplemente cuando reescribimos el historial de cambios borramos algo no deseado. El “reflog” tiene archivados todos y cada uno de los estados anteriores de una rama y nos permite revertir o ir a cualquier estado anterior del proyecto de ser necesario. Es muy importante tener claro lo que esta herramienta realiza, ya que seguramente la vamos a tener que utilizar en algún momento.
¿Qué se escribe en el reflog?
Cada vez que se acuatiza la cabeza “HEAD” del árbol en que nos encontremos se escribe en el “reflog”. Es decir, cada vez que cambiamos de rama, realizamos un “pull”, utilizamos un “merge”, “rebase”, o simplemente agregamos un nuevo “commit”, git escribe dentro del “reflog”.
¿Cómo se usa?
El “reflog” se utiliza por medio del comando git reflog
tiene ciertas banderas como “expire” para expirar datos dentro del “reflog”, pero por lo general solo utilizamos el comando normal.
123456789 $gitreflog--relative-dateOnbranchmaster926a59cHEAD@{7days ago}:reset:movingto926a59cc1c47fede5HEAD@{7days ago}:commit:Pruebadelhook926a59cHEAD@{2weeks ago}:reset:movingto926a59c2614422HEAD@{2weeks ago}:reset:movingto2614422d18926a59cHEAD@{2weeks ago}:reset:movingto926a59c2614422HEAD@{2weeks ago}:reset:moving to2614422d18
Mediante la bandera --relative-date
apreciamos una fecha relativa de cuando se realizó el “commit” {7 days ago}
, esto nos puede ayudar de cierta manera a orientarnos mejor.
Si necesitan recuperar algo particular a partir de este momento solo deben utilizar el comando git checkout
y luego git reset --hard HashDelCommit
para recuperar o ir a un estado particular.
Hagamos esta simple prueba, vamos a regresar al “commit” del capítulo 8 de número de13f1b
lo vamos a buscar el por mensaje.
123 $git reflog--relative-date|grep-iplaneadode13f1bHEAD@{7weeks ago}:rebase-i(squash):Commit planeadoarchivonuevoyviejoa735092HEAD@{7weeks ago}:commit:Commit planeadoarchivo nuevoyviejo
Luego vamos a crear una rama nueva para no afectar el estado actual de nuestra rama principal.
$ git co -b prueba-reflog Switched to a new branch 'prueba-reflog'12 $git co-bprueba-reflogSwitched toanewbranch'prueba-reflog'
Y por último a ir a ese estado particular.
$ git reset --hard de13f1b HEAD is now at de13f1b Commit planeado. archivo nuevo y viejo12 $git reset--hard de13f1bHEAD isnow at de13f1b Commit planeadoarchivo nuevoyviejo
Este procedimiento es exactamente el mismo que se debe realizar cuando se pierde un “commit”, y de querer podemos utilizar git cherry-pick
para trasladar el “commit” a la rama que queramos.
¿Qué es fsck?
“Fsck” es esa herramienta que viene a salvarnos la vida cuando creemos que todo está perdido. En sistemas operativos *nix el comando “fsck” es referido a “File System Check” y revisa las inconsistencias del “File System” para comprobar de que no se haya perdido o dañado nada con un apagón repentino o un “crash” de algún programa. En git el comando revisa la integridad de la base de datos interna de git y busca los objetos que no esten apuntados a otro objeto.
Cuando se pierde un “commit” y no tenemos el “reflog” ya sea porque los expiramos en alguna oportunidad o simplemente borramos la carpeta .git/logs
el comando git fsck
puede ayudarnos a identificar estos “commits” sueltos a los que nosotros nos referimos como perdidos.
¿Cómo se usa?
El “fsck” se utiliza por medio del comando git fsck
. Una vez aplicado el comando comienza a revisar la base de datos de git. También podemos utilizar las siguientes banderas --full
o --unreachable
. “full” realiza una revisión de múltiples carpetas para encontrar todos los objetos posibles. Por otra parte “unreachable” refleja los objetos que existen pero no se pueden encontrar en ningún otro nodo de referencias. Cuando se encuentran aquí es porque probablemente nosotros borramos una rama o “tag” que los contenía.
Vamos a probar los dos comandos y observar las distintas salidas.
$ git fsck --full Checking object directories: 100% (256/256), done. dangling blob 43882b2283b87566d08b5307ff3c5e8abd095b6f dangling commit 4b7347b7514526606484599ee67d7b7abb601a14 dangling blob b4f0de027a1ccdc432ac652052e78e2f53caa1ff dangling blob bead78cc772d5149ce300480d274d09cf5632368 dangling commit eb15ce2cc60a1829f24442fb14b3e69eb0866580 dangling commit f511b3332361558cff180717868ac208132bb2bf12345678 $git fsck--fullChecking objectdirectories:100%(256/256),donedangling blob43882b2283b87566d08b5307ff3c5e8abd095b6fdangling commit4b7347b7514526606484599ee67d7b7abb601a14dangling blob b4f0de027a1ccdc432ac652052e78e2f53caa1ffdangling blob bead78cc772d5149ce300480d274d09cf5632368dangling commit eb15ce2cc60a1829f24442fb14b3e69eb0866580dangling commit f511b3332361558cff180717868ac208132bb2bf
Ahora aplicamos el --unreachable
1234567891011 $git fsck--unreachableChecking objectdirectories:100%(256/256),doneunreachable commit32018436db16348f4d84bb8b40aa394a195c6dedunreachable blob43882b2283b87566d08b5307ff3c5e8abd095b6funreachable commit4b7347b7514526606484599ee67d7b7abb601a14unreachable commit81d47a325c1a73efe01fb67753ff2c32e0da44c0unreachable commit a1248a18c03eedac7046bc140d058647aded02abunreachable blob b4f0de027a1ccdc432ac652052e78e2f53caa1ffunreachable blob bead78cc772d5149ce300480d274d09cf5632368unreachable commit eb15ce2cc60a1829f24442fb14b3e69eb0866580unreachable commit f511b3332361558cff180717868ac208132bb2bf
Podemos apreciar que entre los dos existen objetos similares y todos tienen un “hash” por lo cual si aplicamos el mismo procedimiento utilizado con el “reflog” vamos a poder retornar dicho “commit” a el historial.
Debemos tener en cuenta que estos objetos que se reflejan no duran para siempre; es muy probable que en algún momento sean eliminados por git si el mismo comienza a correr su gc (“garbage colector”) o corremos el comando git gc
.
Conclusión
En este último capítulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento necesario para poder recuperar algún “commit” que hayamos podido borrar. Como sugerencia debes tener en cuenta que si esperas demasiado para recuperar un “commit” puede ser demasiado tarde si git ya corrió su recolector de basura, así que si identificas que algo no está bien corre los comandos “reflog” y “fsck” para asegurar de que todo está como debería estar. Te invitamos a revisar la documentación de ambas herramientas. Si te surge algún tipo de duda no te detengas y déjanos un comentario, que gustosamente lo responderemos.
¡Hasta la semana entrante!