Git: recuperación de changesets perdidos
Hoy me he enfrentado a un problema algo desagradable en Git: Borré un commit
. Básicamente había perdido un artículo de mi blog y algunos cambios más.
En condiciones normales, esto hubiera sido una pérdida terrible. Pero en este caso Git vino al rescate.
Pondré un ejemplo para perder changeset y después recuperarlos. Si tenéis prisa, saltad directamente a la sección “cómo recuperar un commit” :D
Perdiendo changesets o commits
Pero… ¿Cómo puede darse esta situación?
Pues basta con hacer commit
y luego cambiar el HEAD:
|
|
En este punto, el último commit
no es accesible (directamente):
|
|
Cómo recuperar un commit
Evidentemente, hay dos casos. En el primero sabemos el identificador del commit a recuperar, en este caso bea2640. Pero también está el caso chungo, en el que no conocemos este identificador. Veamos ambos.
Recuperar un commit dado su SHA-1
Nada más sencillo que hacer un cherry-pick
:
|
|
Otra opción es cambiar la referencia al HEAD:
|
|
Con cherry-pick
crearemos un commit nuevo, mientras que con reset
reutilizaremos el viejo. Cada uno tiene sus ventajas: si teníamos commits posteriores, con cherry-pick
los mantenemos, mientras que con reset
se eliminarán.
Averiguar el SHA-1 de un commit borrado
La otra opción, la que más nos puede asustar, es qué hacer si no tenemos el SHA-1 para poder recuperarlo. En este caso hay que preguntarle a Git por los changesets huérfanos:
|
|
En este punto podemos preguntar qué tiene ese changeset, para asegurarnos de que es lo que queremos:
|
|
Y proceder a recuperarlo tal y como hemos visto en el apartado anterior.
Explicación más detallada
En Git, un changeset o commit es un objeto. Los objetos tienen un SHA-1 único que los identifica. Si este objeto se encuentra en local pero no en remoto, puede referirse siempre mediante el SHA-1.
Las ramas, HEAD y otras referencias son… bueno, pues referencias XD. En otras palabras: son punteros a un SHA-1. Tal cual:
|
|
Así que podemos jugar con este SHA-1 persistente en lugar de usar las efímeras referencias. Es algo incómodo de recordar (risas), pero muy interesante para arreglar estropicios.
Más información
Podéis encontrar más información en la propia documentación de Git o ir a los posts que escribí yo mismo para sobre aprender a manejar Git(1), aprender a manejar Git(2), y aprender a manejar Git(3).