Comment modifier un message de tag existant dans git?

225

Nous avons plusieurs balises annotées dans notre référentiel git. Les balises plus anciennes contiennent de faux messages que nous aimerions mettre à jour pour être dans notre nouveau style.

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

Dans cet exemple, nous aimerions faire ressembler les messages v1.x au message v2.0. Quelqu'un sait comment nous ferions cela?

jared
la source
2
Remarque: avec Git 2.17 (Q2 2018), un simple git tag -m "A message" --edit v1.0serait suffisant. Voir ma réponse ci
VonC
En relation: Comment renommer une balise Git?
Stevoisiak
@VonC J'ai essayé et reçu en fatal: tag 'v6.6.2' already existsutilisant 2.17.0.
Josh Habdas
1
Vous pouvez toujours supprimer la balise précédente et recommencer.
RoadRunner

Réponses:

264

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

Cela créera une nouvelle balise du même nom (en écrasant l'original).

Andy
la source
7
Cela maintient-il la date de la balise d'origine?
James M. Greene
16
Réponse à ma question de commentaire: Oui, il ne modifie la date. :(
James M. Greene
10
Consultez la section «Sur les balises antidatées» dans git tag --help.
dahlbyk
6
Il convient également de noter que vous pouvez également ajouter plusieurs messages (ils sont séparés par une nouvelle ligne - sur GitHub)git tag <tag name> <tag name> -f -m "<new message>" -m "<new message>" -m "<new message>"
Blair McMillan
5
@ChrisMorley regarde ma réponse ci-dessous stackoverflow.com/a/23532519/603949 - en bref, utilisez <tag name>^{}quand vous voulez remplacer leold tag
Sungam
87

Pour mettre à jour un message complexe, spécifiez simplement l'option de balise annotée avec -aou l'option de balise signée avec -s:

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

Cela ouvrira un éditeur avec le contenu de votre ancien message de balise .

Eric Hu
la source
39

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

Ceci est une amélioration: sans ^{}cela, un nouvel objet tag sera créé qui référencera l'ancien objet tag, où les deux auront le même nom de tag.

<tag name>^{} résoudra la balise / référence jusqu'à ce qu'il trouve le premier hachage de validation.

Sungam
la source
4
@BrentFoust, cela ne fonctionne que lorsque votre tête est au commit balisé usage: git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]
Sungam
33

TL; DR

Vous pouvez le faire en supprimant votre tag et en le recréant tout en usurpant la date et l'auteur:

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

Histoire entière:

S'appuyant sur la réponse de Sungram (initialement proposée comme édition):

1. Réponse acceptée

C'est une amélioration par rapport aux réponses d' Andy et d' Eric Hu . Leurs réponses créeront un nouvel objet balise qui fait référence à l'ancien objet balise et les deux auront le même nom.

Pour illustrer cela, considérez ce qui suit:

> 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. L'amélioration de Sungram

Utiliser <tag name>^{}comme deuxième argument de git tagva à la place supprimer toutes les balises précédentes portant le même nom.

Considérez la poursuite de la session terminale précédente:

> 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. Enregistrez la date

Enfin, si vous souhaitez conserver la date de la balise d'origine comme date de la balise mise à jour, utilisez un peu de magie awk (ou similaire) ou collez simplement la date de votre choix à la place. Ce qui suit est un substitut pour le deuxième exemple (sinon la date d'origine serait perdue en raison d' une substitution ):

> 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]

Références:

4. DIY

Alternativement à la mise à jour des balises, vous pouvez simplement les supprimer et les recréer. Comme il s'avère que la mise à jour ajoute simplement une nouvelle balise et la fait pointer vers l'ancienne, ou alternativement, supprime implicitement l'ancienne et crée une nouvelle pour pointer vers le même commit de toute façon.

Vous pouvez y parvenir en émettant:

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

Voici [optional]un champ facultatif; <required>est un champ obligatoire. Bien sûr, vous pouvez ajouter des indicateurs après la git tagcommande comme vous le feriez normalement.

stanm
la source
3
Merci d'avoir souligné que "Leurs réponses créeront un nouvel objet tag"!
cwhsu
Citant 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 solution de @Andy

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

est faux . Après, avec

git show

, nous verrons des balises de pile portant le même nom.

