Git Tag Pointing to Wrong Commit, How to Fix
A tag pointing to the wrong commit is straightforward to fix locally, but since tags are often used to mark specific releases that others may already rely on, moving a tag that's already been pushed and used requires extra care to avoid confusing anyone who already has the old reference.
The Problem
A tag — often marking a release, like v1.2.0 — was created pointing at the wrong commit, either due to a mistake at creation time or because it was created before a final fix was actually committed:
git show v1.2.0
commit a1b2c3d (wrong - this is missing the final fix)
The tag needs to point at a different, correct commit instead.
Why It Happens
Unlike branches, tags are meant to be fixed, permanent references to a specific point in history — Git doesn't automatically move them, and creating one at the wrong moment (before a final commit that should have been included, or against the wrong branch entirely) is the most common cause. This usually happens from:
- Tagging a commit before realizing a critical fix still needed to be included in that release
- Tagging the wrong branch or commit due to being in an unexpected checkout state at the time
- A release automation script tagging based on incorrect logic, picking up an earlier commit than the intended final one
The Fix
To move a tag locally to point at the correct commit, delete the existing tag and recreate it at the right location:
git tag -d v1.2.0
git tag v1.2.0 <correct-commit-hash>
If you want the tag to point at your current HEAD rather than a specific hash you look up separately:
git tag -d v1.2.0
git tag v1.2.0
If this tag has already been pushed to a remote repository, deleting and recreating it locally isn't enough — the remote still has the old reference, and you need to explicitly update it there as well:
git push origin :refs/tags/v1.2.0
git push origin v1.2.0
The first command deletes the tag from the remote (the colon before the ref path signals deletion), and the second pushes the newly recreated local tag to replace it.
Alternatively, a single command combining both delete and push in one step:
git push origin v1.2.0 --force
Be aware this is genuinely disruptive if anyone else has already fetched the old tag — their local copy of the tag still points to the old commit until they explicitly re-fetch it, and Git doesn't automatically warn them that the tag moved. If this is a public release tag that others may have already built against, moving it can cause confusion or inconsistency between different people's local references to what should be the "same" release.
For any tag that's already been publicly released or widely distributed, the safer practice is creating a new tag (like v1.2.1) with the correct commit, rather than moving the existing one — this avoids any ambiguity about what a given tag name actually points to for anyone who already has a reference to the old one.
Still Not Working?
If other people on your team have already pulled the old (incorrect) tag and their local repository still shows the wrong commit even after you've moved it on the remote, they need to explicitly force their local tag to update, since Git doesn't automatically overwrite a tag someone already has locally just because the remote version changed:
git fetch origin --prune-tags
git tag -d v1.2.0
git fetch origin tag v1.2.0
This ensures they discard their stale local tag reference and pull the corrected one fresh from the remote, rather than continuing to work against the outdated commit their local Git thinks the tag still points to.