Come si rinomina un tag Git?


1219

Oggi stavo cercando tra i registri un progetto e mi sono reso conto che un po 'di tempo fa avevo fatto il dito sul nome di un tag. C'è un modo per rinominare il tag? Google non ha rivelato nulla di utile.

Mi rendo conto che potrei controllare la versione taggata e creare un nuovo tag, ci ho persino provato. Ma questo sembra creare un oggetto tag che non è del tutto corretto. Per uno,

git tag -l

lo elenca fuori servizio rispetto a tutti gli altri tag. Non ho idea se sia significativo, ma mi porta a credere che il nuovo oggetto tag non sia esattamente quello che voglio. Posso convivere con quello, perché mi interessa davvero solo che il nome del tag corrisponda alla documentazione, ma preferirei farlo "giusto", supponendo che ci sia un modo giusto per farlo.


Hai usato la stessa invocazione, ovvero se il vecchio tag era un tag annotato / firmato, anche il nuovo tag è di questo tipo o è un tag leggero?
Jakub Narębski,

1
Sia il vecchio tag errato, sia il nuovo tag desiderato, devono essere annotati e non firmati. Il vecchio tag è stato creato con 'git tag -a nome_del_video', quindi mi piacerebbe fare qualcosa sulla falsariga di 'tag -it_un_nome_tag'.
Brandon Fosdick,

Vorrei sottolineare che voglio anche che questo magico processo di ridenominazione dei tag mantenga l'annotazione dal tag rinominato. In realtà, vorrei davvero cambiare solo il nome e nient'altro.
Brandon Fosdick,

7
git log --oneline --decorate --graphè utile per ripulire i tag.
Joel Purra,

Puoi rinominare un tag in una riga: vedi la mia risposta di seguito
VonC

Risposte:


2040

Ecco come rinominare un tag oldin new:

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

I due punti nel comando push rimuovono il tag dal repository remoto. Se non lo fai, Git creerà il vecchio tag sul tuo computer quando tiri.

Infine, assicurati che gli altri utenti rimuovano il tag eliminato. Si prega di dire loro (collaboratori) di eseguire il seguente comando:

git pull --prune --tags

Si noti che se si modifica un tag con annotazioni , è necessario assicurarsi che il nome del nuovo tag faccia riferimento al commit sottostante e non al vecchio oggetto tag con annotazione che si sta per eliminare. Pertanto, utilizzare git tag -a new old^{}invece di git tag new old(questo perché i tag con annotazioni sono oggetti mentre i tag leggeri non lo sono, maggiori informazioni in questa risposta ).


19
se il tag è annotato, il nuovo tag non avrà il messaggio di quello vecchio, ma è
un'informazione

25
@NickSoft, ho appena fatto quanto sopra con tag annotati. I messaggi sono stati copiati dal vecchio al nuovo bene. Forse ho una versione più recente di git?
katyhuff,

25
git push origin :refs/tags/oldposso essere semplificato a git push origin :oldmio avviso.
Jesse Glick,

25
Suggerirei di cambiare "git push --tags" per essere più esplicito con questo tag "git push origin refs / tags / new". Non vuoi spingere inavvertitamente altri tag.
chrish,

11
Avviso : l'utilizzo git tag new oldcreerà un tag che punta al vecchio tag, non al vecchio commit del tag. (Vedi Perché non posso controllare il mio tag dalla GUI di Git? )
Stevoisiak,

297

La domanda iniziale era come rinominare un tag, che è facile: in primo luogo creare nuovi come alias di OLD: git tag NEW OLDquindi eliminare VECCHIO: git tag -d OLD.

La citazione relativa a "The Git Way" e (in) sanità mentale è off base, perché si tratta di preservare un nome di tag, ma di farlo fare riferimento a un diverso stato del repository.


3
La risposta sopra è leggermente preferibile in quanto include l' git push originattività.
Roly,

il modo più semplice, funziona alla grande per rinominare un tag di rilascio precedente creato con Gitflow
RousseauAlexandre

5
Avviso : l'utilizzo git tag new oldcreerà un tag che punta al vecchio tag, non al vecchio commit del tag. (Vedi Perché non posso controllare il mio tag dalla GUI di Git? )
Stevoisiak,

118

Oltre alle altre risposte:

Per prima cosa devi creare un alias del vecchio nome del tag, puntando al commit originale:

git tag new old^{}

Quindi è necessario eliminare quello vecchio a livello locale :

git tag -d old

Quindi elimina il tag dalle posizioni remote:

# 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

Infine, devi aggiungere il nuovo tag alla posizione remota. Fino a quando non lo avrai fatto, i nuovi tag non verranno aggiunti:

git push origin --tags

Iterate questo per ogni posizione remota.

Essere consapevoli delle implicazioni che una modifica Git Tag ha per i consumatori di un pacchetto!


Avviso : l'utilizzo git tag new oldcreerà un tag che punta al vecchio tag, non al vecchio commit del tag. (Vedi Perché non posso controllare il mio tag dalla GUI di Git? )
Stevoisiak,

