Una guía para deshacer errores con Git (Parte 2)
Publicado: 2022-03-10En esta segunda parte de nuestra serie sobre "Deshacer errores con Git", volveremos a mirar valientemente el peligro a los ojos: he preparado cuatro nuevos escenarios apocalípticos, que incluyen, por supuesto, algunas formas inteligentes de salvarnos el cuello. Pero antes de sumergirnos: ¡eche un vistazo a los artículos anteriores sobre Git para obtener aún más métodos de autorrescate que lo ayuden a deshacer sus errores con Git!
¡Vamos!
Recuperación de una sucursal eliminada mediante Reflog
¿Alguna vez eliminó una rama y, poco después, se dio cuenta de que no debería haberlo hecho? En el improbable caso de que no conozcas este sentimiento, puedo decirte que no es bueno. Te invade una mezcla de tristeza e ira, mientras piensas en todo el arduo trabajo que se dedicó a las confirmaciones de esa rama, todo el código valioso que ahora has perdido.
Afortunadamente, hay una manera de revivir esa rama de entre los muertos, con la ayuda de una herramienta de Git llamada "Reflog". Habíamos usado esta herramienta en la primera parte de nuestra serie, pero aquí hay un pequeño repaso: Reflog es como un diario donde Git anota cada movimiento del puntero HEAD en su repositorio local. En otras palabras menos nerds: cada vez que pagas, confirmas, fusionas, cambias de base, seleccionas, etc., se crea una entrada de diario. ¡Esto hace que Reflog sea una red de seguridad perfecta cuando las cosas van mal!
Veamos un ejemplo concreto:
$ git branch * feature/login master
Podemos ver que actualmente tenemos verificada nuestra feature/login
de sesión de sucursal. Digamos que esta es la rama que vamos a eliminar (sin darnos cuenta). Sin embargo, antes de que podamos hacer eso, debemos cambiar a una rama diferente porque no podemos eliminar nuestra rama HEAD actual.
$ git checkout master $ git branch -d feature/login
Nuestra valiosa rama de características ya no está, y les daré un minuto para (a) comprender la gravedad de nuestro error y (b) llorar un poco. ¡Después de que hayas limpiado las lágrimas, tenemos que encontrar una manera de traer de vuelta esta rama! Abramos Reflog (simplemente escribiendo git reflog
) y veamos qué nos depara:
Aquí hay algunos comentarios para ayudarlo a dar sentido a la salida:
- En primer lugar, debe saber que Reflog ordena sus entradas cronológicamente: los elementos más nuevos están en la parte superior de la lista.
- El elemento superior (y, por lo tanto, el más nuevo) es el comando
git checkout
que realizamos antes de eliminar la rama. Está registrado aquí en el Reflog porque es uno de estos "movimientos de puntero HEAD" que el Reflog registra tan debidamente. - Para deshacer nuestro grave error, simplemente podemos volver al estado anterior , que también se registra limpia y claramente en el Reflog.
Así que intentemos esto, creando una nueva rama (con el nombre de nuestra rama "perdida") que comienza en este hash SHA-1 de estado "antes":
$ git branch feature/login 776f8ca
¡Y voilá! ¡Te encantará ver que ahora hemos restaurado nuestra sucursal aparentemente perdida!
Si está utilizando una GUI de escritorio Git como "Torre", puede tomar un buen atajo: simplemente presione CMD + Z en su teclado para deshacer el último comando, ¡incluso si acaba de eliminar violentamente una rama!
Mover una confirmación a una rama diferente
En muchos equipos, existe un acuerdo para no realizar compromisos en ramas de ejecución prolongada como main
o develop
: ramas como estas solo deben recibir nuevos compromisos a través de integraciones (por ejemplo, fusiones o rebases). Y, sin embargo, por supuesto, los errores son inevitables: ¡a veces olvidamos y cometemos en estas ramas, no obstante! Entonces, ¿cómo podemos limpiar el desastre que hicimos?
Afortunadamente, este tipo de problemas se pueden corregir fácilmente. Arremanguémonos y manos a la obra.
El primer paso es cambiar a la rama de destino correcta y luego mover la confirmación usando el comando cherry-pick
:
$ git checkout feature/login $ git cherry-pick 776f8caf
Ahora tendrá la confirmación en la rama deseada, donde debería haber estado en primer lugar. ¡Increíble!
Pero todavía queda una cosa por hacer: ¡necesitamos limpiar la rama donde aterrizó accidentalmente al principio! El comando cherry-pick
, por así decirlo, creó una copia de la confirmación, pero el original aún está presente en nuestra rama de ejecución prolongada:
Esto significa que tenemos que volver a nuestra rama de ejecución prolongada y usar git reset
para eliminarla:
$ git checkout main $ git reset --hard HEAD~1
Como puede ver, estamos usando el comando git reset
aquí para borrar la confirmación defectuosa. El parámetro HEAD~1
le dice a Git que "retroceda 1 revisión detrás de HEAD", borrando efectivamente la confirmación superior (y en nuestro caso: no deseada) del historial de esa rama.
Y listo: la confirmación ahora está donde debería haber estado en primer lugar y nuestra rama de ejecución prolongada está limpia, ¡como si nuestro error nunca hubiera ocurrido!
Edición del mensaje de una confirmación antigua
Es demasiado fácil pasar de contrabando un error tipográfico en un mensaje de confirmación, y solo descubrirlo mucho más tarde. En tal caso, la buena y antigua opción --amend
de git commit
no se puede usar para solucionar este problema, porque solo funciona para la última confirmación. Para corregir cualquier confirmación que sea más antigua, tenemos que recurrir a una herramienta de Git llamada “Interactive Rebase”.
Primero, tenemos que decirle a Interactive Rebase qué parte del historial de confirmaciones queremos editar. Esto se hace alimentándolo con un hash de confirmación: la confirmación principal de la que queremos manipular.
$ git rebase -i 6bcf266b
A continuación, se abrirá una ventana de edición. Contiene una lista de todas las confirmaciones después de la que proporcionamos como base para la Rebase interactiva en el comando:
Aquí, es importante que no sigas tu primer impulso: en este paso, todavía no editamos el mensaje de confirmación. En su lugar, solo le decimos a Git qué tipo de manipulación queremos hacer con qué compromiso(s). Muy convenientemente, hay una lista de palabras clave de acción anotadas en los comentarios en la parte inferior de esta ventana. Para nuestro caso, marcamos la línea n.º 1 con una reword
(reemplazando así la pick
estándar).
Todo lo que queda por hacer en este paso es guardar y cerrar la ventana del editor. A cambio, se abrirá una nueva ventana del editor que contiene el mensaje actual de la confirmación que marcamos. ¡Y finalmente es el momento de hacer nuestras ediciones!
Aquí está todo el proceso de un vistazo para usted:
Corrección de un compromiso roto (de una manera muy elegante)
Finalmente, vamos a echar un vistazo a fixup
, la navaja suiza de las herramientas de deshacer. En pocas palabras, le permite corregir una confirmación rota/incompleta/incorrecta después del hecho. Es realmente una herramienta maravillosa por dos razones:
- No importa cuál sea el problema.
Es posible que haya olvidado agregar un archivo, debería haber eliminado algo, realizado un cambio incorrecto o simplemente un error tipográfico.fixup
funciona en todas estas situaciones! - Es extremadamente elegante.
Nuestra reacción normal e instintiva a un error en una confirmación es producir una nueva confirmación que solucione el problema. Esta forma de trabajar, por muy intuitiva que parezca, hace que tu historial de confirmaciones parezca muy caótico, muy pronto. Tiene confirmaciones "originales" y luego estas pequeñas confirmaciones "curitas" que arreglan las cosas que salieron mal en las confirmaciones originales. Su historial está plagado de pequeñas confirmaciones de curitas sin sentido que dificultan la comprensión de lo que sucedió en su base de código.
Aquí es donde entra en fixup
la reparación. Le permite aún hacer este compromiso de curita de corrección. Pero aquí viene la magia: luego lo aplica al compromiso original roto (reparándolo de esa manera) y luego descarta por completo el feo compromiso de curita.
¡Podemos pasar juntos por un ejemplo práctico! Digamos que la confirmación seleccionada aquí está rota.
Digamos también que he preparado cambios en un archivo llamado error.html
que solucionará el problema. Aquí está el primer paso que debemos hacer:
$ git add error.html $ git commit --fixup 2b504bee
Estamos creando una nueva confirmación, pero le decimos a Git que es especial: es una solución para una confirmación anterior con el hash SHA-1 especificado ( 2b504bee
en este caso).
El segundo paso, ahora, es iniciar una sesión de Interactive fixup
, porque la corrección pertenece al gran conjunto de herramientas de Interactive Rebase.
$ git rebase -i --autosquash 0023cddd
Vale la pena explicar dos cosas acerca de este comando. Primero, ¿por qué proporcioné 0023cddd
como hash de revisión aquí? Porque necesitamos comenzar nuestra sesión de Rebase interactiva en la confirmación principal de nuestro compañero roto.
Segundo, ¿para qué sirve la opción --autosquash
? ¡Nos quita mucho trabajo de encima! En la ventana del editor que ahora se abre, ya está todo preparado para nosotros:
Gracias a la opción --autosquash
, Git ya ha hecho el trabajo pesado por nosotros:
- Marcó nuestro pequeño compromiso de curita con la palabra clave de acción de
fixup
. De esa manera, Git lo combinará con el compromiso directamente arriba y luego lo descartará. - También reordenó las líneas en consecuencia, moviendo nuestro compromiso de curita directamente debajo del compromiso que queremos corregir (nuevamente: ¡la
fixup
funciona al combinar el compromiso marcado con el de arriba !).
En resumen: ¡no hay nada que hacer por nosotros más que cerrar la ventana!
Echemos un vistazo final al resultado final.
- La confirmación anteriormente rota está arreglada: ahora contiene los cambios que preparamos en nuestra confirmación curita.
- El feo compromiso de curita en sí mismo ha sido descartado: el historial de compromisos es limpio y fácil de leer, como si no hubiera ocurrido ningún error.
Saber deshacer errores es un superpoder
¡Felicidades! ¡Ahora puedes salvar tu cuello en muchas situaciones difíciles! Realmente no podemos evitar estas situaciones: no importa la experiencia que tengamos como desarrolladores, los errores son simplemente parte del trabajo. Pero ahora que sabes cómo lidiar con ellos, puedes enfrentarlos con un ritmo cardíaco relajado.
Si desea obtener más información sobre cómo deshacer errores con Git, puedo recomendar el "Botiquín de primeros auxilios para Git" gratuito, una serie de videos cortos sobre exactamente este tema.
Diviértete cometiendo errores y, por supuesto, deshaciéndolos con facilidad.