Ctrl + K
Git19 min read

Git Tags Explained

A practical guide to Git tags, including lightweight and annotated tags, versioning, release workflows, remote tags, common commands, and best practices.

Published: 2026-10-05

Git tags are named references that point to specific Git objects, usually commits. They are commonly used to mark important points in a repository's history, such as software releases, stable versions, milestones, or deployment states.

Unlike branches, tags are normally intended to identify a fixed point in history rather than represent an ongoing line of development. A tag such as v1.0.0 can permanently identify the commit that produced version 1.0.0, making it easier to return to that exact version later.

This guide explains how Git tags work, the difference between lightweight and annotated tags, how to create and manage tags, how tags interact with remote repositories, and how they fit into release and versioning workflows.

What Is a Git Tag?

A Git tag is a reference with a human-readable name that identifies a particular object in a Git repository. In most development workflows, that object is a commit.

v1.0.0
v1.1.0
v2.0.0
release-2026-09

When a tag points to a commit, you can use the tag name instead of remembering the commit hash. This is especially useful for releases because version numbers are easier for humans to understand than hashes.

git show v1.0.0

The command above lets you inspect the commit and related information associated with the tag.

Git Tags vs Git Branches

Tags and branches are both Git references, but they serve different purposes. A branch normally moves forward as new commits are added. A release tag is usually intended to remain associated with the same point in history.

FeatureBranchTag
Primary purposeTrack ongoing developmentMark a specific point in history
Normally moves?YesNo
Typical useFeatures, fixes, developmentReleases, versions, milestones
Examplemainv1.4.0

For example, main may continue receiving commits after version 1.4.0 is released, while the v1.4.0 tag continues to identify the original release commit.

Why Use Git Tags?

Tags provide stable names for important points in repository history. They are particularly useful in software projects where releases need to be reproducible and easy to identify.

  • Mark production releases.
  • Identify specific application or package versions.
  • Create stable references for deployment systems.
  • Make it easy to inspect the source code for an older release.
  • Connect Git history with release notes and changelogs.
  • Identify milestones in long-running projects.
  • Provide stable references for documentation or external integrations.
💡 A release tag should point to the exact commit that represents the source code being released. This makes it much easier to reproduce or investigate that release later.

Lightweight Git Tags

A lightweight tag is a simple named reference to an object. It does not create a separate tag object containing metadata such as a tagger, message, or signature.

git tag v1.0.0

If no commit is specified, Git creates the tag for the commit currently checked out. A specific commit can also be tagged by providing its reference.

git tag v1.0.0 abc1234

Lightweight tags are useful for simple local markers and situations where additional tag metadata is unnecessary.

Annotated Git Tags

An annotated tag is stored as a separate Git object and contains additional metadata. It can include the tag name, tagger information, creation date, message, and optionally a cryptographic signature.

git tag -a v1.0.0 -m "Release version 1.0.0"

Annotated tags are commonly used for releases because they provide more information about why the tag exists and who created it.

CharacteristicLightweight tagAnnotated tag
Separate tag objectNoYes
MessageNoYes
Tagger metadataNo separate tag metadataYes
Can be signedNoYes
Typical release usePossibleCommon

Which Type of Tag Should You Use?

For temporary local markers, lightweight tags may be sufficient. For published software releases, annotated tags are often more appropriate because they can carry release metadata and can be signed.

The most important point is to follow the project's convention. If a repository already uses annotated tags for releases, new releases should normally follow the same approach.

Creating a Git Tag

The simplest way to create a tag is to run git tag with the desired name.

git tag v1.0.0

For an annotated tag, use the -a option and provide a message.

git tag -a v1.0.0 -m "Release version 1.0.0"

By default, the tag points to the currently checked-out commit. If you need to tag another commit, provide its hash or another valid Git reference.

git tag -a v1.0.0 abc1234 -m "Release version 1.0.0"

Creating a Tag for the Latest Commit

When the correct release commit is checked out, you can create a tag without specifying a commit.

git tag -a v2.0.0 -m "Release version 2.0.0"

Before doing this in a release workflow, verify that the working tree and current commit are actually the intended release state.

Tagging a Specific Commit

Git allows you to tag any reachable commit. This is useful when the release commit is known but is not currently checked out.

git log --oneline

git tag -a v1.2.0 abc1234 -m "Release version 1.2.0"

The reference can be a full commit hash, an abbreviated hash, a branch reference, or another Git expression that resolves to the intended commit.

Listing Git Tags

