tipos - ¿Por qué git permite que las etiquetas remotas se muevan o por qué no se puede usar git-tag para prueba y configuración atómica?
¿qué hace git log-oneline? (1)
Tengo un problema donde dos procesos similares se ejecutan en paralelo dentro de clones separados del mismo repositorio (generalmente en diferentes computadoras). Cada vez que se ejecuta un proceso, obtiene las últimas etiquetas del control remoto y luego deduce un número único basado en las etiquetas que ve.
Por ejemplo, si estas etiquetas existen en el control remoto: 1.0 1.1 1.2 1.3, entonces un proceso elegirá 1.4 como el próximo número.
Antes de que comience el proceso, crea una nueva etiqueta y la vuelve a enviar al control remoto:
$ git tag 1.4 HEAD
$ git push origin tag 1.4
La idea era que esta es una forma de seleccionar números atómicamente. El otro proceso, si está mirando al mismo tiempo, también puede decidir usar 1.4, pero cuando se trata de impulsar su etiqueta, debería descubrir que 1.4 ya existe, y elegir 1.5 en su lugar (y volver a intentarlo).
Mi esperanza era poder tratar los ataques de git tag como atómicos.
Desafortunadamente, por alguna razón extraña, ¡git permite que las etiquetas remotas se muevan en ciertas circunstancias!
Por ejemplo, digamos que la etiqueta 1.4 se ha puesto en origen / maestro y se ha insertado. El otro proceso quiere poner la etiqueta 1.4 en, digamos, origen / maestro ^, lo que implicaría mover la etiqueta hacia atrás. Git rechazará esto con un error de ''no avance rápido'':
Proceso A:
$ git tag 1.4 origin/master
$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
* [new tag] 1.4 -> 1.4
Proceso B:
$ git tag 1.4 origin/master^
$ git push origin tag 1.4
To /repo1
! [rejected] 1.4 -> 1.4 (non-fast forward)
error: failed to push some refs to ''/repo1''
Ok, está bien, el Proceso B puede usar esto para probar 1.5 en su lugar.
Pero considera esta situación:
Proceso A:
$ git tag 1.4 origin/master
$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
* [new tag] 1.4 -> 1.4
Proceso B:
$ git tag 1.4 origin/master
$ git push origin tag 1.4
Everything up-to-date
Oh. Es una lástima, git no indicó que esta etiqueta ya existe en el control remoto. En realidad, sí, con -v:
$ git push origin tag 1.4 -v
Pushing to /repo1
To /repo1
= [up to date] 1.4 -> 1.4
Everything up-to-date
Ok, entonces puedo hacer una especie de redirección de stderr, buscar "=", y eso permitirá que el proceso B determine que el 1.4 ya está en uso.
Pero eso es un poco tonto. Y empeora:
Proceso A:
$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
* [new tag] 1.4 -> 1.4
Proceso B:
$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
fd0e09e..c6cdac9 1.4 -> 1.4
Argg! ¿Qué? ¡Git acaba de mover la etiqueta remota sin previo aviso!
Por lo tanto, me parece que las etiquetas remotas en git están fundamentalmente rotas: no deberían simplemente "moverse" sin una solicitud explícita. Más al punto, deberían negarse a moverse por defecto.
Además, el comando git-tag debería proporcionar una forma de probar y establecer atómicamente una etiqueta.
Pero claramente no es así. Ejecutar git fetch primero no va a ayudar porque todavía hay una ventana de conflicto e incluso si hay un conflicto, ¡en uno de los tres escenarios, la etiqueta simplemente se mueve!
¿Que esta pasando aqui?
¿Hay alguna otra forma de probar y configurar una etiqueta?
Si no, ¿cómo asignan y reservan las personas los números de compilación en un entorno de construcción automatizado? ¿Cómo se puede detectar con fiabilidad cuando dos procesos inadvertidamente recogieron el mismo número de compilación?
Usando git 1.6.1.2.
Creo que la estrategia de etiquetado se vería mejor si utilizaras objetos de etiquetas reales en lugar de etiquetas livianas que están más diseñadas como etiquetas locales.
Puede crear un objeto de etiqueta especificando una de las opciones -a
(o -m
/ -F
), -s
o -u
( git help tag
).
Pruebe su ejemplo pero agregue -m "1.4 tag"
a cada invocación de la git tag
. Los objetos de etiqueta no pueden dirigir descendientes de otros objetos de etiqueta, por lo que cada contenedor de inserción en el que desee fallar debe fallar.