Lesson 24 of 6820 min read

Tagging: git tag, Annotated vs Lightweight Tags, Listing and Pushing

Learn how to mark specific commits as meaningful release points using Git tags, the difference between annotated and lightweight tags, and how to share them.

Author: CodersNexus

Tagging: git tag, Annotated vs Lightweight Tags, Listing and Pushing

As a project matures, certain commits become especially significant — they represent an official release, like v1.0.0 or v2.3.1. Rather than remembering a specific commit hash for these milestones, Git provides tags: permanent, human-readable labels attached to a specific commit. This lesson covers how to create both types of tags Git supports, when to use each, and how to share tags with a remote repository.

Learning Objectives

  • Create lightweight tags using git tag <name>.
  • Create annotated tags using git tag -a <name> -m "message".
  • Explain the practical differences between annotated and lightweight tags.
  • List existing tags and push them to a remote repository.

Key Terms to Know Before Learning Tagging

  • Tag: A named reference that points permanently to a specific commit, typically used to mark release points such as v1.0.0.
  • Lightweight tag: A tag that is simply a named pointer to a commit, with no additional metadata of its own.
  • Annotated tag: A tag stored as a full Git object, including a tagger name, email, date, and message — similar in structure to a commit.
  • git push --tags: A command that pushes all local tags to a remote repository, since tags are not pushed automatically by a plain git push.

How Tagging Actually Works

A **lightweight tag** is the simplest form — just a name pointing directly at a specific commit, with no additional information stored:

```
git tag v1.0.0
```

This tags the current commit (HEAD) as `v1.0.0`. You can also tag a specific past commit by supplying its hash:

```
git tag v0.9.0-beta a1b2c3d
```

An **annotated tag** is the recommended approach for anything meant to represent an actual, official release. It's created with `-a`, and stores a full Git object containing a tagger name and email, the date it was created, and a message — much like a commit:

```
git tag -a v1.0.0 -m "Release version 1.0.0: initial public launch"
```

