What Is a Git Tag? Marking Releases and Versions, Explained

  • VersionDude
  • guides
  • 7 min read

A git tag is a named reference that points to a specific commit, used above all to mark releases and versions. Lightweight versus annotated tags, how they differ from branches, and how to create and push them.

A git tag is a named reference that points to a specific commit in a repository. Where a commit is identified by a long hash that is hard to remember, a tag gives that exact point in history a short, human-readable name. Tags are most commonly used to mark release points, so that a name like v1.0.0 refers to the precise state of the code that was shipped as that version.

The key difference between a tag and a branch is that a tag does not move. A branch is a pointer that advances every time you add a new commit to it, always tracking the latest work. A tag is fixed: once you attach it to a commit, it keeps pointing at that same commit even as development continues past it. This is exactly what you want for a release, because the meaning of v1.0.0 should never change after it is published.

Lightweight versus annotated tags

Syntax-highlighted source code with a motion-blur effect.
Syntax-highlighted source code with a motion-blur effect.

Git supports two kinds of tags: lightweight tags and annotated tags. A lightweight tag is little more than a name pointing directly at a commit, with no extra information stored alongside it. It is quick to create and works well as a private bookmark, but it carries no record of who created it or why.

An annotated tag is stored as a full object in the Git database. It records the name of the person who created the tag, the date it was made, and a tagging message, in much the same way a commit records its author and message. Annotated tags can also be signed with GPG, which lets others verify that a release tag genuinely came from you. For public releases, annotated tags are generally the recommended choice because of this extra metadata and the ability to sign them.

Creating and pushing tags

Creating tags is straightforward. Running git tag with a name and no other options creates a lightweight tag on the current commit. Adding the -a flag, as in git tag -a v1.0.0 -m "Release 1.0.0", creates an annotated tag with a message. You can also tag an older commit by passing its hash at the end of the command, which is useful when you realise after the fact that a particular commit was the real release point.

  • A tag names a specific commit; unlike a branch, it never moves once set.
  • Lightweight tag: just a name pointing at a commit, with no extra metadata.
  • Annotated tag: a full object storing author, date, and message, and can be GPG-signed.
  • Create with git tag v1.0.0 (lightweight) or git tag -a v1.0.0 -m "..." (annotated).
  • Tags are not pushed by default: send them with git push origin <tag> or git push --tags.
  • Tags mark releases, often as SemVer vX.Y.Z, and commonly trigger CI/CD and release pages.

One point that surprises newcomers is that tags are not shared automatically. When you run git push, your branches are updated on the remote, but your tags stay local unless you send them explicitly. You push a single tag with git push origin followed by the tag name, or send all of your tags at once with git push --tags. Forgetting this step is a common reason a release tag appears on a developer machine but is missing from the shared repository.

Tags, versioning, and release automation

Tags fit naturally into a versioning scheme. Many projects follow Semantic Versioning, where a version has the shape MAJOR.MINOR.PATCH, and each release is captured as a matching tag such as v2.4.1. Because the tag is immutable, anyone can later check out that exact tag and rebuild the code as it stood for that version, which is the foundation of reproducible releases.

Tags also power a great deal of automation. Continuous integration and deployment pipelines are frequently configured to trigger when a new tag is pushed, so that tagging a commit as v1.2.0 automatically builds, tests, and publishes that version. Platforms that host repositories often turn tags into release pages, attaching notes and downloadable artifacts to each tagged version. In this way a small, immutable pointer becomes the anchor for an entire release process.

Working with tags safely

Because a tag is just a reference, it is cheap and safe to work with. Listing tags, inspecting what an annotated tag says, or checking out the code at a given tag are all read-only operations that do not disturb your ongoing work. Deleting a tag locally is also simple, though deleting one that has already been pushed and used by others should be done with care, since people and pipelines may already depend on it.

Because a tag is just a reference, it is cheap and safe to work with. Listing tags, inspecting what an annotated tag says, or checking out the code at a given tag are all read-only operations that do not disturb your ongoing work. Deleting a tag locally is also simple, though deleting one that has already been pushed and used by others should be done with care, since people and pipelines may already depend on it.

- VersionDude

Summary

In short, a git tag is a stable label on a moment in your project's history. Lightweight tags are quick personal markers, while annotated tags carry authorship, a message, and optional signatures that make them suited to public releases. Combined with a versioning scheme and pushed to the shared remote, tags turn an unmemorable commit hash into a durable, verifiable reference for a specific version of your software.

Related project