Cómo (y por qué!) Mantener limpio su historial de confirmaciones de Git

Las confirmaciones son una de las partes clave de un repositorio de Git, y más aún, el mensaje de confirmación es un registro de vida del repositorio. A medida que el proyecto / repositorio evoluciona con el tiempo (se agregan nuevas características, se corrigen errores, se refactoriza la arquitectura), los mensajes de confirmación son el lugar donde se puede ver qué se cambió y cómo. Por eso es importante que estos mensajes reflejen el cambio subyacente de una manera breve y precisa.

Por qué es importante un historial de confirmaciones de Git significativo

¿Qué hace la confirmación de Git? Mensajes de confirmación de Git son las huellas digitales que dejas en el código que tocas. Cualquier código que confirmes hoy, dentro de un año cuando veas el mismo cambio; estarías agradecido por un mensaje de confirmación claro y significativo que escribiste, y también hacer la vida de sus compañeros desarrolladores más fácil. Cuando las confirmaciones se aíslan según el contexto, un error que fue introducido por una determinada confirmación se vuelve más rápido de encontrar y más fácil es revertir la confirmación que causó el error en primer lugar.

Mientras trabajamos en un proyecto grande, a menudo nos ocupamos de muchas partes móviles que se actualizan, agregan o eliminan. Asegurar que los mensajes de confirmación se mantengan en tales casos podría ser complicado, especialmente cuando el desarrollo se extiende a lo largo de días. semanas o incluso meses. Para simplificar el esfuerzo de mantener la concisión En el historial de confirmaciones, este artículo usará algunas de las situaciones comunes que un desarrollador podría enfrentar mientras trabaja en un repositorio de Git.

  • Situación 1: Necesito cambiar la confirmación más reciente
  • Situación 2: Necesito cambiar una confirmación específica
  • Situación 3: Necesito agregar, eliminar o combinar confirmaciones
  • Situación 4: Mi historial de confirmaciones no hace sentido, necesito un nuevo comienzo!

Pero antes de sumergirnos, veamos rápidamente cómo se ve un flujo de trabajo de desarrollo típico en nuestra hipotética aplicación Ruby.

Nota: Este artículo asume que conoce los conceptos básicos de Git, cómo funcionan las ramas, cómo agregar cambios no confirmados de una rama a la etapa y cómo confirmar los cambios. Si no está seguro de estos flujos, nuestra documentación es un excelente punto de partida.

Un día en la vida

Aquí, estamos trabajando en un pequeño proyecto de Ruby on Rails en el que necesita agregar una vista de navegación en la página de inicio y eso implica actualizar y agregar varios archivos. A continuación, se muestra un desglose paso a paso de todo el flujo:

  • Comienza a trabajar en una función con la actualización de un archivo ; llamémoslo application_controller.rb
  • Esta función requiere que también actualice una vista: index.html.haml
  • Agregó un parcial que se usa en la página de índice: _navigation.html.haml
  • Los estilos de la página también deben actualizarse para reflejar el parcial que agregamos: styles.css.scss
  • La función ahora está lista con los cambios deseados, es hora de actualizar también las pruebas; Los archivos que se actualizarán son los siguientes:
    • application_controller_spec.rb
    • navigation_spec.rb
  • Las pruebas se actualizan y pasan como se esperaba, ¡ahora es el momento de confirmar los cambios!

Dado que todos los archivos pertenecen a diferentes territorios de la arquitectura, confirmamos los cambios se aíslan entre sí para garantizar que cada confirmación representa un contexto determinado y se realiza en un orden determinado. Por lo general, prefiero el backend: > orden de frontend donde la mayoría de los cambios centrados en el backend se confirman primero, seguido de la capa intermedia y luego de los cambios centrados en el frontend en la lista de confirmaciones de Git. >

Ahora que hemos confirmado nuestros cambios, creamos una solicitud de fusión con la rama. Una vez que tiene abierta la solicitud de fusión, normalmente su compañero la revisa antes de que los cambios se fusionen en la rama master del repositorio. Ahora, aprendamos en qué situaciones diferentes podemos terminar. durante la revisión del código.

Situación 1: Necesito cambiar la confirmación más reciente

Imagine un caso en el que el revisor miró styles.css.scss y sugirió un cambio. En tal caso, es muy simple hacer el cambio ya que los cambios de la hoja de estilo son parte de la última confirmación en su rama. Así es como podemos manejar esto:

  • Realiza directamente los cambios necesarios en styles.css.scss en tu rama.
  • Una vez ya terminó con los cambios, agregue estos cambios al escenario; ejecute git add styles.css.scss.
  • Una vez que los cambios están organizados, necesitamos agregar estos cambios a nuestra última confirmación; ejecute git commit --amend.
    • Desglose del comando: aquí, le estamos pidiendo al comando git commit que modifique los cambios presentes en etapa a la confirmación más reciente.
  • Esto abrirá su última confirmación en su editor de texto definido por Git que tiene el mensaje de confirmación Agregar estilos para la navegación.
  • Dado que solo actualizamos la declaración CSS, no es necesario modificar el mensaje de confirmación.En este punto, puede guardar y salir del editor de texto que Git abrió para usted y sus cambios se reflejarán en la confirmación.