The practical differences matter: because annotated tags are full objects with their own metadata, they show up with complete detail when using `git show v1.0.0` (displaying the tag's message, tagger, and date, followed by the commit itself), whereas a lightweight tag with `git show` shows only the underlying commit, with no separate tag metadata to display. Annotated tags are also what's expected and recommended by Git's own documentation for public releases, since they carry a permanent record of who created the tag and why — lightweight tags are better suited for quick, private, temporary bookmarks (like marking your own local point of reference) rather than official releases.

To see all tags in a repository:

```
git tag
```

A critical detail beginners frequently miss: **tags are not included in a plain `git push`.** Because they're a separate type of reference from branches, you must explicitly push them:

```
git push origin v1.0.0 # push one specific tag
git push --tags # push ALL local tags at once
```

Without this extra step, you might create a perfectly good release tag locally, only to find that it never actually reached the remote repository (and therefore isn't visible to collaborators or reflected on platforms like GitHub's 'Releases' page) until you explicitly push it.

Tagging: Visual Walkthrough

Draw a commit history timeline with five commit dots. Above the third dot, attach a small flag icon labeled 'v0.9.0-beta (lightweight)'. Above the fifth (most recent) dot, attach a larger, more detailed flag icon labeled 'v1.0.0 (annotated) — Tagger: Asha Mehta, Date: 2026-07-01, Message: Initial public launch'. Add a side note: 'Remember: git push alone does NOT send tags — use git push --tags or git push origin <tagname>.'

Lightweight Tag vs Annotated Tag: Side-by-Side Comparison

AspectLightweight TagAnnotated Tag
Commandgit tag <name>git tag -a <name> -m "message"
Stored asSimple pointer to a commitFull Git object with its own metadata
Includes tagger name/email/date/message?NoYes
Recommended forQuick, private, temporary bookmarksOfficial releases (e.g., v1.0.0)
Pushed automatically with git push?No — requires explicit pushNo — requires explicit push

Tagging: Command Syntax and Examples

# Create a lightweight tag on the current commit
git tag v0.9.0-beta

# Create an annotated tag (recommended for real releases)
git tag -a v1.0.0 -m "Release version 1.0.0: initial public launch"

# Tag a specific past commit (not the current HEAD)
git tag -a v0.5.0 a1b2c3d -m "Internal preview release"

# List all tags
git tag

# View detailed info for an annotated tag
git show v1.0.0

# Push a single tag to the remote
git push origin v1.0.0

# Push ALL local tags to the remote at once
git push --tags

Breaking Down the Tagging Example

The lightweight tag `v0.9.0-beta` is created with the simple `git tag <name>` form, storing no additional metadata beyond the pointer itself. The annotated tag `v1.0.0` includes a message via `-a` and `-m`, storing complete tagger information much like a commit does — running `git show v1.0.0` afterward would display this tagger metadata before showing the tagged commit's own details, unlike a lightweight tag. `git tag -a v0.5.0 a1b2c3d -m "..."` demonstrates tagging a specific past commit rather than the current HEAD. Finally, both push examples emphasize that tags require an explicit push — either one at a time (`git push origin v1.0.0`) or all together (`git push --tags`) — since they are never included automatically in a plain `git push`.

How Tagging Is Used on Real Engineering Teams

  • Nearly every software project follows Semantic Versioning (semver) conventions for tags — v1.0.0, v1.1.0, v2.0.0 — with annotated tags marking each official release on GitHub, GitLab, or similar platforms.
  • GitHub's 'Releases' feature is built directly on top of Git tags — creating a GitHub Release effectively creates (or attaches additional notes to) an annotated tag on a specific commit.
  • CI/CD pipelines are frequently configured to automatically trigger a production deployment whenever a new tag matching a pattern like v*.*.* is pushed to the repository.
  • Open-source maintainers commonly use annotated tags with detailed messages summarizing what changed in each release, making git show <tag> a quick way to review a release's key context directly from the command line.

Tagging Interview Questions and Answers

Q1. What is the difference between a lightweight tag and an annotated tag?

A lightweight tag is simply a named pointer to a specific commit, storing no additional information. An annotated tag is a full Git object that includes a tagger name and email, creation date, and a message, similar in structure to a commit. Annotated tags are recommended for official releases, while lightweight tags suit quick, private bookmarks.

Q2. How do you push a tag to a remote repository, and why is this step necessary?

Use git push origin <tagname> to push a single tag, or git push --tags to push all local tags at once. This is necessary because tags are a separate type of reference from branches and are not included automatically in a plain git push — without an explicit push, a tag remains purely local.

Q3. How would you tag a specific past commit, rather than the current HEAD?

Supply the commit's hash after the tag name, for example: git tag -a v0.5.0 a1b2c3d -m "message". This creates an annotated tag pointing at that specific commit rather than your currently checked-out commit.

Tagging Quiz: Test Your Understanding

1. Which command creates an annotated tag with a message?

  1. git tag v1.0.0
  2. git tag -a v1.0.0 -m "message"
  3. git tag --light v1.0.0
  4. git commit --tag v1.0.0

Answer: B. git tag -a v1.0.0 -m "message"

Explanation: The -a flag combined with -m creates an annotated tag, storing a full Git object with tagger metadata and the provided message.

2. What is a key difference between lightweight and annotated tags?

  1. Lightweight tags cannot be pushed to a remote
  2. Annotated tags store tagger name, date, and message; lightweight tags are just a pointer
  3. Annotated tags can only be created on the most recent commit
  4. Lightweight tags automatically expire after 30 days

Answer: B. Annotated tags store tagger name, date, and message; lightweight tags are just a pointer

Explanation: Annotated tags are full Git objects containing metadata like tagger information and a message, while lightweight tags are simply a name pointing to a commit with no extra data.

3. Which command pushes ALL local tags to a remote repository at once?

  1. git push
  2. git push --all-tags
  3. git push --tags
  4. git tag --push

Answer: C. git push --tags

Explanation: git push --tags sends every local tag to the remote repository in one command, since a plain git push does not include tags by default.

Tagging: Common Mistakes Beginners Make

  • Assuming a plain git push automatically sends tags to the remote — it does not; git push --tags or git push origin <tagname> is required.
  • Using lightweight tags for official releases, missing out on the valuable tagger, date, and message metadata that annotated tags provide.
  • Forgetting to specify a commit hash when trying to tag something other than the current HEAD, accidentally tagging the wrong commit.
  • Confusing tags with branches — tags are meant to be permanent, fixed markers for a specific commit, not something meant to move forward like a branch.

Tagging: Exam-Ready Quick Notes

  • Lightweight tag: git tag <name> — just a pointer, no metadata.
  • Annotated tag: git tag -a <name> -m "message" — full object with tagger, date, message.
  • git tag: lists all tags. git show <tag>: shows tag details (and commit, for annotated tags).
  • Tags require explicit push: git push origin <tag> or git push --tags.

Tagging: Key Takeaways

  • Tags provide permanent, human-readable labels for significant commits, most commonly used to mark official software releases.
  • Annotated tags carry meaningful metadata (tagger, date, message) and are the recommended choice for real releases; lightweight tags suit quick personal bookmarks.
  • Tags must be explicitly pushed to a remote — they are never included automatically as part of a regular git push.

Frequently Asked Questions About Tagging

Q1. What is a Git tag used for?

A tag is a permanent, human-readable label attached to a specific commit, most commonly used to mark official release points in a project's history, such as v1.0.0.

Q2. What is the difference between an annotated and a lightweight tag?

A lightweight tag is just a simple pointer to a commit with no extra information. An annotated tag is a full object that also stores a tagger's name, email, creation date, and a message — making it the recommended choice for official releases.

Q3. How do I see all the tags in my repository?

Run git tag with no arguments to list every tag that currently exists in your local repository.

Q4. Why doesn't my tag show up on the remote repository after I push my commits?

Because a plain git push does not send tags automatically — they're a separate type of reference. You need to explicitly push them using git push origin <tagname> for one tag, or git push --tags to send all of them at once.

Q5. Can I create a tag for a commit that isn't my current HEAD?

Yes. Provide the commit's hash after the tag name, for example git tag -a v0.5.0 a1b2c3d -m "message", which tags that specific commit rather than whatever you currently have checked out.

Summary

Git tags create permanent, named references to specific commits, most commonly used to mark official release points like `v1.0.0`. Lightweight tags (`git tag <name>`) are simple pointers with no additional data, while annotated tags (`git tag -a <name> -m "message"`) are full Git objects storing a tagger's name, email, date, and message — the recommended approach for real releases. Existing tags can be listed with `git tag` and inspected with `git show <tag>`. Crucially, tags are never pushed automatically as part of a plain `git push` — they require an explicit `git push origin <tagname>` or `git push --tags` to reach a remote repository.

Frequently Asked Questions

A tag is a permanent, human-readable label attached to a specific commit, most commonly used to mark official release points in a project's history, such as v1.0.0.

A lightweight tag is just a simple pointer to a commit with no extra information. An annotated tag is a full object that also stores a tagger's name, email, creation date, and a message — making it the recommended choice for official releases.

Run git tag with no arguments to list every tag that currently exists in your local repository.

Because a plain git push does not send tags automatically — they're a separate type of reference. You need to explicitly push them using git push origin <tagname> for one tag, or git push --tags to send all of them at once.

Yes. Provide the commit's hash after the tag name, for example git tag -a v0.5.0 a1b2c3d -m "message", which tags that specific commit rather than whatever you currently have checked out.