Git
version control
commit
tags
software development

How to list all tags that contain a commit?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

To list every tag whose history includes a given commit, Git already has a built-in answer: git tag --contains. That command is useful when you want to know which releases include a bug fix, when a feature first shipped, or whether a cherry-picked change made it into a tagged version.

The Main Command

The normal syntax is:

bash
git tag --contains <commit>

Example:

bash
git tag --contains 8f3d7a2

Git prints all local tags that point to the commit directly or to a descendant commit that includes it in history.

If you omit the commit, Git uses HEAD:

bash
git tag --contains

That means "show me the tags whose history contains my current commit."

What "Contains" Means

This part matters. The command does not mean "tags created on exactly this commit." It means "tags whose tagged commit is reachable from the given commit in history."

Suppose:

  • commit A is a bug fix
  • commit B comes later on the same branch
  • tag v1.2.0 points at B

Then git tag --contains A includes v1.2.0, because the tagged release contains the fix.

If you need only tags that point exactly to one commit, use:

bash
git tag --points-at <commit>

That is a different question from historical containment.

Example Workflow

A common workflow is:

bash
git log --oneline
git tag --contains 8f3d7a2

Or, if you already know the commit from git blame or a ticket:

bash
git tag --contains a1b2c3d4

This is especially useful in release support work when you need to answer, "Which tagged versions include this change?"

Sorting and Filtering the Results

You can sort tags in a more human-friendly way:

bash
git tag --contains 8f3d7a2 --sort=version:refname

If your repository uses version-like tag names such as v1.9.0 and v1.10.0, that sort order is easier to read than plain lexicographic sorting.

You can also filter by a naming pattern:

bash
git tag --contains 8f3d7a2 --list 'v2.*'

That is useful when your repo has different families of tags, such as release tags, test tags, or deployment tags.

Fetch Remote Tags First

git tag --contains only sees tags that exist in your local repository. If teammates or CI systems created tags remotely, fetch them first:

bash
git fetch --tags
git tag --contains 8f3d7a2

Without that step, the command may appear to show "no tags" simply because your local clone has incomplete tag information.

Scripting and Automation Use

Because the command prints one tag per line, it is easy to use in shell scripts:

bash
for tag in $(git tag --contains 8f3d7a2); do
  echo "Found in $tag"
done

That can help in release pipelines or support tooling. Just remember that shell loops like this are safest when tag names follow simple conventions.

Common Pitfalls

The most common mistake is confusing --contains with --points-at. The first checks ancestry, while the second checks whether the tag points exactly to the commit.

Another issue is forgetting to fetch tags. Local clones do not always have every remote tag, so the result can look incomplete.

Developers also misread the output when merge history is involved. A tag may contain a commit through a merge even if the commit did not originate on the main release branch.

Finally, do not confuse tags with branches. If you want branch containment, the related command is git branch --contains <commit>, not git tag --contains <commit>.

Summary

  • Use git tag --contains <commit> to list tags whose history includes a commit.
  • Use git tag --points-at <commit> if you need only exact tag targets.
  • Fetch remote tags first with git fetch --tags when needed.
  • Sorting and --list filtering make the output easier to interpret.
  • The command is most useful for release tracking and verifying whether a fix shipped.

Course illustration
Course illustration

All Rights Reserved.