Come posso modificare un messaggio tag esistente in git?


225

Abbiamo diversi tag annotati nel nostro repository git. I tag più vecchi hanno messaggi fasulli che vorremmo aggiornare per essere nel nostro nuovo stile.

% git tag -n1
v1.0 message
v1.1 message
v1.2 message
v2.0 Version 2.0 built on 15 October 2011.

In questo esempio, vorremmo che i messaggi v1.x assomiglino al messaggio v2.0. Qualcuno sa come lo faremmo?


2
Nota: con Git 2.17 (Q2 2018), un semplice git tag -m "A message" --edit v1.0sarebbe abbastanza. Vedi la mia risposta qui sotto
VonC


@VonC L'ho provato e ricevuto fatal: tag 'v6.6.2' already existsusando 2.17.0.
Josh Habdas,

1
Puoi sempre eliminare il tag precedente e farlo di nuovo.
RoadRunner

Risposte:


264

git tag <tag name> <tag name>^{} -f -m "<new message>"

Questo creerà un nuovo tag con lo stesso nome (sovrascrivendo l'originale).


7
Questo mantiene la data del tag originale?
James M. Greene,

16
Risposta alla mia domanda commento: Sì, non cambiare la data. :(
James M. Greene,

10
Vedere la sezione "Sui tag di backdating" in git tag --help .
dahlbyk,

6
Va anche notato che puoi anche aggiungere più messaggi (vengono separati da una nuova riga - su GitHub) git tag <tag name> <tag name> -f -m "<new message>" -m "<new message>" -m "<new message>"
Blair McMillan,

5
@ChrisMorley guarda la mia risposta sotto stackoverflow.com/a/23532519/603949 - in breve, utilizzare <tag name>^{}quando si desidera sostituire ilold tag
Sungam,

87

Per aggiornare un messaggio complesso, basta specificare l'opzione tag annotata con -ao l'opzione tag firmata con -s:

git tag <tag name> <tag name>^{} -f -a

Questo aprirà un editor con i contenuti del tuo vecchio messaggio tag .


39

git tag <tag name> <tag name>^{} -f -a

Questo è un miglioramento: senza ^{} esso creerà un nuovo oggetto tag che fa riferimento al vecchio oggetto tag, in cui entrambi avranno lo stesso nome tag.

<tag name>^{} risolverà il tag / riferimento fino a quando non trova il primo hash di commit.


4
@BrentFoust, che funziona solo quando la tua testa è al commit con tag usage: git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]
Sungam

33

TL; DR

Puoi farlo cancellando il tuo tag e ricreandolo mentre falsi la data e l'autore:

> git tag -d <tag-name>
> [GIT_COMMITTER_DATE=<original-commit-date>] \
> [GIT_AUTHOR_NAME=<original-author-name>] \
> git tag <tag-name> [commit]

L'intera storia:

Costruire su Sungram risposta di (originariamente proposta come modifica):

1. Risposta accettata

Questo è un miglioramento rispetto ad Andy ed Eric Hu alle risposte di . Le loro risposte creeranno un nuovo oggetto tag che fa riferimento al vecchio oggetto tag ed entrambi avranno lo stesso nome.

Per illustrare ciò, considerare quanto segue:

> git tag tag1 tag1 -f -a  # accepted answer
> git rev-list --objects -g --no-walk --all
[ example output: ]
6bdcc347fca041a5138f89fdf5276b3ebf9095d5
260ab7928d986472895b8c55e54569b3f3cb9517 tag1
a5797673f610914a45ef7ac051e3ee831a6e7c25 tag1
f22d6308c3cd330a3b0d86b9bf05562faf6b6f17

> git show tag1
tag tag1
Tagger: [tagger]
Date:   [date of updated tag]
[Updated description]

tag tag1
Tagger: [tagger]
Date:   [date of original tag]
[Original description]

[tagged commit details]

2. Il miglioramento di Sungram

L'utilizzo <tag name>^{}come secondo argomento di git tageliminerà invece tutti i tag precedenti con lo stesso nome.

Considera la continuazione della precedente sessione terminale:

> git tag tag1 tag1^{} -f -a  # suggested improvement
> git rev-list --objects -g --no-walk --all
[ example output: ]
6bdcc347fca041a5138f89fdf5276b3ebf9095d5
75f02acacfd7d91d55b5bcfdfb1f00aebeed15e3 tag1
f22d6308c3cd330a3b0d86b9bf05562faf6b6f17 

> git show tag1
tag tag1
Tagger: [tagger]
Date:   [date of updated tag]
[Updated description]

[tagged commit details]

3. Salva la data

Infine, se si desidera mantenere la data del tag originale come data del tag aggiornato, utilizzare un po 'di magia awk (o simile) o semplicemente incollare la data desiderata. Il seguente è un sostituto del secondo esempio (altrimenti la data originale andrebbe persa a causa della sostituzione ):

> GIT_COMMITTER_DATE="$(git show tag1 |                              # get info about the tag cascade including the date original of the original tag
> awk '{
>     if ($1 == "Date:") {
>         print substr($0, index($0,$3))
>     }
> }' |                                                               # extract all the dates from the info
> tail -2 | head -1)"                                               `# get the second to last date, as the last one is the commit date` \
> git tag tag1 tag1^{} -a -f                                         # finally, update the tag message, but save the date of the old one
>
> git rev-list --objects -g --no-walk --all
6bdcc347fca041a5138f89fdf5276b3ebf9095d5
e18c178f2a548b37799b100ab90ca785af1fede0 tag1
f22d6308c3cd330a3b0d86b9bf05562faf6b6f17
> git show tag1
tag tag1
Tagger: [tagger]
Date:   [date of original tag]
[Updated description]

[tagged commit details]

Riferimenti:

4. Fai da te

In alternativa all'aggiornamento dei tag, puoi semplicemente eliminarli e crearli di nuovo. A quanto pare l'aggiornamento aggiorna semplicemente un nuovo tag e lo fa puntare a quello vecchio, o in alternativa, elimina implicitamente quello vecchio e crea uno nuovo per puntare comunque allo stesso commit.

È possibile ottenere ciò emettendo:

> git tag -d <tag-name>
> [GIT_COMMITTER_DATE=<original-commit-date>] \
> [GIT_AUTHOR_NAME=<original-author-name>] \
> git tag <tag-name> [commit]

Ecco [optional]un campo opzionale; <required>è un campo obbligatorio. Ovviamente, puoi aggiungere qualsiasi flag dopo il git tagcomando che faresti normalmente.


3
Grazie per aver sottolineato che "Le loro risposte creeranno un nuovo oggetto tag"!
cwhsu,

Citando Andreas Schwab : The tagger is controlled by the committer info. (...) GIT_COMMITTER_{NAME,EMAIL}. A tagger isn't really an author.
Ivan Vučica,

11

La soluzione di @Andy

git tag <tag-name> <tag-name> -f -a

è sbagliato . Dopo, con

git show

comando, vedremo i tag dello stack con lo stesso nome.

Aggiunge un nuovo tag con lo stesso nome di tag e un nuovo messaggio al commit <tag-name>. Ma non rimuove il vecchio tag. È un caso speciale di questo comando:

git tag [<commit> | <old-tag>] <tag-name>

Ma <old-tag>è lo stesso con <tag-name>.


La soluzione corretta è semplice, basta aggiornare il tag è OK.

git tag <tag-name> -f -a

Ricorda, solo UNO qui.

Se vogliamo cambiare tag, che non lo è HEAD, abbiamo bisogno di un <commit>argomento in più.

git tag <commit> <tag-name> -f -a

SÌ! Hai ragione. Grazie per averlo indicato. Dopo aver riscritto il tag annotato alcune volte, ho controllato il mio tag git show <tag>e vedo tutte le edizioni precedenti.
Manoel Vilela,

Il problema è: se ho bisogno di aggiornare un tag che non lo è HEAD, passando un extra <commit>, il tag aperto è vuoto. Mi aspettavo che il vecchio tag fosse appena modificato. C'è modo?
Manoel Vilela,

Nota che la soluzione di Andy è stata aggiornata da quando hai risposto. Forse sarebbe bello iniziare la tua risposta con un messaggio dicendo che è stato corretto? Inoltre potrebbe essere che il tuo comando git tag <commit> <tag-name> -f -aabbia <commit> e <tag-name> invertiti? Sembra così quando si confronta con altre risposte e documenti, ma non sono un esperto.
Jacob Akkerboom,

7

vorremmo far apparire i messaggi v1.x come il messaggio v2.0

Con Git 2.17 (Q2 2018), ci sarà un'alternativa alla creazione di un nuovo tag con git tag <tag name> <tag name> -f -m "<new message>", poiché l' opzione " git tag" imparato un esplicito " --edit" che consente il messaggio dato tramite "-m " e " -F".

Vedi commit 9eed6e4 (06 feb 2018) di Nicolas Morey-Chaisemartin ( nmorey) .
(Unita da Junio ​​C Hamano - gitster- in commit 05d290e , 06 mar 2018)

tag: aggiungi --editopzione

Aggiungi --editun'opzione che consente di modificare i messaggi forniti da -mo -F, allo stesso modo git commit --edit.


4
Potresti fornire un esempio coerente utilizzando --edittale indirizzo per l'OP?
Josh Habdas,

@JoshHabdas in realtà, è necessario aggiungere l'opzione -f: --edit consente solo di modificare ulteriormente il messaggio.
VonC,

Grazie. Quindi, se -fviene aggiunto anche il flag --edit, il messaggio verrà modificato e il timestamp, giusto?
Josh Habdas,

@JoshHabdas Questa è l'idea, sì.
VonC,

4

Dovrai taggare di nuovo, usando il -fflag force.

git tag v1.0 -f -m "actual message"

3
Questa soluzione suppone che l'attuale git head sia alla versione 1.0. Questo può rovinare le cose se non lo è, poiché modifica la revisione associata alla versione 1.0. La soluzione di Andy evita questa trappola.
Eric O Lebigot,

4

Usando le risposte sopra, questo è il mio alias one-liner per .gitconfig. Sostituisce il tag esistente e mantiene la data di commit.

[alias]
    tm = "!sh -c 'f() { export GIT_COMMITTER_DATE=$(git log -1 --format=%ci $0); git tag -f -a $0 $0^{}; }; f '"

Miglioramenti?


1
Mantiene anche l'autore: tag-amend = "!sh -c 'f() { name=$(git log -1 --format=%an $0); email=$(git log -1 --format=%ae $0); date=$(git log -1 --format=%ci $0); GIT_AUTHOR_NAME=\"${name}\" GIT_COMMITTER _NAME=\"${name}\" GIT_AUTHOR_EMAIL=\"${email}\" GIT_COMMITTER_EMAIL=\"${email}\" GIT_AUTHOR_DATE=\"${date}\" GIT_COMMITTER_DATE=\"${date}\" git tag -f -a $0 $0^{}; }; f '"
minuscolo

1
Ho appena provato questo. Invece di fornire al tag sostitutivo le informazioni sull'autore e sulla data dal tag stesso, utilizza le informazioni dal commit a cui punta il tag. Questo non è necessariamente lo stesso e, in realtà, non è lo stesso per il nostro caso il più delle volte. Abbiamo un'infrastruttura multi-repo e utilizziamo tag annotati in un repository "core" per registrare informazioni sui push che si estendono su più repository. Quindi, in sostanza, l'impegno indicato potrebbe non far parte nemmeno della vera spinta. Le informazioni nel tag annotato dovrebbero riflettere le spinte reali negli altri repository.
Tanager,

0

Se si utilizza un'interfaccia grafica simile SmartGit solo

  1. crea di nuovo lo stesso tag nella stessa posizione con il nuovo messaggio
  2. scegli "sovrascrivi tag esistente"
  3. forzare il tag verso il repository upstream
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.