Este artículo es parte de nuestra serie “Advanced Git”. Asegúrate de Síguenos en Twitter o suscríbete a nuestro boletín de noticias para conocer artículos futuros.
El “Reflog” es una de las características menos conocidas de Git, pero una que puede ser extremadamente útil. Algunas personas se refieren a él como una “red de seguridad”, mientras que a mí me gusta pensar en él como el “diario” de Git. Eso es porque Git lo usa para llevar un diario sobre cada movimiento del HEAD
puntero (es decir, cada vez que confirma, fusiona, rebasa, selecciona, reinicia, etc.). Git registra sus acciones en el Reflog, lo que lo convierte en un libro de registro valioso y un buen punto de partida cuando algo salió mal.
En esta última parte de nuestra serie “Advanced Git”, explicaré las diferencias entre git log
y git reflog
, y te mostraré cómo usar Reflog para recuperar confirmaciones eliminadas, así como ramas eliminadas.
Serie avanzada de Git:
- Parte 1: Creando el compromiso perfecto en Git
- Parte 2: Estrategias de ramificación en Git
- Parte 3: Mejor colaboración con solicitudes de extracción
- Parte 4: Fusionar conflictos
- Parte 5: Rebase vs. Fusionar
- Parte 6: Rebase interactiva
- Parte 7: Compromisos de selección de cerezas en Git
- Parte 8: Uso de Reflog para restaurar confirmaciones perdidas (¡Usted está aquí!)
git log
o git reflog
: ¿cual es la diferencia?
En artículos anteriores, le recomendé que utilice el git log
comando para inspeccionar eventos anteriores y mirar su historial de confirmaciones, y eso es exactamente lo que hace. Muestra la corriente HEAD
y sus antepasados, es decir, su padre, el siguiente padre en línea, etc. El registro se remonta al historial de confirmaciones imprimiendo de forma recursiva el padre de cada confirmación. Es parte del repositorio, lo que significa que se replica después de presionar, recuperar o extraer.
git reflog
, por otro lado, es una grabación privada y relacionada con el espacio de trabajo. No pasa por la lista de antepasados. En cambio, muestra una lista ordenada de todas las confirmaciones que HEAD
ha señalado en el pasado. Es por eso que puede considerarlo como una especie de “historial de deshacer”, como puede ver en procesadores de texto, editores de texto, etc.
Esta grabación local técnicamente no es parte del repositorio y se almacena por separado de las confirmaciones. El Reflog es un archivo en .git/logs/refs/heads/
y rastrea las confirmaciones locales para cada rama. El diario de Git generalmente se limpia después de 90 días (esa es la configuración predeterminada), pero puede ajustar fácilmente la fecha de vencimiento del Reflog. Para cambiar la cantidad de días a 180, simplemente escriba el siguiente comando:
$ git config gc.reflogExpire 180.days.ago
El archivo de configuración del repositorio (.git/config
) ahora incluye la variable reflogExpire
con el valor 180.days.ago
Alternativamente, puede decidir que su Reflog nunca caduque:
$ git config gc.reflogExpire never
Propina: Recuerde que Git hace una distinción entre el archivo de configuración del repositorio (.git/config
), la configuración global por usuario ($HOME/.gitconfig
) y la configuración de todo el sistema (/etc/gitconfig
). Para ajustar la fecha de vencimiento del Reflog para el usuario o el sistema, agregue el --system
o --global
parámetro a los comandos que se muestran arriba.
Suficiente trasfondo teórico. Déjame mostrarte cómo trabajar con git reflog
para corregir errores.
Recuperar confirmaciones eliminadas
Imagina el siguiente escenario: después de ver tu historial de confirmaciones, decides deshacerte de las dos últimas confirmaciones. Realizas valientemente un git reset
, las dos confirmaciones desaparecen del historial de confirmaciones … y un rato después, notas que se trata de un error. ¡Acaba de perder valiosos cambios y comienza a entrar en pánico!
¿Realmente tienes que empezar de cero de nuevo? Tu no En otras palabras: mantén la calma y usa git reflog
!
Entonces, estropeemos las cosas y cometamos este error en la vida real. La siguiente imagen muestra nuestro historial de confirmaciones original en Tower, un cliente gráfico de Git:
Queremos deshacernos de dos confirmaciones y realizar la confirmación “Cambiar titulares para about e imprint” (ID: 2b504bee
) nuestra última revisión sobre el master
rama. Todo lo que tenemos que hacer es copiar el ID de hash al portapapeles y luego usar git reset
en la línea de comando e ingrese ese hash:
$ git reset --hard 2b504bee
Voilà. Las confirmaciones han desaparecido. Ahora, supongamos que esto fue un error y echemos un vistazo al Reflog para recuperar los datos perdidos. Escribe git reflog
para ver el diario en su terminal:
Notarás que todas las entradas están ordenadas cronológicamente. Eso significa: las confirmaciones más recientes, las más recientes, están en la parte superior. Y, si miras de cerca, notarás el fatal git reset
acción de hace unos minutos justo en la parte superior.
El diario parece funcionar, eso es una buena noticia. Entonces, usémoslo para deshacer esa última acción y restaurar el estado antes del comando de reinicio. Copie el ID de hash (que es e5b19e4
en este ejemplo específico) al portapapeles, como antes. Podrías usar git reset
de nuevo, lo cual es totalmente válido. Pero en este caso, voy a crear una nueva rama basada en el estado anterior:
$ git branch happy-ending e5b19e4
Echemos un vistazo a nuestro cliente gráfico Git nuevamente:
Como puede ver, la nueva rama, happy-ending
, se ha creado e incluye las confirmaciones que eliminamos anteriormente: ¡increíble, no se pierde nada!
Veamos otro ejemplo y usemos Reflog para recuperar una rama completa.
Recuperar ramas eliminadas
El siguiente ejemplo se parece a nuestro primer escenario: vamos a eliminar algo; esta vez, es una rama completa la que tiene que desaparecer. Tal vez su cliente o el líder de su equipo le haya dicho que se deshaga de una rama de funciones, tal vez fue su propia idea limpiarla. Para empeorar las cosas, un compromiso (C3
en la imagen) no está incluido en ninguna de las otras ramas, por lo que definitivamente perderá datos:
Realmente hagamos esto y luego recuperemos la rama más tarde:
Antes de poder eliminar la rama feature/login
, debes alejarte de él. (Como puede ver en la captura de pantalla, es el actual HEAD
rama, y no puede eliminar la HEAD
rama en Git.) Entonces, vamos a cambiar ramas (a master
) y luego vamos a eliminar feature/login
:
Bien … ahora digamos que nuestro cliente o líder de equipo cambió de opinión. El feature/login
Después de todo, se desea una rama (incluidas sus confirmaciones). ¿Qué debemos hacer?
Echemos un vistazo al diario de Git:
$ git reflog
776f8ca (HEAD -> master) [email protected]{0}: checkout: moving from feature/login to master
b1c249b (feature/login) [email protected]{1}: checkout: moving from master to feature/login
[...]
Resulta que volvemos a tener suerte. La última entrada muestra nuestro cambio de feature/login
a master
. Intentemos regresar al estado justo antes de eso y copiemos el ID de hash b1c249b
al portapapeles. A continuación, crearemos una rama llamada feature/login
basado en el estado deseado:
$ git branch feature/login b1c249b
$ git branch -vv
feature/login b1c249b Change Imprint page title
* master 776f8ca Change about title and delete error page
Genial, la rama ha vuelto de entre los muertos y también incluye ese valioso compromiso que pensamos que habíamos perdido:
Si está utilizando Git en una GUI de escritorio como Tower, simplemente puede presionar CMD + Z para deshacer su última acción, como un editor de texto o un procesador de texto cuando comete un error tipográfico.
Mantenga la calma y no pierda de vista
¡Reflog de Git puede ser un verdadero salvavidas! Como puede ver, es bastante fácil sacar confirmaciones perdidas o incluso ramas enteras de la tumba. Lo que debe hacer es encontrar el ID de hash correcto en el Reflog; el resto es pan comido.
Si desea profundizar en las herramientas avanzadas de Git, no dude en consultar mi “Kit de Git avanzado” (gratuito): es una colección de videos cortos sobre temas como estrategias de ramificación, Rebase interactiva, Reflog, Submódulos y mucho más.
Esta fue la última parte de nuestra serie sobre “Git avanzado” aquí en CSS-Tricks. Espero que hayan disfrutado de los artículos. ¡Feliz piratería!
Serie avanzada de Git:
- Parte 1: Creando el compromiso perfecto en Git
- Parte 2: Estrategias de ramificación en Git
- Parte 3: Mejor colaboración con solicitudes de extracción
- Parte 4: Fusionar conflictos
- Parte 5: Rebase vs. Fusionar
- Parte 6: Rebase interactiva
- Parte 7: Compromisos de selección de cerezas en Git
- Parte 8: Uso de Reflog para restaurar confirmaciones perdidas (¡Usted está aquí!)