How do you rename a Git tag?

How do you rename a Git tag?



Today I was looking through the logs for a project and realized that I fat fingered a tag name some time ago. Is there some way to rename the tag? Google hasn't turned up anything useful.



I realize I could check out the tagged version and make a new tag, I even tried that. But that seems to create a tag object that isn't quite right. For one,


git tag -l



lists it out of order relative to all of the other tags. I have no idea if that's significant, but it leads me to believe that the new tag object isn't quite what I want. I can live with that, because I really only care that the tag name matches the documentation, but I'd rather do it "right", assuming there is a right way to do this.





Did you use the same invocation, i.e. if the old tag was annotated/signed tag, is the new tag also of this kind, or is it lightweight tag?
– Jakub Narębski
Jun 23 '09 at 8:07





Both the incorrect old tag, and the desired new tag, should be annotated and unsigned. The old tag was created with 'git tag -a bad_tag_name', so I'd like to do something along the lines of 'git tag -a good_tag_name'.
– Brandon Fosdick
Jun 23 '09 at 22:01





I should point out that I also want this magical tag rename process to preserve the annotation from the tag being renamed. Actually, I would really like to change just the name and nothing else.
– Brandon Fosdick
Jun 23 '09 at 22:09





git log --oneline --decorate --graph is helpful when cleaning up tags.
– Joel Purra
May 4 '12 at 18:00


git log --oneline --decorate --graph





You can rename a tag in one line: see my answer below
– VonC
Jun 16 '14 at 14:21




9 Answers
9



Here is how I rename a tag old to new:


old


new


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



The colon in the push command removes the tag from the remote repository. If you don't do this, Git will create the old tag on your machine when you pull.



Finally, make sure that the other users remove the deleted tag. Please tell them (co-workers) to run the following command:


git pull --prune --tags





if tag is annotated the new tag won't have the message of the old one, but it's a helpful info
– NickSoft
May 26 '11 at 15:34






@NickSoft, I just did the above with annotated tags. The messages were copied from old to new just fine. Maybe I have a newer version of git?
– katyhuff
Apr 19 '13 at 4:17






One thing to note is that if you use git tag new old is that "old" makes it into the "new" tag iff "old" is not a lightweight tag. To see that, try: git tag -m tralala old; git tag new old; git tag -d old; git cat-file tag new | grep old. That's because "new" points to the "old" tag, not to the commit "old" points to.
– Uwe Kleine-König
Dec 17 '13 at 16:43


git tag new old


git tag -m tralala old; git tag new old; git tag -d old; git cat-file tag new | grep old





git push origin :refs/tags/old can be simplified to git push origin :old I think.
– Jesse Glick
Jan 28 '14 at 0:30


git push origin :refs/tags/old


git push origin :old





I would suggest changing "git push --tags" to be more explicit to this tag "git push origin refs/tags/new". You don't want to inadvertently push other tags.
– chrish
May 14 '14 at 18:47




The original question was how to rename a tag, which is easy: first create NEW as an alias of OLD: git tag NEW OLD then delete OLD: git tag -d OLD.


git tag NEW OLD


git tag -d OLD



The quote regarding "the Git way" and (in)sanity is off base, because it's talking about preserving a tag name, but making it refer to a different repository state.





Answer above is slightly preferable as it includes the git push origin business.
– Roly
Sep 29 '13 at 20:39


git push origin





easiest way, work great to rename a previous release tag created with Gitflow
– RousseauAlexandre
Nov 17 '16 at 10:02





Warning: Using git tag new old will create a tag pointing to the old tag, not the old tag's commit. (See Why can't I checkout my tag from Git GUI?)
– Steven M. Vascellaro
Mar 14 at 17:30



git tag new old



In addition to the other answers:



First you need to build an alias of the old tag name, pointing to the original commit:


git tag new old^



Then you need to delete the old one locally:


git tag -d old