1
@StevenVascellaro Grazie per il link. Per la prossima volta, si prega di presentare una modifica - anche la risposta è uno sforzo della comunità. Grazie.
Kaiser

Non ho apportato alcuna modifica perché non ho ancora testato il codice per me stesso. (Nota la data di presentazione sulla domanda collegata)
Stevoisiak

Una volta fatto git tag new old^{}, non abbiamo bisogno git tag new_tag_name old_tag_name(il primo passo).
Numero 945,

28

Se è pubblicato, non puoi eliminarlo (senza rischiare di essere catramato e piumato, cioè). Il "modo Git" è quello di fare:

La cosa sana di mente. Ammetti di aver sbagliato e di usare un nome diverso. Altri hanno già visto un nome-tag e se mantieni lo stesso nome, potresti trovarti nella situazione in cui due persone hanno entrambe la "versione X", ma in realtà hanno "X" diverse. Quindi chiamalo semplicemente "X.1" e falla finita.

In alternativa,

La cosa folle. Vuoi davvero chiamare anche la nuova versione "X", anche se altri hanno già visto quella vecchia. Quindi usa di nuovo git-tag -f, come se non avessi già pubblicato quello vecchio.

È così folle perché:

Git non cambia (e non dovrebbe) cambiare i tag dietro gli utenti. Quindi, se qualcuno ha già ottenuto il vecchio tag, fare un git-pull sul tuo albero non dovrebbe solo farli sovrascrivere quello vecchio.

Se qualcuno ha ricevuto un tag di rilascio da te, non puoi semplicemente cambiarlo aggiornando il tuo. Questo è un grosso problema di sicurezza, in quanto le persone DEVONO essere in grado di fidarsi dei loro nomi di tag. Se vuoi davvero fare la cosa folle, devi solo farcela e dire alla gente che hai sbagliato.

Tutto per gentile concessione delle pagine man .


6
Oppure puoi taggare (con il nome corretto) questo tag dal nome errato.
Jakub Narębski,

6
Grazie, ho già consultato quella pagina man un milione di volte. Fortunatamente il brutto tag non è stato pubblicato da nessuna parte. Anche se lo fosse, questo è un progetto interno e sono l'unico sviluppatore (per il momento). Penso di essere abbastanza al sicuro sia dal combattimento che dalla sfumatura, ma solo se riesco a ottenere il repository in modo che corrisponda ai documenti.
Brandon Fosdick,

A volte uso i tag per i miei riferimenti personali. Per esempio. potrebbe essere un tag "ok_jb". Lo uso perché alcune delle persone con cui lavoro non possono creare per la mia piattaforma, quindi a volte ci saranno errori di compilazione. Posso quindi ottenere rapidamente una versione che crea, controllando quel tag. Quando le nuove fonti vengono compilate, sposto semplicemente il tag o lo rinomino in build ##, dove ## è un numero (a seconda del progetto). Posso anche sottolineare quando è stata introdotta una funzione speciale, aggiungendo un tag.

7
Risposta scadente "Non farlo" non è mai la risposta corretta a "Come posso farlo?". L'utente non stava chiedendo se pensi che sia una buona idea farlo o se alla gente piacerà. Se qualcuno chiede "Come posso tagliare la mia mano", digli come è fatto o lascialo in pace, ma non avrà bisogno che qualcuno gli dica che tagliare una mano potrebbe non essere una grande idea. E puoi farlo. È possibile aggiungere un nuovo tag ed eliminare quello vecchio, è tecnicamente possibile, anche in un repository remoto.
Mecki,

5
Questo sembra rispondere alla domanda "Come faccio a fare in modo che un tag esistente punti a una revisione diversa?" invece della domanda del PO, "Come rinominare un tag?" Non è anche chiaro come dire alla gente che hai incasinato risolverà il problema (anche se è una buona idea in generale).
LarsH

25

Questa pagina wiki ha questo interessante one-liner, che ci ricorda che possiamo spingere diversi ref :

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

e chiedere ad altri clonatori di fare git pull --prune --tags

Quindi l'idea è di spingere:

  • <new-tag>per ogni commit a cui fa riferimento <old-tag>> <refs/tags/old-tag>:<refs/tags/new-tag>,
  • la cancellazione di<old-tag> ::<refs/tags/old-tag>

Vedi come esempio " Cambia la convenzione di denominazione dei tag all'interno di un repository git? ".


Ciò preserva le annotazioni?
Brandon Fosdick,

1
Attenzione che questo lascia il nome del tag originale nell'annotazione per i tag annotati !! Non sono sicuro che ciò implichi effettivamente qualcosa, almeno nelle versioni attuali.
martedì

@gbr Puoi modificare la risposta con un esempio che mostra che "nome tag originale" è rimasto nell'annotazione?
VonC,

1
@VonC Non sono sicuro di aver capito cosa stai chiedendo; forse non ero chiaro: gli oggetti annotazione contengono un campo tag che è impostato sul nome del tag, puoi vederlo con git cat-file -p <tag>; con il tuo metodo sul mio sistema ottengo il tag 'rinominato' ref ( <new-tag>), ma il suo campo tag è ancora <old-tag>.
martedì

