¿Cómo se cambia el nombre de una etiqueta Git?

1219

Hoy estaba buscando un proyecto a través de los registros y me di cuenta de que hacía mucho que buscaba un nombre de etiqueta. ¿Hay alguna forma de cambiar el nombre de la etiqueta? Google no ha encontrado nada útil.

Me di cuenta de que podía ver la versión etiquetada y hacer una nueva etiqueta, incluso lo intenté. Pero eso parece crear un objeto de etiqueta que no es del todo correcto. Para uno,

git tag -l

lo enumera fuera de servicio en relación con todas las otras etiquetas. No tengo idea de si eso es significativo, pero me lleva a creer que el nuevo objeto de etiqueta no es exactamente lo que quiero. Puedo vivir con eso, porque realmente solo me importa que el nombre de la etiqueta coincida con la documentación, pero prefiero hacerlo "bien", suponiendo que haya una manera correcta de hacerlo.

Brandon Fosdick
fuente
¿Usó la misma invocación, es decir, si la etiqueta anterior fue anotada / firmada, la nueva etiqueta también es de este tipo o es ligera?
Jakub Narębski
1
Tanto la etiqueta antigua incorrecta como la nueva etiqueta deseada deben estar anotadas y sin firmar. La etiqueta anterior se creó con 'git tag -a bad_tag_name', por lo que me gustaría hacer algo similar a 'git tag -a good_tag_name'.
Brandon Fosdick
Debo señalar que también quiero que este proceso de cambio de nombre de etiqueta mágica conserve la anotación de la etiqueta que se renombra. En realidad, me gustaría cambiar solo el nombre y nada más.
Brandon Fosdick
77
git log --oneline --decorate --graphes útil al limpiar etiquetas.
Joel Purra
Puede cambiar el nombre de una etiqueta en una línea: vea mi respuesta a continuación
VonC

Respuestas:

2040

Así es como cambio el nombre de una etiqueta olda new:

git tag new old
git tag -d old
git push origin :refs/tags/old
git push --tags

Los dos puntos en el comando push eliminan la etiqueta del repositorio remoto. Si no hace esto, Git creará la etiqueta anterior en su máquina cuando tire.

Finalmente, asegúrese de que los otros usuarios eliminen la etiqueta eliminada. Dígales a ellos (compañeros de trabajo) que ejecuten el siguiente comando:

git pull --prune --tags

Tenga en cuenta que si está cambiando una etiqueta anotada , debe asegurarse de que el nuevo nombre de la etiqueta haga referencia a la confirmación subyacente y no al antiguo objeto de la etiqueta anotada que está a punto de eliminar. Por lo tanto, use en git tag -a new old^{}lugar de git tag new old(esto se debe a que las etiquetas anotadas son objetos mientras que las etiquetas livianas no lo son, más información en esta respuesta ).

Casey Watson
fuente
19
si la etiqueta está anotada, la nueva etiqueta no tendrá el mensaje de la anterior, pero es una información útil
NickSoft
25
@NickSoft, acabo de hacer lo anterior con etiquetas anotadas. Los mensajes fueron copiados de viejos a nuevos bien. ¿Tal vez tengo una versión más nueva de git?
katyhuff
25
git push origin :refs/tags/oldse puede simplificar a git push origin :oldmi parecer.
Jesse Glick
25
Sugeriría cambiar "git push --tags" para que sea más explícito a esta etiqueta "git push origin refs / tags / new". No desea empujar inadvertidamente otras etiquetas.
2014
11
Advertencia : el uso git tag new oldcreará una etiqueta que apunte a la etiqueta anterior, no a la confirmación de la etiqueta anterior. (Consulte ¿Por qué no puedo retirar mi etiqueta de Git GUI? )
Stevoisiak
297

La pregunta original era cómo cambiar el nombre de una etiqueta, que es fácil: primero crear nuevas como un alias de VIEJO: git tag NEW OLDa continuación, eliminar VIEJO: git tag -d OLD.

La cita sobre "la forma Git" y la (in) cordura está fuera de lugar, porque se trata de preservar un nombre de etiqueta, pero hacer que se refiera a un estado de repositorio diferente.

Greg McGary
fuente
3
La respuesta anterior es ligeramente preferible ya que incluye el git push originnegocio.
Roly
la manera más fácil, funciona muy bien para cambiar el nombre de una etiqueta de lanzamiento anterior creada con Gitflow
RousseauAlexandre
55
Advertencia : el uso git tag new oldcreará una etiqueta que apunte a la etiqueta anterior, no a la confirmación de la etiqueta anterior. (Consulte ¿Por qué no puedo retirar mi etiqueta de Git GUI? )
Stevoisiak
118