Then delete the tag on you remote location(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



Finally you need to add your new tag to the remote location. Until you have done this, the new tag(s) will not be added:


git push origin --tags



Iterate this for every remote location.



Be aware, of the implications that a Git Tag change has to consumers of a package!





Warning: Using git tag new old will create a tag pointing to the old tag, not the old tag's commit. (See Why can't I checkout my tag from Git GUI?)
– Steven M. Vascellaro
Mar 14 at 17:30


git tag new old





@StevenVascellaro Thanks for the link. For the next time, please file an edit – answering is a community effort as well. Thanks.
– kaiser
Mar 14 at 21:13





I didn’t make an edit because I have not tested the code for myself yet. (Note the submit date on the linked question)
– Steven M. Vascellaro
Mar 14 at 21:26





Once we do git tag new old^, then we don't need git tag new_tag_name old_tag_name (the first step).
– Breaking Benjamin
May 13 at 7:04


git tag new old^


git tag new_tag_name old_tag_name





OK, I tested and edited the answer.
– jcupitt
May 18 at 7:16



If it's published, you can't delete it (without risking being tarred and feathered, that is). The 'Git way' is to do:



The sane thing. Just admit you screwed up, and use a different name. Others have already seen one tag-name, and if you keep the same name, you may be in the situation that two people both have "version X", but they actually have different "X"'s. So just call it "X.1" and be done with it.



Alternatively,



The insane thing. You really want to call the new version "X" too, even though others have already seen the old one. So just use git-tag -f again, as if you hadn't already published the old one.



It's so insane because:



Git does not (and it should not) change tags behind users back. So if somebody already got the old tag, doing a git-pull on your tree shouldn't just make them overwrite the old one.



If somebody got a release tag from you, you cannot just change the tag for them by updating your own one. This is a big security issue, in that people MUST be able to trust their tag-names. If you really want to do the insane thing, you need to just fess up to it, and tell people that you messed up.



All courtesy of the man pages.





Or you can tag (with correct name) this incorrectly named tag.
– Jakub Narębski
Jun 23 '09 at 8:06





Thanks, I've been over that man page a million times already. Fortunately the bad tag hasn't been published anywhere. Even if it was, this is an internal project and I'm the only developer (for the moment). I'm think I'm fairly safe from both the tarring and the feathering, but only if I can get the repo to match the docs.
– Brandon Fosdick
Jun 23 '09 at 22:06





I sometimes use tags for my own personal references. Eg. it could be a 'ok_jb' tag. I use this, because some of the people I work with cannot build for my platform, so sometimes there will be build errors. I can then quickly get a version that builds, by checking out that tag. When the new sources builds, I just move the tag, or I rename it to builds##, where ## is a number (depending on the project). I may also emphasize when a special feature was introduced, by adding a tag.
– user1985657
Oct 10 '14 at 2:04






Poor answer. "Don't do it" is never the correct answer to "How can I do it?". The user wasn't asking if you think it is a good idea to do that or if people will like that. If someone asks "How can I cut off my hand", either tell him how it's done or leave him alone but he won't need someone telling him that cutting of a hand may not be such a great idea. And you can do it. You can add a new tag and delete the old one, it's technically possible, even in a remote repository.
– Mecki
Nov 3 '15 at 15:08