Dado que modificó una confirmación existente, estos cambios son necesarios para ser forzado a su repositorio remoto usando git push --force-with-lease <remote_name> <branch_name>. Este comando anulará la confirmación Add styles for navigation en el repositorio remoto con la confirmación actualizada que acabamos de realizar en nuestro repositorio local.

Una cosa a tener en cuenta al forzar la inserción de ramas es que si está trabajando en la misma rama con varias personas, forzar el empuje puede causar problemas a otros usuarios cuando intentan normalmente empujar sus cambios en una rama remota que tiene nuevos compromisos forzados. Por lo tanto, utilice esta función con prudencia. Puede obtener más información sobre las opciones de inserción forzada de Git aquí.

Situación 2: Necesito cambiar una confirmación específica

En la situación anterior, la solución fue bastante simple, ya que tuvimos que modificar solo nuestra última confirmación de Git, pero imagina si el revisor sugirió cambiar algo en _navigation.html.haml. En este caso, es el segundo compromiso desde arriba, por lo que cambiarlo no será tan directo como en la primera situación. Veamos cómo podemos manejar esto:

Siempre que se realice un compromiso hecho en una rama, se identifica mediante una cadena hash SHA1 única. Piense en ello como una identificación única que separa una confirmación de otra. Puede ver todas las confirmaciones, junto con sus hashes SHA1 en una rama, ejecutando git log. Con esto, verá una salida que se parece a lo siguiente, donde las confirmaciones más recientes están en la parte superior:

Aquí es donde entra en juego el comando git rebase. Siempre que deseamos editar una confirmación específica con git rebase, primero necesitamos volver a establecer la base de nuestra rama moviendo HEAD hacia atrás al punto justo antes de la confirmación que deseamos editar. En nuestro caso, necesitamos cambiar la confirmación que dice Page Navigation View.

Aquí, observe el hash de confirmación que está justo antes de la confirmación que queremos modificar; copie el hash y realice los siguientes pasos:

  • Rebase de la rama para pasar a confirmar antes de nuestro compromiso objetivo; ejecutar git rebase -i 8d74af102941aa0b51e1a35b8ad731284e4b5a20
    • Desglose de comandos: aquí «estamos ejecutando el comando rebase de Git con modo interactivo con hash SHA1 proporcionado como compromiso para rebase.
  • Esto ejecutará el comando rebase para Git en modo interactivo y abrirá su editor de texto mostrando todas sus confirmaciones que vinieron después de la confirmación a la que rebasó. . Se verá algo así:

Observe cómo cada confirmación tiene una palabra pick delante de él, y en el contenido a continuación, hay todas las palabras clave posibles que podemos usar. Como queremos editar una confirmación, debemos cambiar pick 4155df1cdc7 Page Navigation View a edit 4155df1cdc7 Page Navigation View. Guarde los cambios y salga del editor.

Ahora su rama se reajusta al punto en el tiempo justo antes de la confirmación que realizó, que incluía _navigation.html.haml. Abra el archivo y realice los cambios deseados según los comentarios de revisión. Una vez que haya terminado con los cambios, organícelos ejecutando git add _navigation.html.haml.

Ya que hemos realizado los cambios, es hora de mover la rama HEAD de nuevo al confirmar que teníamos originalmente (aunque también incluimos los nuevos cambios que agregamos), ejecute git rebase --continue, esto abrirá su editor predeterminado en la terminal y le mostrará el mensaje de confirmación que editamos durante el rebase; Page Navigation View. Puede cambiar este mensaje si lo desea, pero lo dejaríamos como está por ahora, así que guarde y salga del editor. En este punto, Git reproducirá todas las confirmaciones que siguió después de la confirmación que acaba de editar y ahora la rama HEAD ha vuelto a la confirmación superior que teníamos originalmente, y también incluye los nuevos cambios que realizó en una de las confirmaciones.

Dado que de nuevo modificamos una confirmación que ya está presente en el repositorio remoto, necesitamos forzar el empuje de esta rama nuevamente usando git push --force-with-lease <remote_name> <branch_name>.

Situación 3 : Necesito agregar, eliminar o combinar confirmaciones

Una situación común es cuando ha realizado varias confirmaciones solo para arreglar algo previamente comprometido. Ahora reduzcámoslas tanto como podamos, combinándolas con las confirmaciones originales.

Todo lo que necesitas hacer es iniciar la rebase interactiva como lo harías en los otros escenarios.

Ahora imagina que quieres combinar todas esas correcciones en c22a3fa0c5c Render navigation partial. Solo necesitas:

  1. Mueva las correcciones hacia arriba para que estén justo debajo de la confirmación que desea mantener al final.
  2. Cambie pick a squash o fixup para cada una de las correcciones.

Nota: squash mantiene los mensajes de confirmación en la descripción. fixup olvidará los mensajes de confirmación de las correcciones y conservará el original.