To see the tags available in a local repository, use git tag.

git tag

You can also filter tags using a pattern.

git tag -l "v1.*"
git tag -l "release-*"

Patterns are useful when a repository contains many releases and you want to inspect only a particular version family or naming scheme.

Sorting Git Tags by Version

When tags use semantic versioning, version-aware sorting can make the list easier to read.

git tag --sort=-version:refname

This can be useful for repositories with tags such as v1.8.0, v1.10.0, and v2.0.0, where simple alphabetical sorting does not always produce the desired version order.

Inspecting a Git Tag

The git show command can be used to inspect what a tag points to and, for annotated tags, view the tag metadata and message.

git show v1.0.0

For a compact reference to the commit associated with a tag, rev-parse can be useful.

git rev-parse v1.0.0

This resolves the tag reference to the corresponding object identifier. For annotated tags, additional commands can be useful when you need to distinguish the tag object from the commit it ultimately references.

Pushing a Git Tag to a Remote

Creating a tag locally does not automatically publish it to a remote repository. You need to push the tag explicitly unless your workflow or tooling handles this automatically.

git push origin v1.0.0

To push multiple tags, you can specify several tag names.

git push origin v1.0.0 v1.1.0

Git also provides an option for pushing all local tags.

git push origin --tags
⚠️ Use git push --tags carefully. It publishes all local tags that have not already been pushed, which may include tags you did not intend to publish.

Fetching Tags from a Remote

Tags can also be retrieved from a remote repository. A fetch operation can bring remote tag information into the local repository.

git fetch origin

If you want to fetch tags explicitly, Git provides tag-related options for fetch.

git fetch origin --tags

After fetching, the tags can be listed with git tag.

Deleting a Local Git Tag

A local tag can be removed with git tag -d.

git tag -d v1.0.0

Deleting the local tag does not automatically remove a tag from a remote repository.

Deleting a Remote Git Tag

To remove a tag from a remote repository, push a deletion request to the remote.

git push origin --delete v1.0.0

The same operation can be written using the refspec syntax.

git push origin :refs/tags/v1.0.0
⚠️ Deleting a published release tag can cause problems for users, CI/CD systems, package managers, or documentation that already reference it. Treat published tags as stable references unless there is a clear reason to remove or replace one.

Checking Out a Git Tag

You can check out a tag to inspect the repository exactly as it existed at that point.

git checkout v1.0.0

Modern Git also supports switching directly to a tag with git switch, although checking out a tag leaves you detached from a branch.

git switch --detach v1.0.0

What Is Detached HEAD?

When you check out a tag, HEAD normally points directly to the tagged commit instead of a branch. Git calls this a detached HEAD state.

git status

Detached HEAD is not a problem when you are inspecting, testing, or building an old version. However, if you create commits there and then move away without creating a branch, those commits may become difficult to find.

If you need to continue development from a tagged version, create a branch instead.

git switch -c hotfix-from-v1.0.0 v1.0.0

Git Tags and Semantic Versioning

Git tags are frequently combined with Semantic Versioning, commonly written as MAJOR.MINOR.PATCH. A project might use tags such as v1.0.0, v1.1.0, and v2.0.0 to identify releases.

v1.0.0
v1.1.0
v1.2.0
v2.0.0

The Git tag itself does not determine whether a version follows Semantic Versioning. The project chooses the naming convention. However, using a consistent version format makes releases easier to understand and automate.

Should Git Tags Start with v?

Both v1.0.0 and 1.0.0 are valid tag names. Many projects use the v prefix because it clearly distinguishes a version tag from other references.

StyleExampleComment
With prefixv1.4.0Common and easy to recognize as a version tag
Without prefix1.4.0Also valid and used by many projects
Custom release namerelease-2026-09Useful for non-SemVer milestones

There is no universal requirement to use the v prefix. What matters is choosing a convention and using it consistently.

Pre-release Git Tags

Projects may use version tags for pre-release versions as well. Semantic Versioning supports identifiers such as alpha, beta, and rc.

v2.0.0-alpha.1
v2.0.0-beta.1
v2.0.0-rc.1
v2.0.0

These tags can identify testing or release-candidate versions without confusing them with the final stable release.

Git Tags in Release Workflows

A common release workflow uses a tag to identify the exact commit that is being released. After the feature work and fixes are merged, the project determines the next version, creates a tag, and pushes it to the remote repository.

  • Review the changes included in the release.
  • Run the project's tests and validation checks.
  • Determine the next version according to the project's versioning rules.
  • Create an annotated release tag.
  • Push the tag to the remote repository.
  • Generate or publish release notes.
  • Deploy or publish the tagged version.