Además de las otras respuestas:

Lo primero que necesita para construir un alias del antiguo nombre de la etiqueta, que apunta a la original cometer:

git tag new old^{}

Luego debe eliminar el antiguo localmente :

git tag -d old

Luego, elimine la etiqueta en su (s) ubicación (es) remota (s):

# Check your remote sources:
git remote -v
# The argument (3rd) is your remote location,
# the one you can see with `git remote`. In this example: `origin`
git push origin :refs/tags/old

Finalmente, debe agregar su nueva etiqueta a la ubicación remota. Hasta que haya hecho esto, no se agregarán las nuevas etiquetas :

git push origin --tags

Itere esto para cada ubicación remota.

¡Tenga en cuenta las implicaciones que un cambio de etiqueta Git tiene para los consumidores de un paquete!

emperador
fuente
Advertencia : el uso git tag new oldcreará una etiqueta que apunte a la etiqueta anterior, no a la confirmación de la etiqueta anterior. (Consulte ¿Por qué no puedo retirar mi etiqueta de Git GUI? )
Stevoisiak
1
@StevenVascellaro Gracias por el enlace. Para la próxima vez, presente una edición ; responder también es un esfuerzo de la comunidad. Gracias.
kaiser
No hice una edición porque todavía no he probado el código por mí mismo. (Tenga en cuenta la fecha de envío de la pregunta vinculada)
Stevoisiak
Una vez que lo hacemos git tag new old^{}, entonces no necesitamos git tag new_tag_name old_tag_name(el primer paso).
Número 945
28

Si se publica, no puede eliminarlo (sin arriesgarse a ser asfaltado y con plumas). La 'forma Git' es hacer:

Lo cuerdo. Solo admite que te equivocaste y usa un nombre diferente. Otros ya han visto un nombre de etiqueta, y si mantiene el mismo nombre, es posible que dos personas tengan "versión X", pero en realidad tienen "X" diferentes. Así que simplemente llámalo "X.1" y termina de una vez.

Alternativamente,

Lo loco. Realmente quieres llamar a la nueva versión "X" también, aunque otros ya hayan visto la anterior. Así que solo usa git-tag -f nuevamente, como si aún no hubieras publicado el anterior.

Es una locura porque:

Git no (y no debería) cambiar las etiquetas detrás de los usuarios. Entonces, si alguien ya tiene la etiqueta anterior, hacer un git-pull en su árbol no debería hacer que sobrescriba la anterior.

Si alguien recibió una etiqueta de lanzamiento de usted, no puede simplemente cambiar la etiqueta para ellos actualizando la suya. Este es un gran problema de seguridad, ya que las personas DEBEN poder confiar en sus nombres de etiquetas. Si realmente quieres hacer lo loco, solo tienes que confesar y decirle a la gente que te equivocaste.

Toda cortesía de las páginas del manual .

Robert Munteanu
fuente
66
O puede etiquetar (con el nombre correcto) esta etiqueta con un nombre incorrecto.
Jakub Narębski
66
Gracias, ya he leído esa página de manual un millón de veces. Afortunadamente, la etiqueta incorrecta no se ha publicado en ninguna parte. Incluso si lo fuera, este es un proyecto interno y soy el único desarrollador (por el momento). Creo que estoy bastante a salvo tanto de las peleas como de las plumas, pero solo si puedo conseguir que el repositorio coincida con los documentos.
Brandon Fosdick
A veces uso etiquetas para mis propias referencias personales. P.ej. podría ser una etiqueta 'ok_jb'. Lo uso porque algunas de las personas con las que trabajo no pueden compilar para mi plataforma, por lo que a veces habrá errores de compilación. Luego puedo obtener rápidamente una versión que se construye, al revisar esa etiqueta. Cuando se compilan las nuevas fuentes, solo muevo la etiqueta, o le cambio el nombre a compilaciones ##, donde ## es un número (según el proyecto). También puedo enfatizar cuándo se introdujo una característica especial, al agregar una etiqueta.
77
Mala respuesta. "No lo hagas" nunca es la respuesta correcta a "¿Cómo puedo hacerlo?". El usuario no preguntaba si crees que es una buena idea hacer eso o si a la gente le gustará eso. Si alguien pregunta "¿Cómo puedo cortarme la mano?", Dígale cómo se hace o déjelo solo, pero no necesitará que alguien le diga que cortar una mano puede no ser una gran idea. Y usted puede hacerlo. Puede agregar una nueva etiqueta y eliminar la anterior, es técnicamente posible, incluso en un repositorio remoto.
Mecki
55
Esto parece responder a la pregunta "¿Cómo hago que una etiqueta existente señale a una revisión diferente?" en lugar de la pregunta del OP, "¿Cómo cambio el nombre de una etiqueta?" Tampoco está claro cómo decirle a las personas que cometiste un error va a resolver el problema (aunque es una buena idea en general).
LarsH
25

Esta página wiki tiene esta interesante frase, que nos recuerda que podemos empujar varias referencias :

git push origin <refs/tags/old-tag>:<refs/tags/new-tag> :<refs/tags/old-tag> && git tag -d <old-tag>

y pedirle a otros cloners que hagan git pull --prune --tags

Entonces la idea es impulsar:

  • <new-tag>por cada commit que hace referencia <old-tag>: <refs/tags/old-tag>:<refs/tags/new-tag>,
  • la eliminación de<old-tag> ::<refs/tags/old-tag>

Vea como ejemplo "¿ Cambiar la convención de nomenclatura de etiquetas dentro de un repositorio git? ".

VonC
fuente
¿Esto preserva las anotaciones?
Brandon Fosdick
1
¡Tenga en cuenta que esto deja el nombre de la etiqueta original en la anotación para las etiquetas anotadas! Sin embargo, no estoy seguro de si eso implica algo, al menos en las versiones actuales.
gbr
@gbr ¿Puede editar la respuesta con un ejemplo que muestre que el "nombre de etiqueta original" quedó en la anotación?
VonC
1
@VonC No estoy seguro de entender lo que estás preguntando; tal vez no estaba claro: los objetos de anotación contienen un campo de etiqueta configurado con el nombre de la etiqueta, puede verlo con git cat-file -p <tag>; con su método en mi sistema obtengo la etiqueta 'renombrada' ref ( <new-tag>), pero su campo de etiqueta todavía está <old-tag>.
gbr
3
@gbr ¿No es lo que quería el OP? Mencionó "Debo señalar que también quiero que este proceso de cambio de nombre de la etiqueta mágica conserve la anotación de la etiqueta que se renombra. En realidad, me gustaría cambiar solo el nombre y nada más" ( stackoverflow.com/questions/1028649/ how-do-you-rename-a-git-tag / ... )
VonC
25

Como complemento de las otras respuestas, agregué un alias para hacerlo todo en un solo paso, con una sensación de comando de movimiento * nix más familiar. El argumento 1 es el nombre de la etiqueta anterior, el argumento 2 es el nombre de la etiqueta nueva.

[alias]
    renameTag = "!sh -c 'set -e;git tag $2 $1; git tag -d $1;git push origin :refs/tags/$1;git push --tags' -"

Uso:

git renametag old new
Jared Knipp
fuente
Esto no funcionó para mí, ya que falló en !sh(pregunta fue respecto de Windows Git), sin embargo, después de actualizar el formato de la siguiente, funcionó: renametag = "!f() { git tag $2 $1; git tag -d $1; git push origin :refs/tags/$1; git push --tags; }; f".
Sunny Patel
10

Siga el enfoque de 3 pasos para una o varias etiquetas.

Paso 1: Identifique el ID de compromiso / objeto del compromiso al que apunta la etiqueta actual

     command: git rev-parse <tag name>
     example: git rev-parse v0.1.0-Demo
     example output: db57b63b77a6bae3e725cbb9025d65fa1eabcde

Paso 2: elimine la etiqueta del repositorio

     command: git tag -d <tag name>
     example: git tag -d v0.1.0-Demo
     example output: Deleted tag 'v0.1.0-Demo' (was abcde)

Paso 3: cree una nueva etiqueta que apunte a la misma identificación de confirmación a la que apuntaba la etiqueta anterior

     command: git tag -a <tag name>  -m "appropriate message" <commit id>
     example: git tag -a v0.1.0-full  -m "renamed from v0.1.0-Demo" db57b63b77a6bae3e725cbb9025d65fa1eabcde
     example output: Nothing or basically <No error>

Una vez que el git local está listo con el cambio de nombre de la etiqueta, estos cambios se pueden volver al origen para que otros los tomen.