Terminará con algo como esto:

Guarde los cambios, salga del editor , ¡y tu estas listo! Este es el historial resultante:

Como antes, todo lo que necesita hacer ahora es git push --force-with-lease <remote_name> <branch_name> y los cambios están activos.

Si desea eliminar la confirmación de la rama por completo, en lugar de squash o fixup, simplemente escriba drop o simplemente elimine esa línea.

Evite conflictos

Para evitar conflictos, asegúrese de que se compromete «estar subiendo en la línea de tiempo» no está tocando los mismos archivos tocados por las confirmaciones que quedan después de ellos.

Pro-tip : Correcciones rápidas

Si sabe exactamente qué compromiso desea corregir, cuando se comprometa no tiene que desperdiciar ciclos cerebrales pensando en buenos nombres temporales para «Arreglar 1», «Arreglar 2»,…, «Arregle 42».

Paso 1: Conozca --fixup

Después de «haber realizado los cambios arreglando lo que sea que necesite arreglo, solo Git confirma todos los cambios de esta manera:

(Tenga en cuenta que este es el hash para la confirmación c22a3fa0c5c Render navigation partial)

Esto generará este mensaje de confirmación: fixup! Render navigation partial.

Paso 2: Y el compañero --autosquash

Fácil rebase interactivo. Puede hacer que git coloque los fixup s automáticamente en el lugar correcto.

git rebase -i 4155df1cdc7 --autosquash

El historial se mostrará así:

Listo para que solo revisa y continúa.

Si te sientes aventurero, puedes hacer un cambio de base no interactivo git rebase --autosquash, pero solo si te gusta vivir peligrosamente, ya que no tengo la oportunidad de revisar los squashes que se están haciendo antes de que se apliquen.

Situación 4: Mi historial de confirmaciones de Git no tiene sentido, necesito un nuevo comienzo.

Si queremos «Al trabajar en una función grande, es común tener varios cambios de corrección y revisión de comentarios que se realizan con frecuencia. En lugar de cambiar la base de la rama constantemente, podemos dejar la limpieza de las confirmaciones hasta el final del desarrollo.

Aquí es donde la creación de archivos de parche es extremadamente útil. De hecho, los archivos de parche eran la forma principal de compartir código por correo electrónico mientras se colaboraba en grandes proyectos de código abierto antes de que los servicios basados en Git como GitLab estuvieran disponibles para los desarrolladores. Imagina que tienes una de esas ramas (por ejemplo, add-page-navigation) donde hay toneladas de confirmaciones que no transmiten claramente los cambios subyacentes. A continuación, te mostramos cómo puedes crear un archivo de parche para todos. los cambios que hizo en esta rama:

  • El primer paso para crear el archivo de parche es asegurarse de que su rama tenga todos los cambios presentes desde master rama y no tiene conflictos con la misma.
  • Puede ejecutar git rebase master o git merge master mientras «vuelve a marcar en la rama add-page-navigation para obtener todos los cambios de master en su rama.
  • Ahora cree el archivo de parche ; ejecute git diff master add-page-navigation > ~/add_page_navigation.patch.
    • Desglose de comandos: aquí «estamos usando la función de diferenciación de Git» y solicitando una diferencia entre master rama y add-page-navigation rama, y redireccionando la salida (a través del símbolo >) a un archivo llamado add_page_navigation.patch en nuestro nosotros er directorio de inicio (normalmente ~/ en los sistemas operativos * nix).
  • Puede especificar cualquier ruta que desee para mantener este archivo in y el nombre del archivo y la extensión pueden ser los que desee.
  • Una vez que se ejecuta el comando y no ve ningún error, se genera el archivo de parche.
  • Ahora realice el pago master rama; ejecute git checkout master.
  • Elimine la rama add-page-navigation del repositorio local; ejecutar git branch -D add-page-navigation. Recuerde, ya tenemos cambios de esta rama en un archivo de parche creado.
  • Ahora cree una nueva rama con el mismo nombre (mientras master está desprotegido); ejecute git checkout -b add-page-navigation.
  • En este punto, esta es una rama nueva y no tiene ninguno de sus cambios.
  • Finalmente, aplique sus cambios del archivo de parche; git apply ~/add_page_navigation.patch.
  • Aquí, todos sus cambios se aplican en una rama y aparecerán como no confirmados, como si todas sus modificaciones donde se hizo, pero ninguna de las modificaciones se comprometió realmente en la rama.
  • Ahora puede continuar y enviar archivos individuales o archivos agrupados por área de impacto en el orden que desee con mensajes de confirmación concisos.

Al igual que en situaciones anteriores, básicamente modificamos toda la rama, ¡así que es hora de forzar el empuje!

Conclusión

Si bien hemos cubierto las situaciones más comunes y básicas que surgen en un flujo de trabajo diario con Git, reescribir el historial de Git es un tema vasto y a medida que se familiariza con consejos anteriores, puede aprender conceptos más avanzados sobre el tema en la Documentación oficial de Git. ¡Feliz git «ing!

Foto de pan xiaozhen en Unsplash

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *