Chapter 11Lesson 01~85 minutes

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.

Tag objectsSigned releasesSemVerSupport lines

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.

Lightweight versus annotated release name
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.

Development and support histories
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?

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.

Next

Create, inspect, describe, push, and safely retire tags

Lesson 2 builds a local release repository and bare remote, proves that tags are not universally pushed with branch updates, demonstrates describe, and keeps signing optional so the core lab needs no external account or key infrastructure.

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.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.