Reputation: 12913
I created a tag on the master branch called v0.1
like this:
git tag -a v0.1
But then I realized there were still some changes I needed to merge into master for release 0.1, so I did that. But now my v0.1
tag is stuck on (to invoke the post-it note analogy) the wrong commit. I want it to be stuck on the most recent commit on master, but instead it is stuck on the second most recent commit on master.
How can I move it to the most recent commit on master?
Upvotes: 1232
Views: 620894
Reputation: 345
If needed to update all tags to the latest commit of the current branch:
for i in $(git tag); do
git push origin ":refs/tags/$i"
git tag -fa $i
done
git push origin --tags
Upvotes: 0
Reputation: 992707
Use the -f
option to git tag
:
-f
--force
Replace an existing tag with the given name (instead of failing)
You probably want to use -f
in conjunction with -a
to force-create an annotated tag instead of a non-annotated one.
Delete the tag on any remote before you push
git push origin :refs/tags/<tagname>
Replace the tag to reference the most recent commit
git tag -fa <tagname>
Push the tag to the remote origin
git push origin --tags
Upvotes: 1635
Reputation: 1024
If the desired end result is updating the contents of a tag already on remote:
git checkout <tag_name>
git tag -f <tag_name>
git push -f origin <tag_name>
Upvotes: 2
Reputation: 987
Remove locally:
git tag -d v0.1
Remove on remote:
git push origin --delete v0.1
Then re-add locally and push v0.1 to the most recent commit:
git tag -a v0.1
git push origin --tags
Upvotes: 18
Reputation: 11948
If you want to move an annotated tag, changing only the targeted commit but preserving the annotation message and other metadata use:
moveTag() {
local tagName=$1
# Support passing branch/tag names (not just full commit hashes)
local newTarget=$(git rev-parse $2^{commit})
git cat-file -p refs/tags/$tagName |
sed "1 s/^object .*$/object $newTarget/g" |
git hash-object -w --stdin -t tag |
xargs -I {} git update-ref refs/tags/$tagName {}
}
usage: moveTag <tag-to-move> <target>
The above function was developed by referencing teerapap/git-move-annotated-tag.sh.
Upvotes: 1
Reputation: 12942
To sum up if your remote is called origin
and you're working on master
branch:
git tag -d <tagname> # delete the old tag locally
git push origin :refs/tags/<tagname> # delete the old tag remotely
git tag <tagname> <commitId> # make a new tag locally
git push origin <tagname> # push the new local tag to the remote
Description:
You can also change line 4 to git push origin --tags
to push all of your local tag changes/updates to the remote repo.
The above answer is based on content in the question by @eedeep, as well as answers by Stuart Golodetz, Greg Hewgill, and @ben-hocking, and comments below their answers, and @NateS's original comments below my answer.
Upvotes: 436
Reputation: 487
If you use github and want change commit for release (for example you find that don't commit smth after creating release).You can use
git push origin :refs/tags/<tagname>
After this command github delete your tag and your release will become a draft. It means you can recreate release and select commit. Your files and your message will be saved.
Upvotes: 6
Reputation: 4753
I try to avoid a few things when using Git.
Using knowledge of the internals, e.g. refs/tags. I try to use solely the documented Git commands and avoid using things which require knowledge of the internal contents of the .git directory. (That is to say, I treat Git as a Git user and not a Git developer.)
The use of force when not required.
Overdoing things. (Pushing a branch and/or lots of tags, to get one tag where I want it.)
So here is my non-violent solution for changing a tag, both locally and remotely, without knowledge of the Git internals.
I use it when a software fix ultimately has a problem and needs to be updated/re-released.
git tag -d fix123 # delete the old local tag
git push github :fix123 # delete the old remote tag (use for each affected remote)
git tag fix123 790a621265 # create a new local tag
git push github fix123 # push new tag to remote (use for each affected remote)
github
is a sample remote name, fix123
is a sample tag name, and 790a621265
a sample commit.
Upvotes: 99
Reputation: 141
One other way:
Move tag in remote repo.(Replace HEAD with any other if needed.)
$ git push --force origin HEAD:refs/tags/v0.0.1.2
Fetch changes back.
$ git fetch --tags
Upvotes: 14
Reputation: 35054
I'll leave here just another form of this command that suited my needs.
There was a tag v0.0.1.2
that I wanted to move.
$ git tag -f v0.0.1.2 63eff6a
Updated tag 'v0.0.1.2' (was 8078562)
And then:
$ git push --tags --force
Upvotes: 65
Reputation: 1191
Alias to move one tag to a different commit.
In your sample, to move commit with hash e2ea1639 do: git tagm v0.1 e2ea1639
.
For pushed tags, use git tagmp v0.1 e2ea1639
.
Both alias keeps you original date and message. If you use git tag -d
you lost your original message.
Save them on your .gitconfig
file
# Return date of tag. (To use in another alias)
tag-date = "!git show $1 | awk '{ if ($1 == \"Date:\") { print substr($0, index($0,$3)) }}' | tail -2 | head -1 #"
# Show tag message
tag-message = "!git show $1 | awk -v capture=0 '{ if(capture) message=message\"\\n\"$0}; BEGIN {message=\"\"}; { if ($1 == \"Date:\" && length(message)==0 ) {capture=1}; if ($1 == \"commit\" ) {capture=0} }; END { print message }' | sed '$ d' | cat -s #"
### Move tag. Use: git tagm <tagname> <newcommit>
tagm = "!GIT_TAG_MESSAGE=$(git tag-message $1) && GIT_COMMITTER_DATE=$(git tag-date $1) && git tag-message $1 && git tag -d $1 && git tag -a $1 $2 -m \"$GIT_TAG_MESSAGE\" #"
### Move pushed tag. Use: git tagmp <tagname> <newcommit>
tagmp = "!git tagm $1 $2 && git push --delete origin $1 && git push origin $1 #"
Upvotes: 17
Reputation: 3923
More precisely, you have to force the addition of the tag, then push with option --tags and -f:
git tag -f -a <tagname>
git push -f --tags
Upvotes: 356
Reputation: 20616
Delete it with git tag -d <tagname>
and then recreate it on the correct commit.
Upvotes: 105