Esta publicación explora los principios de desplazamiento a la izquierda y sugiere que los PR apilados serán cada vez más útiles.
El proceso de revisión de código entre pares es una parte esencial del desarrollo de software. Ayuda a mantener la calidad del software y promueve el cumplimiento de los estándares, los requisitos del proyecto, las guías de estilo y facilita el aprendizaje y la transferencia de conocimientos.
Si bien la efectividad es alta para revisar cambios de código suficientemente pequeños, cae exponencialmente con el aumento en el tamaño del cambio. Para mantener el nivel necesario de enfoque mental para que sea efectivo, las revisiones de código grandes son agotadoras.
Por lo general, cuanto más dura la revisión, menos efectiva se vuelve la revisión general:
Entonces, ¿por qué no podemos simplemente restringir el tamaño de las solicitudes de extracción (PR)? Si bien muchos cambios pueden comenzar pequeños, de repente un pequeño cambio de dos líneas puede convertirse en un refactor de 500 líneas que incluye múltiples conversaciones de ida y vuelta con los revisores.
Algunos equipos de ingeniería también mantienen ramas de funciones de ejecución prolongada mientras continúan trabajando, lo que dificulta la revisión.
Entonces, ¿cómo logramos el equilibrio correcto? Simple. Utilice relaciones públicas apiladas.
Las solicitudes de extracción apiladas realizan cambios iterativos más pequeños y se apilan una encima de la otra en lugar de agrupar grandes cambios monolíticos en una sola solicitud de extracción. Cada RP de la pila se centra en un solo cambio lógico, lo que hace que el proceso de revisión sea más manejable y requiera menos tiempo.
También escribimos una publicación el año pasado explicando cómo esta ayuda representa los cambios de código como una narrativa en lugar de desglosar las cosas por archivos o funciones.
Además de crear una cultura de revisiones de código más efectivas, existen algunos otros beneficios de las relaciones públicas apiladas:
Imagine que está implementando una característica grande. En lugar de crear la función completa y luego solicitar una revisión del código, considere crear el marco inicial y presentarlo rápidamente para recibir comentarios.
Esto podría ahorrarle incontables horas al obtener comentarios tempranos sobre su diseño.
Los PR apilados respaldan la práctica de cambio a la izquierda porque los cambios se integran y prueban continuamente, lo que permite la detección temprana y la rectificación de problemas.
¡Los cambios se fusionan en partes y piezas detectando cualquier problema temprano en lugar de fusionar un cambio gigante con la esperanza de que no derribe la producción!
Las revisiones de código también son maravillosas para la posteridad. Sus cambios de código están narrando su proceso de pensamiento detrás de la implementación de una característica, por lo tanto, el desglose de los cambios crea una transferencia de conocimiento más efectiva.
Es más fácil para los miembros del equipo comprender los cambios, lo que promueve un mejor intercambio de conocimientos para el futuro.
Esperar a que se revise y apruebe el código puede ser un proceso frustrante. Con las relaciones públicas apiladas, los desarrolladores pueden trabajar en varias partes de una función sin esperar a que los revisores aprueben las relaciones públicas anteriores.
Entonces, ¿por qué más desarrolladores no usan relaciones públicas apiladas para las revisiones de código?
Aunque este flujo de trabajo de relaciones públicas apilado aborda las prácticas deseadas de mantener las revisiones de código manejables y los desarrolladores productivos, desafortunadamente, Git o GitHub no lo admiten muy bien de forma nativa.
Como resultado, se han desarrollado varias herramientas en la comunidad de código abierto para permitir que los ingenieros incorporen esta técnica de apilamiento en las plataformas Git y GitHub existentes. Pero acumular relaciones públicas es solo una parte de la historia.
A medida que recibimos comentarios sobre la revisión del código y hacemos cambios en la parte de la pila, ahora tenemos que reorganizar y resolver conflictos en todas las ramas posteriores.
Tomemos un ejemplo. Imagine que está trabajando en un cambio que requiere realizar un cambio de esquema, un cambio de backend y un cambio de frontend.
Con eso, ahora puede enviar un cambio de esquema simple para su revisión primero, y mientras se revisa, puede comenzar a trabajar en el backend y el frontend. Usando PR apilados, estos 3 cambios pueden ser revisados por 3 revisiones diferentes.
En este caso, puede tener una pila que se vea así donde demo/schema
, demo/backend
y demo/frontend
representan las 3 ramas apiladas una encima de la otra.
Hasta ahora, esto tiene sentido, pero ¿qué pasa si tienes algunos comentarios de revisión de código sobre el cambio de esquema que requiere crear una nueva confirmación? De repente, su historial de confirmación se ve así:
Ahora, debe volver a establecer manualmente todas las ramas posteriores y resolver los conflictos en cada etapa. Imagínese si tiene 10 ramas apiladas en las que puede tener que resolver los conflictos 10 veces.
Pero eso no es todo, fusionar un PR en la pila puede ser una verdadera pesadilla. Tiene 3 opciones: squash
, merge
y rebase
para fusionar un PR. Tratemos de entender qué hay detrás de escena en cada uno.
squash
, Git toma los cambios de todas las confirmaciones existentes del PR y las vuelve a escribir en una única confirmación. En este caso, no se mantiene ningún historial sobre el origen de esos cambios.
Una confirmación merge
es un tipo especial de confirmación de Git que se representa mediante una combinación de dos o más confirmaciones. Por lo tanto, funciona de manera muy similar a una confirmación squash
, pero también captura información sobre sus padres. En un escenario típico, una confirmación de combinación tiene dos padres: la última confirmación en la rama base (donde se fusiona el PR) y la confirmación superior en la rama de características que se fusionó.
Aunque este enfoque brinda más contexto al historial de confirmaciones, sin darse cuenta crea un historial de git no lineal que puede ser indeseable.
rebase
y fusión, Git reescribirá las confirmaciones en la rama base. Entonces, de manera similar a la opción de confirmación squash
, perderá cualquier historial asociado con las confirmaciones originales.
Por lo general, si está utilizando la estrategia de confirmación merge
mientras acumula PR, su vida será un poco más simple, pero la mayoría de los equipos desaconsejan el uso de esa estrategia para mantener limpio el historial de git. Eso significa que es probable que esté utilizando una combinación squash
o rebase
.
Y eso crea un conflicto de fusión para todas las ramas apiladas no fusionadas posteriores.
En el ejemplo anterior, digamos que fusionamos la primera rama demo/schema
en la línea principal. Creará una nueva confirmación D1
que contiene los cambios de A1
y A2
.
Dado que Git no sabe de dónde vino D1
, y demo/backend
todavía se basa en A2
, intentar reorganizar demo/backend
en la parte superior de la línea principal creará conflictos de fusión.
Del mismo modo, cambiar demo/frontend
después de cambiar demo/backend
también causará los mismos problemas. Entonces, si tuviera diez ramas apiladas y fusionara una de ellas, tendría que resolver estos conflictos nueve veces.
Todavía estamos rascando la superficie; hay muchos otros casos de uso , como reordenar confirmaciones, dividir, plegar y renombrar ramas, que pueden generar una gran sobrecarga para administrar cuando se trata de relaciones públicas apiladas.
Es por eso que creamos una gestión de relaciones públicas apiladas como parte de Aviator.
Piense en Aviator como una capa de aumento que se asienta sobre su herramienta existente. Aviator se conecta con GitHub, Slack, Chrome y Git CLI para brindar una experiencia de desarrollador mejorada.
Aviator CLI funciona a la perfección con todo lo demás. La CLI no es solo una capa sobre Git, sino que también comprende el contexto de las pilas en GitHub. Consideremos un ejemplo.
Crear una pila es bastante sencillo. Excepto en este caso, usamos av
CLI para crear las ramas para garantizar que se realice un seguimiento de la pila. Por ejemplo, para crear su rama de esquema y el PR correspondiente, siga los pasos a continuación.
av stack branch demo/schema # make schema changes git commit -a -m "[demo] schema changes" av pr create
Dado que Aviator también está conectado a su GitHub, le facilita visualizar la pila.
O si desea visualizarlo desde la terminal, aún puede hacerlo con los comandos CLI:
Usar la pila ahora se vuelve pan comido. Puede agregar nuevas confirmaciones a cualquier rama y simplemente ejecutar av stack sync
desde cualquier lugar de la pila para sincronizar todas las ramas. Aviator reorganiza automáticamente todas las ramas por usted, y si hay un conflicto de fusión real, solo tiene que resolverlo una vez.
Aquí es donde las herramientas Aviator se destacan fácilmente de cualquier herramienta existente. En Aviator, hemos creado uno de los MergeQueue más avanzados para gestionar la fusión automática de miles de cambios a escala.
Aviator admite una integración perfecta con la CLI y los PR apilados. Entonces, para fusionar una pila parcial o completa de PR, puede asignarlos a Aviator MergeQueue usando CLI av pr queue
o publicando un comentario en GitHub: /aviator stack merge
.
Aviator maneja automáticamente la validación, actualización y fusión automática de todas las pilas en cola en orden.
Ahora, cuando los PR se fusionen, esta vez puede ejecutar av stack sync --trunk
para actualizar todos los PR y limpiar todos los PR combinados.
Las relaciones públicas apiladas inicialmente pueden parecer más trabajo debido a la necesidad de dividir los cambios en partes más pequeñas. Sin embargo, el aumento en la eficiencia de la revisión de código, los bucles de retroalimentación más rápidos y las mejores oportunidades de aprendizaje seguramente compensarán esta sobrecarga.
A medida que sigamos adoptando los principios del cambio a la izquierda, los RP apilados serán cada vez más útiles.
Aviator CLI proporciona una excelente manera de administrar relaciones públicas apiladas con mucho menos tedio. La CLI es de código abierto y completamente gratuita. Nos encantaría que lo probara y compartiera sus comentarios en nuestro foro de discusión .
En Aviator, estamos creando herramientas de productividad para desarrolladores desde los primeros principios para capacitar a los desarrolladores para que construyan más rápido y mejor.