Your copy of the tag stays pointing at the old commit. Git does not change tags behind your back, so you and the maintainer can hold different code under the same version name. To be sure what you build, record and pin the commit hash, not just the tag.
What the git manual says
The git-tag documentation has a section on re-tagging. If someone tagged the wrong commit and has not pushed anything, they can simply re-tag with the force option. If they have pushed, others will already have seen the old tag, and the manual gives two choices.
The sane one is to admit the mistake and use a different name, for example the next patch number. The manual points out that if the same name is kept, you may end up with two people who both have "version X" while having different "X"s.
The other one is to force the tag again anyway. The manual says that git does not, and should not, change tags behind users' backs, so people who already fetched the old tag keep it unless they take action.
Why this matters for your supply chain
If a build pipeline fetches a tag once and caches it, a later move of that tag will not reach the cache. If a fresh machine fetches the tag after the move, it gets different code. Two environments then build "the same version" from different source. That is hard to debug and, in a hostile case, a way to slip changed code under a trusted name.
Mutable names are a recurring pattern in supply chain trouble. Related reading: pin GitHub Actions to a commit SHA after tag repointing.
What to do as a consumer
- Record the commit hash next to the version in your lockfile, build notes or deployment record.
- Pin dependencies fetched from git by commit where the tool allows it.
- Compare what the tag points to now against your record.
git rev-parse v2.4.0^{commit}
git ls-remote --tags origin v2.4.0
If the remote hash differs from what you recorded, stop and ask why.
- Refetch tags deliberately only when you intend to take a changed tag.
What to do as a maintainer
- Never move a published release tag. Ship a new version.
- Protect release tags so only a few people can change them.
- Say in the release notes if a release was withdrawn and which version replaces it.
Tag behaviour at a glance
| Situation | Result |
|---|---|
| Tag moved before anyone fetched it | Fine, nobody saw the old one |
| Tag moved after publishing | Fetched copies keep the old target |
| New name used instead | Everyone converges on the new version |
A small example
Two developers pull tag v2.4.0 on Monday. On Tuesday the maintainer force pushes the tag to a different commit. The developer who pulls on Wednesday gets the new target, while the one who pulled on Monday still has the old one. Both run builds called v2.4.0 and the results differ. Neither did anything wrong, which is the point: the name stopped identifying a single thing.
Quick check
Can I trust a tag name as an identifier?
Only as a convenience. A commit hash identifies content. A tag is a movable label unless the host enforces immutability.
How do I notice a moved tag?
Compare the hash the remote reports with the hash you recorded when you first built. A difference means the tag now points somewhere else.
Sources
Last reviewed: 19 October 2026.