This seems to answer the question "How do I make an existing tag point to a different revision?" instead of the OP's question, "How do I rename a tag?" It's also unclear how telling people you messed up is going to solve the problem (even though it's a good idea in general).
– LarsH
Mar 9 '16 at 19:49



As an add on to the other answers, I added an alias to do it all in one step, with a more familiar *nix move command feel. Argument 1 is the old tag name, argument 2 is the new tag name.


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



Usage:


git renametag old new



This wiki page has this interesting one-liner, which reminds us that we can push several refs:


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



and ask other cloners to do git pull --prune --tags


git pull --prune --tags



So the idea is to push:


<new-tag>


<old-tag


<refs/tags/old-tag>:<refs/tags/new-tag>


<old-tag>


:<refs/tags/old-tag>



See as an example "Change naming convention of tags inside a git repository?".





Does this preserve annotations?
– Brandon Fosdick
Jun 21 '14 at 8:32





@BrandonFosdick yes, it works for annotated tags.
– VonC
Jun 21 '14 at 8:42





Beware that this leaves the original tag name in the annotation for annotated tags!! I'm not sure if that actually implies anything though, at least in the current versions.
– gbr
Aug 20 '15 at 18:26






@VonC I'm not sure I understand what you're asking; maybe I wasn't clear: the annotation objects contain a tag field that's set to the tag's name, you can see it with git cat-file -p <tag>; with your method on my system I do get the 'renamed' tag ref (<new-tag>), but its tag field is still <old-tag>.
– gbr
Aug 20 '15 at 23:25



git cat-file -p <tag>


<new-tag>


<old-tag>





@gbr Isn't what the OP wanted? He mentioned "I should point out that I also want this magical tag rename process to preserve the annotation from the tag being renamed. Actually, I would really like to change just the name and nothing else" (stackoverflow.com/questions/1028649/how-do-you-rename-a-git-tag/…)
– VonC
Aug 21 '15 at 5:33




For the adventurous it can be done in one command:


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





This won't work if your refs are packed, i.e. if you've run git gc recently
– forivall
Dec 7 '12 at 1:21


git gc





This also will only affect the local repo. If you have a remote configured, I'm not sure what negative effects this could cause. I do not recommend this approach.
– therealklanni
May 9 '13 at 21:08





Note also that for annotated tags this will probably be even more troublesome, as the 'annotation' blob among the other things contains the original name of the tag. Actually I'm not sure if that's used by anything (hopefully at least by verify-tag), but I wouldn't take a chance.
– gbr
Aug 20 '15 at 18:12





@gbr This works just fine.(Of course, the note by @forivall is to be taken into account.) This trick has been massively used for ages in the ALT Sisyphus build system. Look at how the sources for a package are stored, e.g.: git.altlinux.org/gears/g/gear.git . The readable tags like 2.0.7-alt1 are the signed tags submitted by the maintainers to the build system. The cryptic tags gb-sisyphus-task164472.200 are put there by the build system to track the task ID that has built&published the pkg from this source. They are dumb copies (cp), with the maintainer's message untouched.
– imz -- Ivan Zakharyaschev
May 11 '16 at 22:54


cp





@imz--IvanZakharyaschev Good to know, I wouldn't put too much trust though that it won't give rise to problems in the future, with some product; there's no real specification of the git repositories format and expected interaction, so when it's viable I would strive to do things cleanly in the least surprising way
– gbr
May 13 '16 at 14:29



The easy part is renaming local tags. The tougher part is the remote ones.
The idea behind this trick is to duplicate the old tag/branch to a new one and delete the old one, without checkout.



Remote tag rename / Remote branch → tag conversion: (Notice: :refs/tags/)


:refs/tags/


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



Remote branch rename / Remote tag → branch conversion: (Notice: :refs/heads/)


:refs/heads/


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



Output renaming a remote tag:


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



Regardless of the issues dealing with pushing tags and renaming tags that have already been pushed, in case the tag to rename is an annotated one, you could first copy it thanks to the following single-line command line:


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



Then, you just need to delete the old tag:


git tag -d old_tag



I found this command line thanks to the following two answers:



Edit:

Having encountered problems using automatic synchronisation of tags setting fetch.pruneTags=true (as described in https://stackoverflow.com/a/49215190/7009806), I personally suggest to first copy the new tag on the server and then delete the old one. That way, the new tag does not get randomly deleted when deleting the old tag and a synchronisation of the tags would like to delete the new tag that is not yet on the server. So, for instance, all together we get:


fetch.pruneTags=true


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




Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



Would you like to answer one of these unanswered questions instead?

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)