git tag -a v1.5.0 -m "Release version 1.5.0"
git push origin v1.5.0

The exact order can vary. Some teams create release notes before tagging, while automated systems may create releases immediately after detecting a pushed tag.

Git Tags and CI/CD

Continuous integration and deployment systems can use tags as release triggers. For example, a CI/CD pipeline may run a production deployment whenever a tag matching a version pattern is pushed.

v1.8.0
v1.9.0
v2.0.0

This approach provides a clear connection between source control and deployment. Instead of deploying an arbitrary branch state, the deployment system can be configured to build the exact commit identified by the release tag.

⚠️ If tags trigger production deployments, protect the release process carefully. An incorrectly created or pushed tag can trigger automation against an unintended commit.

Git Tags and GitHub Releases

Git hosting platforms can build release interfaces around Git tags. A release can reference a tag and provide additional information such as release notes, binaries, or other artifacts.

The tag and the hosting platform's release record are related but are not exactly the same thing. The Git tag is part of the repository's Git references, while a platform release can add metadata and distribution features around that tag.

Git Tags and Changelogs

Tags provide useful boundaries for changelog generation. For example, release tooling can compare the commits between v1.4.0 and v1.5.0 and use those changes to help construct release notes.

git log v1.4.0..v1.5.0 --oneline

When commit messages follow a consistent convention, automated tools can classify changes as features, fixes, documentation updates, performance improvements, or breaking changes.

Comparing Git Tags

Two tags can be compared to determine which commits were added between releases.

git log v1.0.0..v1.1.0 --oneline

You can also compare the actual source changes between two tagged versions.

git diff v1.0.0 v1.1.0

This is useful when investigating what changed between releases or verifying that a release contains the expected modifications.

Finding the Tag That Contains a Commit

Git can show which tags point to or contain a particular commit. One useful command is git tag with the --contains option.

git tag --contains abc1234

This can help determine which releases include a particular change, especially when investigating bugs or verifying whether a fix has reached a released version.

Moving or Replacing a Git Tag

A tag can technically be moved to another commit, but doing so after publishing it is usually undesirable. Developers and automation may already have the original reference.

git tag -f v1.0.0 <commit>

If the tag has already been pushed, updating the remote requires a forced push.

git push origin --force v1.0.0
⚠️ Avoid moving published release tags unless the project has an explicit policy for doing so. Reusing a version tag for different source code can make builds, deployments, caches, and historical references difficult to reproduce.

Signed Git Tags

Annotated tags can be cryptographically signed. Signed tags provide a way to verify that the tag was created by the expected signing identity and that the signed tag object has not been altered.

git tag -s v1.0.0 -m "Release version 1.0.0"

Signing is most useful when a project has a defined trust and key-management process. It should be treated as part of a broader release security workflow rather than as a replacement for access controls.

Tag Naming Best Practices

A consistent naming scheme makes tags easier to discover, sort, automate, and understand.

  • Choose one version naming convention and use it consistently.
  • Use Semantic Versioning when it matches the project's release model.
  • Decide whether version tags use a v prefix.
  • Use annotated tags for important releases when metadata is useful.
  • Avoid changing published release tags.
  • Keep release tags associated with reproducible source states.
  • Document tag naming rules in the project's contribution or release documentation.
  • Protect tags that trigger automated deployments.

Common Git Tag Mistakes

MistakeWhy it causes problemsBetter approach
Creating a tag on the wrong commitThe tag no longer represents the intended releaseVerify the commit before creating the tag
Forgetting to push the tagThe release exists only locallyPush the intended tag explicitly
Using inconsistent namesSearching and automation become harderDocument and follow one naming convention
Moving a published tagExisting references may point to different source codeTreat published tags as stable
Deleting release tags casuallyBuilds and external references may breakAvoid deleting published tags without a clear reason
Using --tags without checking local tagsUnintended tags may be publishedPush specific tags when possible
Creating commits from a tag without a branchCommits may be created in detached HEADCreate a branch when continuing development

A Practical Git Tag Release Workflow

A simple release process can combine Git tags, semantic versions, consistent commit messages, and automated release notes.

git status
git log --oneline -10
git tag --sort=-version:refname

git tag -a v1.5.0 -m "Release version 1.5.0"
git show v1.5.0
git push origin v1.5.0