Il ajoute une nouvelle balise avec le même nom de balise et un nouveau message lors de la validation <tag-name>. Mais cela ne supprime pas l'ancienne balise. C'est un cas particulier de cette commande:

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

Mais <old-tag>c'est pareil avec <tag-name>.


La solution correcte est simple, il suffit de mettre à jour la balise est OK.

git tag <tag-name> -f -a

Rappelez - vous, seulement UN ici.

Si nous voulons changer de balise, ce qui n'est pas le cas HEAD, nous avons besoin d'un <commit>argument supplémentaire .

git tag <commit> <tag-name> -f -a
liuyang1
la source
OUI! Vous avez raison. Merci d'avoir souligné cela. Après avoir réécrit le tag annoté plusieurs fois, j'ai vérifié mon tag avec git show <tag>et je vois toutes les éditions précédentes.
Manoel Vilela
Le problème est: si j'ai besoin de mettre à jour une balise qui ne l'est pas HEAD, en passant le supplément <commit>, la balise ouverte est vide. Je m'attendais à ce que l'ancienne balise soit éditée. Y a-t-il moyen?
Manoel Vilela
Veuillez noter que la solution d'Andy a été mise à jour depuis votre réponse. Ce serait peut-être bien de commencer votre réponse par un message disant qu'elle a été corrigée? Se pourrait-il également que votre commande git tag <commit> <tag-name> -f -aait <commit> et <tag-name> inversés? Cela ressemble à cela lorsque vous comparez avec d'autres réponses et les documents, mais je ne suis pas un expert.
Jacob Akkerboom
7

nous aimerions que les messages v1.x ressemblent au message v2.0

Avec Git 2.17 (Q2 2018), il y aura une alternative à la création d'une nouvelle balise git tag <tag name> <tag name> -f -m "<new message>", car l' option " git tag" a appris une explicite " --edit" qui permet de modifier davantage le message donné via " -m" et " -F".

Voir commit 9eed6e4 (06 février 2018) par Nicolas Morey-Chaisemartin ( nmorey) .
(Fusionné par Junio ​​C Hamano - gitster- en commit 05d290e , 06 mars 2018)

tag: ajouter une --editoption

Ajoutez une --editoption qui permet de modifier les messages fournis par -mou -F, de la même manière git commit --edit.

VonC
la source
4
Pourriez-vous, s'il vous plaît, fournir un exemple cohérent utilisant --editcette adresse du PO?
Josh Habdas
@JoshHabdas en fait, vous devez ajouter l'option -f: --edit permet uniquement de modifier le message.
VonC
Merci. Donc, si un -fdrapeau est également ajouté, --editle message sera modifié et l'horodatage sera modifié, non?
Josh Habdas
@JoshHabdas C'est l'idée, oui.
VonC
4

Vous devrez à nouveau marquer, en utilisant le -fdrapeau de force.

git tag v1.0 -f -m "actual message"
manojlds
la source
3
Cette solution suppose que la tête git actuelle est à la version 1.0. Cela peut gâcher les choses si ce n'est pas le cas, car cela modifie la révision associée à la version 1.0. La solution d'Andy évite cet écueil.
Eric O Lebigot
4

En utilisant les réponses ci-dessus, c'est mon alias one-liner pour .gitconfig. Remplace la balise existante et préserve la date de validation.

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

Des améliorations?

h0tw1r3
la source
1
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 '"
Garde
1
Je viens d'essayer ça. Au lieu de donner à la balise de remplacement l'auteur et les informations de date de la balise elle-même, elle utilise les informations de la validation vers laquelle la balise pointe. Ce n'est pas nécessairement la même chose et, en fait, ce n'est pas la même chose dans notre cas la plupart du temps. Nous avons une infrastructure multi-repo et utilisons des balises annotées dans un repo «core» pour enregistrer des informations sur les push qui s'étendent sur plusieurs référentiels. Donc, dans le fond, l'engagement validé pourrait ne même pas faire partie de la vraie poussée. Les informations dans la balise annotée doivent refléter les poussées réelles dans les autres référentiels.
tanager
0

Si vous utilisez une interface graphique comme SmartGit juste

  1. recréez la même balise au même endroit avec le nouveau message
  2. choisissez "écraser la balise existante"
  3. forcer la balise vers le référentiel en amont
rubo77
la source