Tags, Signed Releases, Semantic Versioning, Changelogs, and Support Lines: Concepts, Architecture, and Mental Model
Understand Git release identifiers from first principles: lightweight and annotated tags, tag objects and peeling, signing evidence, Semantic Versioning, changelogs, immutable published names, and parallel support histories.
Learning objectives
- Distinguish lightweight tag refs from annotated tag objects and peeled release targets.
- Explain what a cryptographic tag signature proves and what organizational trust still must define.
- Separate Semantic Versioning and changelog conventions from core Git mechanics.
- Model published version tags as immutable operational source identifiers.
- Explain how support branches and backports create parallel release histories.
1. A release needs a stable name for an exact source state
Chapter 10 focused on recovering from mistakes while preserving provenance. Release work adds the opposite requirement: once an organization says “this exact source produced version 1.4.2,” developers, CI, deployment records, incident reports, and rollback procedures need that identifier to keep meaning the same source state.
Git provides refs under refs/tags/ for names that
normally mark important objects. A release policy then decides which
tags are authoritative, whether they are annotated or signed, how
version numbers are chosen, how changelogs are maintained, and how
older support lines receive fixes.
2. Inspect release identifiers before creating new ones
git status --short --branch
git log --graph --decorate --oneline --all --max-count=20
git tag --list
git show-ref --tags
git for-each-ref --sort=creatordate --format='%(refname:short) %(objecttype) %(objectname:short) %(creatordate:iso8601)' refs/tags
The first two commands establish repository state and graph position. The tag commands show the names already in use and the objects those refs currently identify. Release automation should inspect existing refs rather than assume a version name is free.
3. Lightweight tags are refs directly naming an object
A lightweight tag is a ref such as
refs/tags/build-check whose value directly names
another Git object, commonly a commit. There is no separate tag
object containing a tagger, tag message, or tag signature.
git tag build-check
git cat-file -t build-check
git rev-parse build-check
If build-check directly names a commit,
git cat-file -t reports commit.
Lightweight tags can be useful as temporary/local markers, but they
carry less release metadata than annotated tags.
4. Annotated tags add a tag object between the ref and target
An annotated tag created with git tag -a creates a real
tag object. That object records the target object,
target type, tag name, tagger identity/time, and a message. The ref
in refs/tags/ points to that tag object.
flowchart TD LW[refs/tags/build-check] --> C1[commit C1] AT[refs/tags/v1.0.0] --> TO[tag object] TO -->|object field| C1 TO --> M[tagger + date + message] C1 --> T1[tree snapshot]
The lightweight arrow goes directly to the commit. The annotated path first reaches a tag object, and that object names the commit. Both can identify the same commit while representing different Git structures.
5. Peeling means following an annotated tag to its target
Git revision syntax can ask for the tag object itself or its peeled commit target:
git cat-file -t v1.0.0
git rev-parse v1.0.0^{tag}
git rev-parse v1.0.0^{commit}
git cat-file -p v1.0.0
^{tag} insists that the name resolves to a tag object.
^{commit} dereferences tag objects until a commit is
reached. Release scripts should be explicit about whether they are
recording the tag-object OID or the released commit OID; often both
are useful provenance.
6. Inspect the ref and the peeled object together
git for-each-ref --format='%(refname:short) ref=%(objectname:short) type=%(objecttype) peeled=%(*objectname:short) peeled-type=%(*objecttype)' refs/tags
For an annotated tag, the ordinary fields describe the tag object
and the fields prefixed by * describe the peeled
target. For a lightweight tag there is no tag object to peel, so the
starred fields may be empty.
7. A signed tag adds authenticity evidence to the tag object
git tag -s creates an annotated tag whose tag object
includes a cryptographic signature. Current Git can use OpenPGP,
X.509, or SSH signing backends depending on gpg.format.
A successful git verify-tag proves that the stored tag
payload validates under the configured verification machinery.
That result is not the same as organizational trust. You still need policy for which key/principal is trusted, how keys are distributed/revoked, and whether the signer was authorized to release this project. Chapter 21 treats trust in depth.
8. Semantic Versioning is a release convention, not a Git feature
Git does not understand that v2.0.0 is “major” while
v1.8.4 is “patch.” Those are names. Semantic Versioning
2.0.0 defines meaning around a declared public API: incompatible API
changes increment MAJOR, backward-compatible functionality
increments MINOR, and backward-compatible bug fixes increment PATCH.
The common v prefix in Git tags is a repository naming
convention. If package/build tooling expects strict SemVer text,
document whether it accepts v1.2.3 or strips the
prefix.
9. Published version identifiers should be immutable
A local tag can technically be deleted or force-moved. That does not
make moving a published release tag good policy. Once consumers have
fetched v1.2.0, two different commits carrying the same
public version name create an integrity and incident-response
problem.
A safer release correction is normally: acknowledge the mistake, create a new version identifier, and publish the provenance change. The official Git tag documentation deliberately warns that already-published tags should not be silently changed.
10. A changelog serves a different audience than raw commit history
Commit history is engineering provenance. A changelog is a curated release communication artifact. It can group changes by user/operational significance, call out breaking changes and migrations, identify security considerations, and omit implementation noise that is valuable in commits but not to release consumers.
Good commit messages help generate changelogs, but they do not guarantee that a chronological list of subjects is an adequate release note.
11. Support branches preserve multiple maintained histories
A project may release 1.0.0, continue new development
on trunk, and also keep a
support/1.0 branch for patch releases. A bug fix can be
developed on one line and backported to another with an explicit
commit, often via cherry-pick. Each support line then has its own
reachable commit set and tags.
flowchart LR R100[v1.0.0] --> N110[v1.1.0] N110 --> FIX[fix on trunk] FIX --> R111[v1.1.1] R100 --> BP[backported fix] BP --> R101[v1.0.1] TR[trunk] --> R111 SUP[support/1.0] --> R101
The backport and original fix can contain the same logical change yet be different commit objects because their parents differ. Tags name the released tips on each line.
12. DevOps connection — release identifiers become operational foreign keys
Build records, containers, deployment manifests, SBOMs, incident tickets, monitoring annotations, and rollback runbooks often store a Git commit/tag. That identifier is only useful if the release process keeps the mapping stable and auditable. An annotated/signed release tag plus exact peeled commit OID gives automation a durable source reference; the changelog and support policy explain what that source means operationally.
13. Knowledge check
Question 1. Why does git cat-file -t v1.0.0 often
say tag for an annotated release?
v1.0.0^{commit} reaches the released commit.
Question 2. What metadata does an annotated tag add that a lightweight tag does not?
Question 3. Does naming a tag v2.0.0 make Git
enforce Semantic Versioning rules?
Question 4. What does a valid tag signature prove?
Question 5. Why is changing a published release tag hazardous?
14. Summary
Lightweight tags are direct refs; annotated tags add tag objects; peeling distinguishes the tag object from its released target; signatures add authenticity evidence; SemVer and changelogs are release conventions; and support branches maintain parallel histories. Production release provenance depends on keeping published identifiers stable.
Authoritative references
git-tag
git-for-each-ref
git-rev-parse
git-verify-tag
Semantic Versioning 2.0.0
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.