3
@gbr Non è quello che voleva l'OP? Ha menzionato "Vorrei sottolineare che voglio anche che questo magico processo di ridenominazione dei tag preservi l'annotazione dal tag che viene rinominato. In realtà, vorrei davvero cambiare solo il nome e nient'altro" ( stackoverflow.com/questions/1028649/ how-do-you-rename-a-git-tag / ... )
VonC

25

Come aggiunta alle altre risposte, ho aggiunto un alias per fare tutto in un solo passaggio, con una sensazione di comando di spostamento * nix più familiare. L'argomento 1 è il vecchio nome del tag, l'argomento 2 è il nuovo nome del tag.

[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

Questo non ha funzionato per me, dal momento che non è riuscito a !sh(domanda è stata relative a Windows Git), invece, dopo l'aggiornamento del formato di seguito, ha funzionato: renametag = "!f() { git tag $2 $1; git tag -d $1; git push origin :refs/tags/$1; git push --tags; }; f".
Sunny Patel,

10

Segui l'approccio in 3 passaggi per uno o alcuni numeri di tag.

Passaggio 1: identificare l'ID commit / oggetto del commit a cui punta il tag corrente

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

Passaggio 2: eliminare il tag dal repository

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

Passaggio 3: crea un nuovo tag che punta allo stesso ID commit a cui puntava il vecchio tag

     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 volta che git locale è pronto con la modifica del nome del tag, queste modifiche possono essere riportate all'origine per consentire ad altri di prenderle.


Mancano i passaggi per respingere i tag eliminati: git push origin :refs/tags/v0.1.0-Demoe per respingere i tag (con altre cose in sospeso)git push --tags
Star Wolf,

6

Per gli avventurosi può essere fatto in un solo comando:

mv .git/refs/tags/OLD .git/refs/tags/NEW

7
Questo non funzionerà se i vostri arbitri sono imballati, vale a dire se si è a corto git gcdi recente
forivall

2
Ciò influirà anche solo sul repository locale. Se hai un telecomando configurato, non sono sicuro di quali effetti negativi ciò potrebbe causare. Non consiglio questo approccio.
therealklanni,

1
Si noti inoltre che per i tag annotati ciò sarà probabilmente ancora più problematico, poiché il BLOB "annotazione" tra le altre cose contiene il nome originale del tag. In realtà non sono sicuro che sia usato da qualcosa (speriamo almeno con il tag di verifica), ma non avrei alcuna possibilità.
martedì

1
@gbr Funziona bene (ovviamente, la nota di @forivall deve essere presa in considerazione). Questo trucco è stato usato in modo massiccio da secoli nel sistema di build ALT Sisyphus. Guarda come sono archiviati i sorgenti di un pacchetto, ad esempio: git.altlinux.org/gears/g/gear.git . I tag leggibili come 2.0.7-alt1 sono i tag firmati inviati dai manutentori al sistema di compilazione. I tag criptici gb-sisyphus-task164472.200 vengono messi lì dal sistema di compilazione per tenere traccia dell'ID attività che ha creato e pubblicato il pkg da questa fonte. Sono copie stupide ( cp), con il messaggio del manutentore intatto.
imz - Ivan Zakharyaschev,

@ imz - IvanZakharyaschev Buono a sapersi, non mi fiderei troppo anche del fatto che non causerà problemi in futuro, con alcuni prodotti; non esiste una specifica specifica del formato dei repository git e dell'interazione prevista, quindi quando è fattibile mi sforzo di fare le cose in modo pulito nel modo meno sorprendente
gbr

3

Indipendentemente dai problemi relativi al push dei tag e alla ridenominazione dei tag che sono già stati inviati, nel caso in cui il tag da rinominare sia annotato , è possibile innanzitutto copiarlo grazie alla seguente riga di comando a riga singola:

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

Quindi, devi solo eliminare il vecchio tag:

git tag -d old_tag

Ho trovato questa riga di comando grazie alle seguenti due risposte:

Modifica: dopo
aver riscontrato problemi utilizzando la sincronizzazione automatica delle impostazioni dei tag fetch.pruneTags=true(come descritto in https://stackoverflow.com/a/49215190/7009806 ), suggerisco personalmente di copiare prima il nuovo tag sul server e quindi eliminare quello vecchio. In questo modo, il nuovo tag non viene eliminato in modo casuale quando si elimina il vecchio tag e una sincronizzazione dei tag vorrebbe eliminare il nuovo tag che non è ancora sul server . Quindi, per esempio, tutti insieme otteniamo:

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

3

Puoi anche rinominare i tag remoti senza estrarli, duplicando il vecchio tag / ramo con un nuovo nome ed eliminando quello vecchio, con un solo git pushcomando.

Tag rename remoto / filiale remota → conversione tag: (Avviso: :refs/tags/)

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

Ramo rinominare Remote / tag remoto → conversione ramo: (Avviso: :refs/heads/)

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

Output che rinomina un tag remoto:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.