How can I move a tag on a git branch to a different commit?

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?

0

10 Answers

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.

Example

  1. Delete the tag on any remote before you push

    git push origin :refs/tags/<tagname> 
  2. Replace the tag to reference the most recent commit

    git tag -fa <tagname> 
  3. Push the tag to the remote origin

    git push origin master --tags 
16

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 
1

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:

  • Line 1 removes the tag in local env.
  • Line 2 removes the tag in remote env.
  • Line 3 adds the tag to different commit
  • Line 4 pushes the change to the remote

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.

1

Delete it with git tag -d <tagname> and then recreate it on the correct commit.

4

I try to avoid a few things when using Git.

  1. 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.)

  2. The use of force when not required.

  3. 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.

2

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 
0

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 #" 

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 
1

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.

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.

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like