The Hook (The "Byte-Sized" Intro)
Git has two types of tags, and using the wrong one is like signing an important contract in pencil. Lightweight tags are quick, anonymous labels — fine for personal notes. Annotated tags are official stamps with your name, the date, and a description. For anything teammates or CI will see, always go annotated.
📖 What is Annotated vs Lightweight Tags?
This lesson compares the two tag types side-by-side so you always choose the right one.
Conceptual Clarity
Side-by-side comparison:
| Feature | Lightweight | Annotated |
|---|---|---|
| Git object type | None (just a ref file) | Tag object |
Stored in .git/refs/tags/ | ✅ Name → commit SHA | ✅ Name → tag object SHA |
| Tagger info | ❌ | ✅ Name, email |
| Timestamp | ❌ Only the commit's | ✅ Tag creation time |
| Message | ❌ | ✅ Required |
| GPG signable | ❌ | ✅ |
Shows in git describe | ❌ Skipped by default | ✅ Included |
| Recommended for releases | ❌ | ✅ |
Internal difference:
- Lightweight:
.git/refs/tags/v1.0contains the commit SHA directly - Annotated:
.git/refs/tags/v1.0points to a tag object, which points to the commit
Real-Life Analogy
- Lightweight = Writing "v1.0" on a sticky note and placing it on a page
- Annotated = Stamping "v1.0" with a notary seal: name, date, signature, official record
Visual Architecture
Why It Matters
git describe: Only finds annotated tags by default — critical for version tooling.- Audit trail: Annotated tags answer "who tagged this and when?"
- CI/CD: Many pipelines differentiate between tag types.
- Convention: Open-source projects almost universally use annotated tags.
Code
# ─── Create both types ───
git tag v1.0-light # Lightweight
git tag -a v1.0-annotated -m "Official release" # Annotated
# ─── See the difference ───
git show v1.0-light
# Shows the commit directly
git show v1.0-annotated
# Shows: tag v1.0-annotated
# Tagger: Jane Doe <jane@example.com>
# Date: Thu Feb 13 22:30:00 2026 +0530
# Official release
# (then the commit details)
# ─── git describe behavior ───
git describe
# v1.0-annotated-2-g1a2b3c4 ← Uses annotated tag
# Lightweight tags are SKIPPED by default!
git describe --tags
# Now includes lightweight tags too
# ─── Check tag type ───
git cat-file -t v1.0-light # commit (lightweight)
git cat-file -t v1.0-annotated # tag (annotated object)Key Takeaways
- Annotated tags are full Git objects with metadata — use for all public/release tags.
- Lightweight tags are simple pointers — use for quick personal bookmarks.
git describeonly sees annotated tags by default — this affects version tooling.- When in doubt, use annotated.
Interview Prep
-
Q: How can you tell if a tag is lightweight or annotated? A: Run
git cat-file -t <tag>. If it returnscommit, it's lightweight (points directly to the commit). If it returnstag, it's annotated (points to a tag object). You can also usegit show <tag>— annotated tags show tagger info and message before the commit. -
Q: Why does
git describeskip lightweight tags? A:git describeis designed to find version identifiers, which should be deliberate, annotated tags. Lightweight tags are more casual and may not represent official versions. Usegit describe --tagsto include them. -
Q: What does the internal structure of an annotated tag look like? A: An annotated tag is a Git object containing: the object it points to (usually a commit SHA), the object type, the tag name, the tagger's name and email, a timestamp, and a message. It's stored as a separate object in
.git/objects/.