vikas pachisia
fuente
Faltan pasos para rechazar la etiqueta eliminada: git push origin :refs/tags/v0.1.0-Demoy para retrasar las etiquetas (con otras cosas pendientes)git push --tags
Star Wolf
6

Para los aventureros se puede hacer en un solo comando:

mv .git/refs/tags/OLD .git/refs/tags/NEW
Wolfc
fuente
77
Esto no funcionará si sus referencias están empacadas, es decir, si ha ejecutado git gcrecientemente
para el
2
Esto solo afectará al repositorio local. Si tiene un control remoto configurado, no estoy seguro de qué efectos negativos podría causar. No recomiendo este enfoque.
therealklanni
1
Tenga en cuenta también que para las etiquetas anotadas esto probablemente será aún más problemático, ya que el blob 'anotación', entre otras cosas, contiene el nombre original de la etiqueta. En realidad, no estoy seguro de si eso es usado por algo (con suerte, al menos, por verificar-etiqueta), pero no me arriesgaría.
gbr
1
@gbr Esto funciona bien. (Por supuesto, la nota de @forivall debe tenerse en cuenta). Este truco se ha usado masivamente durante años en el sistema de construcción ALT Sisyphus. Observe cómo se almacenan las fuentes de un paquete, por ejemplo: git.altlinux.org/gears/g/gear.git . Las etiquetas legibles como 2.0.7-alt1 son las etiquetas firmadas enviadas por los encargados del mantenimiento al sistema de compilación. El sistema de compilación coloca las etiquetas crípticas gb-sisyphus-task164472.200 para rastrear el ID de tarea que ha compilado y publicado el paquete desde esta fuente. Son copias tontas ( cp), con el mensaje del mantenedor intacto.
imz - Ivan Zakharyaschev
@ imz - IvanZakharyaschev Es bueno saberlo, aunque no confiaría demasiado en que no dará lugar a problemas en el futuro, con algún producto; no hay ninguna especificación real del formato de repositorios Git y la interacción esperada, por lo que cuando es viable Me esforzarse por hacer las cosas limpiamente en lo más mínimo sorprendente manera
GBR
3

Independientemente de los problemas relacionados con las etiquetas de inserción y el cambio de nombre de las etiquetas que ya se han enviado, en caso de que la etiqueta para cambiar el nombre sea anotada , primero puede copiarla gracias a la siguiente línea de comando de una sola línea:

git tag -a -m "`git cat-file -p old_tag | tail -n +6`" new_tag old_tag^{}

Luego, solo necesita eliminar la etiqueta anterior:

git tag -d old_tag

Encontré esta línea de comando gracias a las siguientes dos respuestas:

Editar:
Habiendo encontrado problemas al usar la configuración de sincronización automática de etiquetas fetch.pruneTags=true(como se describe en https://stackoverflow.com/a/49215190/7009806 ), personalmente sugiero que primero copie la nueva etiqueta en el servidor y luego elimine la anterior. De esa manera, la nueva etiqueta no se elimina aleatoriamente cuando se elimina la etiqueta anterior y una sincronización de las etiquetas le gustaría eliminar la nueva etiqueta que aún no está en el servidor . Entonces, por ejemplo, todos juntos obtenemos:

git tag -a -m "`git cat-file -p old_tag | tail -n +6`" new_tag old_tag^{}
git push --tags
git tag -d old_tag
git push origin :refs/tags/old_tag
Olivier
fuente
3

También puede cambiar el nombre de las etiquetas remotas sin retirarlas, duplicando la etiqueta / rama anterior con un nuevo nombre y eliminando la anterior, en un solo git pushcomando.

Cambiar nombre etiqueta remoto / rama remoto → conversión de la etiqueta: (Nota: :refs/tags/)

git push <remote_name> <old_branch_or_tag>:refs/tags/<new_tag> :<old_branch_or_tag>

Cambiar nombre rama remoto / tag remoto → conversión rama: (Nota: :refs/heads/)

git push <remote_name> <old_branch_or_tag>:refs/heads/<new_branch> :<old_branch_or_tag>

Salida renombrando una etiqueta remota:

D:\git.repo>git push gitlab App%2012.1%20v12.1.0.23:refs/tags/App_12.1_v12.1.0.23 :App%2012.1%20v12.1.0.23

Total 0 (delta 0), reused 0 (delta 0)
To https://gitlab.server/project/repository.git
 - [deleted]               App%2012.1%20v12.1.0.23
 * [new tag]               App%2012.1%20v12.1.0.23 -> App_12.1_v12.1.0.23
zionyx
fuente