Encontrar la twig donde aparece originalmente una confirmación (git / Jenkins / CD)

Estoy diseñando un sistema de compilation de Jenkins que se activa cuando cualquier label se envía a un repository. A partir de ahí, queremos saber a qué twig se presionó la confirmación a la que hace reference la label. A partir de ahí, inicio otras comstackciones de Jenkins basadas en ese nombre de twig. Todo en esta canalización es sencillo excepto para descubrir qué twig fue labelda.

Básicamente, mi equipo creó y actualmente utiliza twigs de production y staging : cuando un desarrollador fusiona cosas en production o staging en staging , y desea lanzarlas, labelrán con un número de versión y lo expulsarán. Jenkins puede actualizar los serveres de producción con esa label en la twig de producción, así como organizarlas con tags en la twig de etapas. Si el master está labeldo, entonces iniciaré una compilation y testing de CI.

He estado probando el método en esta publicación de blog aquí: http://johndstein-blog.logdown.com/posts/428667, que ofrece lo siguiente:

 export HASH=$(git rev-parse HEAD) export BRANCH=$(basename $(git branch -r --contains ${HASH})) export TAG=$(basename $(git describe --all --exact-match ${HASH})) echo "HASH: $HASH" echo "BRANCH: $BRANCH" echo "TAG: $TAG" 

pero esto no funciona el 100% del time – para algunos repos, cuando se ejecuta la línea 2 (twig de agarre) – obtengo múltiples twigs, y se produce un error. Soy bastante nuevo en git, pero por lo que puedo decir, esto se debe a que la confirmación se realizó en una twig y se fusionó con otra.

Mi pregunta es, ¿puedo encontrar de manera confiable el nombre de la twig a la que se envió originalmente la confirmación si tengo una label? Además, ¿es esta una forma inteligente de hacer esto?

Esto no es posible en general. "Originalmente fue empujado a" no está ni bien definido sin elegir algo "original" y hacer que mantenga los loggings.

Aquí hay un ejemplo. Supongamos que creo twigs sneak y gotcha :

  C <-- sneak / A--B <-- master \ D <-- gotcha 

Ahora bien, si git push una o ambas de estas twigs, el repository Git receptor obtiene las dos confirmaciones C y D junto con una request para actualizar los nombres refs/heads/sneak y refs/heads/gotcha . Hasta ahora, todo parece bueno. Pero ahora hago esto en lugar de presionar, o muy rápido después de empujar, lo suficientemente rápido como para no poder ver lo que estoy haciendo:

 $ git push origin sneak:sneak gotcha:gotcha && > git checkout master && > git merge sneak gotcha && > git push origin master:master :sneak :gotcha 

La git merge hace una fusión de pulpo (que, por supuesto, he arreglado para tener éxito, de lo contrario, esto me lleva demasiado time engañarlo :-)). El paso de push envía la confirmación E al server, junto con una request para actualizar refs/heads/master para apuntar a ella, y para eliminar refs/heads/sneak y refs/heads/gotcha . El resultado es:

  C / \ A--B---E <-- master \ / D 

¿Qué twigs se comprometieron y / o presionaron C y D ? Bueno, tuvimos esa información en el server durante unos seis milisegundos, antes de sobrescribirla y eliminarla.

Peor aún, tal vez el lugar donde presiono es un espejo retrovisor, y el server real está más atrás. El espejo de empuje puede haber tenido la información durante dos o tres segundos, mucho time para tomarlo … pero el vínculo entre el espejo de inserción y el server real (punto final) está actuando, y durante esos tres segundos lo sobreescribí, de modo que el espejo push termina enviando confirmaciones C , D y E al server real, con una única request, para actualizar refs/heads/master para que apunte a E

Ahora, si definimos "originalmente pulsado a" como "enviado al espejo de inserción", y hacemos que el espejo de inserción mantenga un logging, el logging mostrará que originalmente pedí que el compromiso C ingrese sneak y confirme que D vaya a gotcha . Asumiendo el problema de enlace entre el espejo de inserción y el server central final, ese logging es el único lugar con esta información. Puede organizar un canal lateral para recuperar esto, pero nada de eso está integrado en Git (incluso el logging es problemático: puede intentar usar los loggings de Git, pero puede que no sean lo suficientemente precisos, si le preocupan los múltiples impulsos por segundo y verdaderamente estricto orderamiento).

Los Reflogs no están habilitados por defecto para los repositorys simples (y los réplicas push), pero puede habilitarlos con una git config simple de git config .

Todo lo dicho …

Lo principal de lo que preocuparse es el hecho de que commits puede estar en cero, una o muchas twigs. 1 El truco es no depender de los nombres de las twigs a less que usted sea el que controle esos nombres. Tiene breves momentos de control sobre los nombres de las sucursales en pre-receive anzuelos pre-receive y post-receive , pero es difícil de usar.

Su mejor opción es no confiar en absoluto en los nombres, sino más bien requerir algún indicador separado, como una cadena incrustada en el post de confirmación (y puede tener un gancho de pre-recepción que verifique esto). O bien, simplemente puede solicitar que los nombres de sus tags tengan un formatting bien definido:

 production-v1.0.1 staging-v3.7 

o lo que sea. El nombre de la label le dice cuál es la intención de esa confirmación específica, y es bastante independiente de las twigs que la contienen.


1 Los commits que no están en ninguna twig son algo inusuales, pero fáciles de crear: simplemente marque un commit de tip-of-branch, luego borre el nombre de la twig. Puede presionar la label y la confirmación se envía al server receptor con una label, pero no a una twig.