Cómo las mejores prácticas de Git me ahorraron horas de reelaboración

Recientemente, estaba trabajando en la tarea de actualizar un certificado para una aplicación NodeJS. Esto se tocó por última vez hace dos años para una mejora de funciones. Cualquier problema en vivo que se plantee a esta aplicación requeriría atención inmediata, aunque la aplicación solo se ha utilizado internamente.

La aplicación es antigua. Los módulos Core-NodeJS-Infra no se han actualizado durante más de dos años. Los servicios posteriores están obsoletos. Se cambia la forma en que llamamos a los servicios descendentes. La fecha límite ajustada es una guinda del pastel. Sabía que iba a ser una montaña rusa.

Pasé tres días ejecutando la aplicación.

¿Se actualizan los inframódulos? Cheque.

¿Los servicios de downstream funcionan bien? Cheque.

¿Los flujos de UI funcionan bien? Cheque.

Uno de los miembros de nuestro equipo había tocado la aplicación para actualizarla hace más de un año. Señaló que el repositorio desde el que bifurqué era en sí mismo un repositorio bifurcado. Otro equipo había trabajado en ese repositorio, y luego nuestro equipo trabajó en el repositorio original a partir de ese momento, pero el miembro de mi equipo no sabe a partir de qué momento. ¡Así que fue un desastre!

Tenemos una herramienta de "Propiedad" que muestra el repositorio correcto y me "mintió". Entonces la situación era así:

¡Sí, fue Forkception! WTF y FML fueron los dos primeros pensamientos que salieron de mi boca. Yo debería haber trabajado en el repositorio en vivo, pero, en cambio , trabajé en un tenedor, que estaba duro. ¡Que estúpido de mi parte!

Primer pensamiento: mis tres días de trabajo se han desperdiciado y necesito empezar de nuevo.

¿Segundo pensamiento? Déjame preguntarle a mi viejo amigo Git. Me ha estado ayudando durante mucho tiempo.

Yo - “Hey Git? Estoy en un gran problema y necesito su ayuda para resolver este problema ".

Git - “¡Oye! Bien, primero tenemos que empezar desde lo que esté en vivo. Cree una nueva rama llamada actualización y apunte esa rama al código en vivo. Puedes usar un restablecimiento completo de git para eso ".

Yo - "Ok, lo haré".

En este punto, la situación se ve así.

Git : “Necesitamos saber qué cambió entre desarrollo y actualización. ¿Puede enumerar los archivos que difieren entre su actualización y desarrollo ? Verifique esos archivos individualmente y averigüe qué tipo de cambios hubo ".

Yo - “Genial. Veo tres tipos de cambios. Hay un servicio S1 al que necesito llamar de otra manera. Hay un servicio S2 al que necesito llamar usando un punto final diferente. Hay un servicio S3 que necesito llamar usando diferentes parámetros. También veo que el archivo package.json en la rama de actualización tiene algunos de los paquetes ya actualizados. Por lo tanto, solo es necesario cambiar algunos paquetes ".

Git - “Impresionante que hayas segregado los cambios. Ahora muéstrame el registro de Git de tu rama de desarrollo . Espero que hayas seguido algunas prácticas básicas de Git, por ejemplo, tener siempre código compilable en cada confirmación. El mensaje de confirmación debe representar lo que ha cambiado ".

Yo : “Sí, tengo un total de cuatro confirmaciones en la rama de desarrollo . Un compromiso fue hacer el proyecto edificable. Hay uno para cada una de las tres llamadas de servicio. "

Git - “¡Perfecto! Parece que ha seguido las mejores prácticas correctamente. Comencemos por estabilizar la compilación del proyecto haciendo que package.json esté actualizado. Ir a la rama de actualización y hacer un duplicado de package.json - package-copy.json. Ahora, usando Git replace, actualice / package.json con Develop / package.json y ejecute la diferencia entre package.json y package-copy.json. Dado que el código en vivo ya ha cambiado algunos de los paquetes y tiene diferentes versiones, necesitará actualizar mirando la diferencia ".

Yo - “Déjame intentar eso. Ok, se está construyendo y funcionando ".

Git - “¡Impresionante! Ahora, trabajemos en las llamadas de servicio. Veo que tiene una confirmación para cada cambio de llamada de servicio en la rama de desarrollo. Es hora de elegir. Elija desde la llamada de servicio menos complicada hasta la llamada de servicio más complicada. Elija, combine y resuelva conflictos. Asegúrese de verificar si el proyecto está en condiciones de construcción después de cada selección y antes de cada compromiso ".

Yo - “S1 hecho. S2 hecho. S3 hecho. Gracias, Git "

Git - “De nada. Pero es usted quien se ha ayudado a sí mismo siguiendo las prácticas de compromiso de Git y no tratando a Git como un mero almacenamiento de código ".

Que hice aqui ?

Confirmar cambios relacionados

Haga una pausa por un momento y piense si este cambio debería incluirse en este compromiso. Una confirmación que dice que "cambiar: puntos finales de servicio-s1" y tiene cambios de servicio-s2 simplemente crearía confusión.

No comprometa el trabajo a medias

A menudo hemos escuchado el mantra "comprométete temprano, comprométete a menudo". En el ejemplo anterior, puede tener una confirmación para diferentes puntos finales del mismo servicio. Esto se llama hacer salchichas .

Sin embargo, personalmente aplazo mis pequeñas confirmaciones usando el modo interactivo de git rebase . Esto me ayuda a tener un cambio lógico, que se puede certificar, y ayuda a un responsable de confianza a revisar su código también. Esto es mucho mejor para proyectos a gran escala.

Pruebe su código antes de comprometerse

Deberíamos pensar en Git como una máquina de estado, y cualquier máquina debería estar en condiciones de construcción en cualquier estado.

Escribe buenos mensajes de compromiso

Esta es la parte más crucial. Siempre hago una pausa por un momento y pienso si podré entender, después de tres meses, el tipo de cambio en este compromiso con solo mirar el mensaje de compromiso.

Conclusión

Pude resolver rápidamente el lío. Pude salir de ese momento WTF y FML solo porque seguí algunas buenas prácticas. Existen por una razón y son como la sal en los alimentos: solo te das cuenta de su valor cuando no se usan.

Los errores sucederán tarde o temprano, inconscientemente. Pero asegúrese de seguir conscientemente algunas prácticas relacionadas con Git.

Soy fanático de los mensajes de confirmación semántica de Git, que ayudan a navegar por el historial de Git. Porque, seamos honestos, no puede esperar que todos usen las mismas palabras para cada mensaje de confirmación. Sin embargo, se puede esperar el tipo de mensaje .

Esto ayuda a garantizar que, después de cada confirmación, se pueda construir su proyecto, lo cual es realmente útil.

VSCode tiene un soporte enfermizo para Git. Es muy fácil ver los conflictos y resolverlos, a veces con un solo clic. ¿Vea el siguiente ejemplo?

Referencias

  • Mejores prácticas de Git
  • Integración de control de versiones súper impresionante en VSCode
  • Mensajes de confirmación semántica de Git
  • ¿Sugerencia de Git?: Cómo "fusionar" archivos específicos de otra rama
  • ¿Sugerencia de Git?: Git - Documentación de git-cherry-pick
  • ¿Sugerencia de Git?: Git - Documentación de git-reset

Un agradecimiento especial a mis amigos Saurabh Rajani y Anish Dhargalkar, que me ayudaron a mejorar el contenido.