Uso de Reflog para restaurar confirmaciones perdidas | Programar Plus

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

Captura de pantalla de una Terminal con fondo amarillo claro y texto negro.  El contenido muestra la salida del 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:

Captura de pantalla de la interfaz de la aplicación Tower.  A la izquierda hay una navegación con el elemento Historial seleccionado.  En el panel central hay un esquema visual del historial de confirmaciones que muestra los avatares de las personas que realizaron las confirmaciones.  Se selecciona la segunda confirmación y, a la derecha, hay un panel que muestra más detalles sobre la confirmación, incluido el autor, la fecha, el confirmador, las referencias, los valores hash y los archivos modificados.

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

Captura de pantalla de la interfaz de la aplicación Tower.  La rama maestra se selecciona en la navegación derecha, la primera confirmación se selecciona en el panel central y el detalle de esa confirmación se muestra en el panel derecho.  Las confirmaciones en el panel central son limpias y lineales sin ninguna confirmación o bifurcación adicional.

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:

Captura de pantalla de una ventana de Terminal abierta con un fondo amarillo claro.  El texto es principalmente negro, pero algunas palabras están resaltadas en rojo, azul claro y verde brillante.  La línea superior es el comando git reset --hard 2b504bee.  La segunda línea dice que el encabezado está ahora en ese ID de confirmación.  La tercera línea es el comando git reflog, que genera el historial.

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:

Una captura de pantalla de la terminal con un fondo amarillo claro y la salida para git reflog en ella, en la parte superior de una captura de pantalla de la ventana de la aplicación Tower, que muestra el historial de confirmación actualizado después del comando.

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:

Ilustración que muestra el flujo del historial de confirmación de una función / rama de inicio de sesión con la ID C2 eliminada de una rama C2 que está fuera de la rama maestra.  Al lado del diagrama hay una lista de los pasos tomados para eliminar la rama, que finaliza con el paso 4: entra en pánico junto a un emoji que grita.

Realmente hagamos esto y luego recuperemos la rama más tarde:

Captura de pantalla de la interfaz de la aplicación Tower que muestra la rama de inicio de sesión seleccionada en el panel izquierdo, el historial de confirmación de esa rama en el panel central con la primera confirmación seleccionada y resaltada en azul, luego los detalles de la confirmación en el panel derecho, incluido el autor, fecha, referencias, casos y archivos modificados.

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:

Captura de pantalla de una ventana de Terminal abierta con un fondo amarillo claro y texto en su mayoría negro, aunque los nombres de la rama y el confirmador están resaltados en verde brillante.  El primer comando es git status, el segundo es git checkout master, el tercero es git branch -vv, el cuarto es git branch -D feature / login y el último comando es git branch -vv.

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:

Captura de pantalla de la interfaz de la aplicación Tower.  La función / rama de inicio de sesión se selecciona en el panel izquierdo, el historial de confirmaciones de la rama está en el panel central con la primera confirmación seleccionada, y el panel izquierdo muestra más información sobre la confirmación, incluido el autor, la fecha, las referencias, los hash y archivos modificados.

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í!)