Cómo duplicar tags locales a control remoto

Hay cientos de preguntas sobre tags de Git en SO, pero no pude encontrar esta.

¿Cómo puedo reflejar mis tags git locales en remoto?

Es decir:

  1. No importa cuál sea el estado original de origin
  2. Me gustaría tener una function bash que refleje todas las tags locales en el control remoto.
  3. Esto incluye la synchronization si una label fue creada, eliminada o movida localmente.

Lo contrario de este script se encuentra en todas partes, pero para esta dirección no pude encontrar nada.

 git tag -l | xargs git tag -d git fetch --tags 

La Parte 1 es relativamente fácil, la Parte 2 es less fácil y la Parte 3 es imposible en general, porque simplemente no hay suficiente información registrada.

Aquí hay un ejemplo. Verifica el repository L (que tienes localmente), y encuentras que la label T1 existe, T2 no, y T3 existe.

Ahora revisa el repository O , el del origen de L , y encuentra que todas las tags T1, T2 y T3 existen.

¿Qué sucedió realmente: "la label T2 existió en L y se eliminó explícitamente" o "la label T2 nunca existió en L , pero se agregó de alguna manera a O "?

Dado que Git no guarda este tipo de datos, no hay forma de saber si T2 fue eliminado explícitamente, o simplemente no se recogió.

Si su requisito es más simple: si no le importa si T2 se agregó a O , solo necesita hacer O las tags de L, independientemente de por qué L tiene esas tags y no otras, entonces todo lo que necesita hacer es lo mismo que hace el script de dos líneas, pero en la otra dirección: primero, elimine todas las tags (pero en O , no en L ), y luego, segundo, empuje todas las tags de O a L , con git push --tags o equivalentes.

Es más fácil eliminar las tags de O en la máquina que aloja O , pero suponiendo que no le preocupen los problemas de atomicidad, puede hacerlo desde L :

 git ls-remote origin 'refs/tags/*' 

(que obtendrá todas las tags que están en origin ), entonces:

 git push --delete origin refs/tags/T1 refs/tags/T2 ... 

(repita para todas las tags), luego:

 git push --tags origin 

Tenga en count que git ls-remote muestra los nombres de los objects de label y sus últimos objects de destino:

 7446b8fa5ead8ce0990e8f2be3a2490eac8e199f refs/tags/v2.9.0 05219a1276341e72d8082d76b7f5ed394b7437a4 refs/tags/v2.9.0^{} 7590ed7abf57429b36761c00377a3648630029bd refs/tags/v2.9.0-rc0 3a0f269e7c82aa3a87323cb7ae04ac5f129f036b refs/tags/v2.9.0-rc0^{} c93578b0c65ac46bb6bba0750542798518f09335 refs/tags/v2.9.0-rc1 60bd4b1c513bb652cdffad44382046ca872140eb refs/tags/v2.9.0-rc1^{} 

así que esto requiere un poco de filtrado; y si puede presionar forzar para sobrescribir las tags, puede hacerlo más eficiente presionando +refs/tags/*:refs/tags/* como refspec principal, y algunas :refs/tags/xyz refspecs auxiliares para borre cualquier label "extraña" (como T2 en mi ejemplo anterior). Eso requiere un script un poco más inteligente. Una forma tonta y simple es imprimir solo tags no sujetas, por ejemplo:

 git ls-remote origin 'refs/tags/*' | awk '/\^{}$/ { next } { print $2 }' 

que luego puede canalizar a xargs git push --delete origin .