Move a Git Tag

Janne Kemppainen |

Normally when you create a Git tag you should just let it be and not alter the history after the fact. But if you really need to move a tag forward how can it be done?

Now, before you go ahead and start moving tags check these notes about re-tagging and make sure you understand the implications.

Moving an existing tag

Let’s assume that you have just created a commit that you want to tag with v1 , but that tag already exists in the repository. When you attempt to call the git tag command you will get an error message:

>> git tag v1
fatal: tag 'v1' already exists

But don’t worry! Like with many other commands in Git you can just force your way through the problem with the --force flag:

>> git tag --force v1
Updated tag 'v1' (was 6a996f7)

Now that your tag has been moved it needs to be pushed to the remote. Tags need to be pushed explicitly, so they won’t be included in your normal git push. The way to push a tag called v1 doesn’t really differ from pushing a branch:

>> git push origin v1
To github.com:jannekem/gittest.git
 ! [rejected]        v1 -> v1 (already exists)
error: failed to push some refs to '[email protected]:jannekem/gittest.git'
hint: Updates were rejected because the tag already exists in the remote.

Well, it got rejected since my remote repository already had that tag. We need to use the Force!

>> git push origin v1 --force

This works and the tag is now updated on the server, pointing to the tagged commit.

Strange things will happen if you accidentally push the tag but forget to push the branch. The tag and its commit will appear on the remote but it can’t point to the correct branch because the commit does not exist in that context yet. For example GitHub will warn you with this message when you try to view the commit:

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Here is an alternative way to force push git tags:

>> git push --tags --force

Note that this will force push all your local tags, which might be unwanted.

Pulling after a tag has been edited

What if someone else has moved a tag on the remote server but you sill have the old one on the local repository? Then you need to delete local tag first, before pulling from the remote.

>> git tag -d v1
Deleted tag 'v1' (was 8b7f222)
>> git pull
From github.com:jannekem/gittest
 * [new tag]         v1         -> v1
Already up to date.

You can also force fetch tags, overwriting your local ones:

>> git fetch --tags --force
From github.com:jannekem/gittest
 t [tag update]      v1         -> v1

All tags on the remote will now be available on your local repository.

Why would you want to move a tag in the first place?

Moving tags around can cause all sorts of problems but in some cases you may just need to go with it. One case where this practice is used is GitHub’s own continuous integration platform, GitHub Actions.

Users can create custom actions that are distributed via Git repositories. When you want to use a certain version of an action you define it with the repo and a reference, for example actions/checkout@v2.

The reference can be a branch, commit, or a tag, but tags are commonly used for this purpose. When a new release is made it can be tagged with a semantic version such as v1.4.3, and the major tag v1 can then be moved ahead to point to the same commit. This way the users of the action will automatically use the latest available release of a major version next time they run their workflows.

If you’d like to automatically maintain a latest tag in your repo that always points to the latest release you could use the Latest tag action. The Update Major Version action looks for a semantic version when you push a tag, and it automatically moves the matching major version ahead.

Discuss on Twitter

Subscribe to my newsletter

What’s new with PäksTech? Subscribe to receive occasional emails where I will sum up stuff that has happened at the blog and what may be coming next.

powered by TinyLetter | Privacy Policy