The exact commands depend on the project, but the important principle is to verify the release state before creating and publishing the tag.

Git Tags in Monorepos

Monorepos can require more detailed tagging strategies because a single repository may contain several applications or packages. A project might tag the entire repository for a coordinated release or use package-specific tag naming conventions.

web-v2.1.0
api-v2.1.0
shared-v1.8.0

The correct approach depends on how the repository builds and releases its individual packages. The naming scheme should make it clear which component a tag belongs to.

Git Tags for Hotfixes

Tags are also useful for documenting hotfix releases. For example, if version 2.1.0 contains a production bug and the project releases a patch, the next version might be tagged v2.1.1.

v2.1.0
v2.1.1

The patch tag gives the team a stable reference for the exact source code that contains the fix.

Useful Git Tag Commands

CommandPurpose
git tagList local tags
git tag v1.0.0Create a lightweight tag
git tag -a v1.0.0 -m "Release version 1.0.0"Create an annotated tag
git show v1.0.0Inspect a tag
git tag -d v1.0.0Delete a local tag
git push origin v1.0.0Push one tag
git push origin --tagsPush all local tags not on the remote
git push origin --delete v1.0.0Delete a remote tag
git fetch origin --tagsFetch tags from a remote
git tag --contains <commit>Find tags containing a commit
git diff v1.0.0 v1.1.0Compare two tagged versions

Git Tags and Commit Messages

Tags identify important points in history, while commit messages explain the individual changes that led to those points. Together, they provide a useful release history.

For example, a release tag such as v2.0.0 can identify the final release commit, while the commits between v1.5.0 and v2.0.0 explain the features, fixes, refactors, and breaking changes introduced during development.

This becomes especially powerful when commit messages follow a predictable convention. Release tooling can use the tagged boundaries and structured commit history to produce more useful release notes.

Git Tags and Reproducible Releases

A tag provides a stable reference to source code, but a completely reproducible build can depend on more than the Git commit alone. Dependency versions, build configuration, generated files, external services, and the build environment can also affect the resulting artifact.

For this reason, tags should be considered one important part of release reproducibility rather than the entire solution. Projects that require highly reproducible builds should also manage dependencies and build environments carefully.

Helpful Git Release Tools

Versioning and release workflows can be supported by several categories of developer tools. A semantic version calculator can help determine the next version from a release type. Release notes and changelog generators can turn structured project history into release documentation.

Git commit generators and Conventional Commit generators can help create consistent commit messages, which in turn makes automated release workflows easier to maintain.

What is a Git tag?

A Git tag is a named reference to a Git object, most commonly a commit. Tags are frequently used to mark releases, versions, milestones, and other important points in repository history.

What is the difference between a Git tag and a branch?

A branch normally moves as new commits are added, while a tag is generally used to identify a fixed point in repository history. For example, main can continue to change after v1.0.0 has been created.

What is the difference between lightweight and annotated tags?

A lightweight tag is a simple reference, while an annotated tag is a separate Git object containing metadata such as a tagger, date, message, and optional signature. Annotated tags are commonly used for releases.

How do I push a Git tag to GitHub or another remote?

Create the tag locally and push it explicitly with a command such as git push origin v1.0.0. You can also push multiple tags or use --tags when you intentionally want to publish all relevant local tags.

Can I delete a Git tag?

Yes. git tag -d removes a local tag, while git push origin --delete <tag> removes a tag from a remote. Published release tags should generally not be deleted without a clear reason because other systems may depend on them.

Should Git tags use semantic versioning?

They do not have to, but Semantic Versioning is a common choice for software releases because it provides a predictable MAJOR.MINOR.PATCH format. The project should choose and consistently document its versioning convention.

Can a Git tag be moved to another commit?

Yes, Git technically allows tags to be replaced or force-pushed to another commit. However, moving a published release tag can make historical references and automated builds inconsistent, so published tags are usually treated as immutable.

Conclusion

Git tags provide stable, human-readable references to important points in a repository's history. They are especially useful for software releases because a version such as v1.5.0 is easier to identify and reuse than a raw commit hash.

For important releases, annotated tags provide useful metadata and can also be signed. A consistent naming convention, careful release verification, and explicit tag publishing help keep release history predictable.

When Git tags are combined with semantic versioning, structured commit messages, changelogs, release notes, and CI/CD automation, they become an important part of a reliable software release workflow.

Found an issue?

Found an error, outdated information, or something missing from this article? Let me know through the Contact page.

Your feedback helps improve our articles and keep them accurate and useful.