问题
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.
回答1:
Here is how I rename a tag old to 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
Note that if you are changing an annotated tag, you need ensure that the new tag name is referencing the underlying commit and not the old annotated tag object that you're about to delete. Therefore, use git tag -a new old^{} instead of git tag new old (this is because annotated tags are objects while lightweight tags are not, more info in this answer).
回答2:
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.
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.
回答3:
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!
回答4:
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.
回答5:
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
So the idea is to push:
<new-tag>for every commits referenced by<old-tag>:<refs/tags/old-tag>:<refs/tags/new-tag>,- the deletion of <old-tag>:
:<refs/tags/old-tag>
See as an example "Change naming convention of tags inside a git repository?".
回答6:
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
回答7:
Follow the 3 step approach for a one or a few number of tags.
Step 1: Identify the commit/object ID of the commit the current tag is pointing to
command: git rev-parse <tag name>
example: git rev-parse v0.1.0-Demo
example output: db57b63b77a6bae3e725cbb9025d65fa1eabcde
Step 2: Delete the tag from the 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)
Step 3: Create a new tag pointing to the same commit id as the old tag was pointing to
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>
Once the local git is ready with the tag name change, these changes can be pushed back to the origin for others to take these.
回答8:
For the adventurous it can be done in one command:
mv .git/refs/tags/OLD .git/refs/tags/NEW
回答9:
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:
- https://stackoverflow.com/a/26132640/7009806 (second comment)
- https://stackoverflow.com/a/49286861/7009806
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:
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
回答10:
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/)
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/)
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
来源:https://stackoverflow.com/questions/1028649/how-do-you-rename-a-git-tag