Chapter 11Lesson 05~150 minutes

Checkpoint Lab — Tags, Signed Releases, Semantic Versioning, Changelogs, and Support Lines

Checkpoint a complete release history with annotated tags, changelog entries, a maintained 1.0 support branch, an explicit backport, reachability verification, remote publication, and a CI-ready provenance report.

CheckpointRelease provenanceSupport branchBackport

Learning objectives

  • Create annotated release tags and verify tag-object versus peeled-commit OIDs.
  • Maintain trunk and support/1.0 as separate release histories with intentional reachability.
  • Backport one fix and prove that the source and backport commits have different OIDs.
  • Publish exact branch/tag refs to a local bare remote without replacing published versions.
  • Produce a release provenance checklist suitable for future CI/CD automation.

1. Checkpoint scenario — maintain a current line and a 1.0 support line

You will create releases v1.0.0 and v1.1.0 on trunk, develop one bug fix, backport that fix to support/1.0, publish v1.0.1 on the support line and v1.1.1 on trunk, and produce an exact source/tag/support provenance report.

2. Predictions before mutation

  1. Will v1.0.0 and v1.1.0 be tag objects or direct commit refs?
  2. If the same logical fix is cherry-picked from trunk to support/1.0, will the support commit have the same OID?
  3. Should v1.1.0 be reachable from support/1.0?
  4. After tagging v1.0.1, should its peeled target equal the support branch tip?

3. Setup a disposable release repository and local remote

mkdir git-release-checkpoint
cd git-release-checkpoint
git init --bare origin.git
git init -b trunk work
cd work
git config user.name "Release Checkpoint"
git config user.email "release-checkpoint@example.invalid"
git remote add origin ../origin.git
git config --local push.followTags false

printf "# Widget API\n" > README.md
printf "api=1\ntimeout=5\n" > service.conf
cat > CHANGELOG.md <<'EOF'
# Changelog

## 1.0.0
- Initial stable Widget API.
EOF

git add README.md service.conf timeouts.conf CHANGELOG.md
git commit -m "Release baseline for Widget API"
git status --short --branch

PowerShell setup alternative

New-Item -ItemType Directory git-release-checkpoint | Out-Null
Set-Location git-release-checkpoint
git init --bare origin.git
git init -b trunk work
Set-Location work
git config user.name "Release Checkpoint"
git config user.email "release-checkpoint@example.invalid"
git remote add origin ../origin.git
git config --local push.followTags false

Set-Content README.md '# Widget API'
Set-Content service.conf 'api=1'
Set-Content timeouts.conf 'timeout=5'
@(
  '# Changelog',
  '',
  '## 1.0.0',
  '- Initial stable Widget API.'
) | Set-Content CHANGELOG.md

git add README.md service.conf timeouts.conf CHANGELOG.md
git commit -m "Release baseline for Widget API"
git status --short --branch

Subsequent Git graph, tag, cherry-pick, and reachability commands are shell-independent. File edits shown as comments can be made in any text editor; inspect the diff before staging.

4. Create and inspect the first annotated release

git tag -a v1.0.0 -m "Widget API 1.0.0"
V100_TAG=$(git rev-parse v1.0.0^{tag})
V100_COMMIT=$(git rev-parse v1.0.0^{commit})

git cat-file -t v1.0.0
git cat-file -p v1.0.0
git show --stat v1.0.0
git for-each-ref --format='%(refname:short) %(objecttype) %(objectname) %(*objectname)' refs/tags/v1.0.0

Verify prediction 1: v1.0.0 is a tag object whose peeled target is the release commit.

5. Advance trunk and release 1.1.0

printf "batch=true\n" >> service.conf
cat >> CHANGELOG.md <<'EOF'

## 1.1.0
- Add backward-compatible batch processing.
EOF
git add service.conf CHANGELOG.md
git commit -m "Add batch processing"

git tag -a v1.1.0 -m "Widget API 1.1.0"
V110_COMMIT=$(git rev-parse v1.1.0^{commit})
git describe --long HEAD
git log --graph --decorate --oneline --all --max-count=10

6. Develop one patch fix on trunk

# Change timeout=5 to timeout=10 in timeouts.conf.
git add timeouts.conf
git commit -m "Increase timeout for slow clients"
SOURCE_FIX=$(git rev-parse HEAD)

cat >> CHANGELOG.md <<'EOF'

## 1.1.1
- Increase timeout for slow clients.
EOF
git add CHANGELOG.md
git commit -m "Document 1.1.1 patch release"

git tag -a v1.1.1 -m "Widget API 1.1.1"
V111_COMMIT=$(git rev-parse v1.1.1^{commit})

7. Create the support branch from the released 1.0.0 commit

git switch -c support/1.0 v1.0.0^{commit}
git log --oneline --decorate -4
git merge-base --is-ancestor v1.0.0^{commit} support/1.0
git merge-base --is-ancestor v1.1.0^{commit} support/1.0
echo $?

The first ancestry check succeeds. The second should fail because the support branch intentionally forked before the 1.1 feature.

8. Backport the fix and prove that it receives a new OID

git cherry-pick "$SOURCE_FIX"
BACKPORT_FIX=$(git rev-parse HEAD)

git show --stat "$SOURCE_FIX"
git show --stat "$BACKPORT_FIX"
test "$SOURCE_FIX" != "$BACKPORT_FIX"
git log --graph --decorate --oneline --all --max-count=14

Verify prediction 2: the cherry-picked support commit has a different parent and therefore a different OID, even though it represents the same logical timeout fix.

9. Add the support-line changelog entry and tag 1.0.1

cat >> CHANGELOG.md <<'EOF'

## 1.0.1
- Backport timeout increase for slow clients from the current line.
EOF
git add CHANGELOG.md
git commit -m "Document 1.0.1 patch release"

git tag -a v1.0.1 -m "Widget API 1.0.1 support release"
V101_TAG=$(git rev-parse v1.0.1^{tag})
V101_COMMIT=$(git rev-parse v1.0.1^{commit})

git rev-parse support/1.0
git rev-parse v1.0.1^{commit}

Verify prediction 4: both OIDs should match because the release tag was created at the support tip.

10. Verify which releases belong to which support line

git merge-base --is-ancestor v1.0.0^{commit} support/1.0
git merge-base --is-ancestor v1.0.1^{commit} support/1.0
git merge-base --is-ancestor v1.1.0^{commit} support/1.0
git merge-base --is-ancestor "$SOURCE_FIX" support/1.0
git merge-base --is-ancestor "$BACKPORT_FIX" support/1.0

git tag --contains v1.0.0^{commit}
git tag --contains v1.1.0^{commit}
git branch --contains "$SOURCE_FIX"
git branch --contains "$BACKPORT_FIX"

Verify prediction 3: v1.1.0 is not in the support/1.0 ancestry. The original fix belongs to trunk; the backport belongs to the support branch.

11. Publish branches and release tags explicitly

git switch trunk
git push -u origin trunk
git push origin refs/tags/v1.0.0:refs/tags/v1.0.0
git push origin refs/tags/v1.1.0:refs/tags/v1.1.0
git push origin refs/tags/v1.1.1:refs/tags/v1.1.1

git switch support/1.0
git push -u origin support/1.0
git push origin refs/tags/v1.0.1:refs/tags/v1.0.1

git ls-remote --heads origin
git ls-remote --tags origin

Each release tag is named explicitly in the publish sequence. A production release job should fail if the remote tag already exists with an unexpected OID rather than silently replacing it.

12. Produce a release provenance checklist suitable for CI

git for-each-ref   --sort=refname   --format='tag=%(refname:short)|tag_oid=%(objectname)|type=%(objecttype)|peeled=%(*objectname)|subject=%(contents:subject)'   refs/tags/v1.*

printf "v1.0.0_commit=%s\n" "$(git rev-parse v1.0.0^{commit})"
printf "v1.0.1_commit=%s\n" "$(git rev-parse v1.0.1^{commit})"
printf "v1.1.0_commit=%s\n" "$(git rev-parse v1.1.0^{commit})"
printf "v1.1.1_commit=%s\n" "$(git rev-parse v1.1.1^{commit})"
printf "source_fix=%s\n" "$SOURCE_FIX"
printf "backport_fix=%s\n" "$BACKPORT_FIX"

Future CI can extend this with signature verification, build artifact digest, SBOM/attestation identifiers, test results, and deployment environment metadata.

13. Verification checklist

  • All four version tags are annotated tag objects.
  • Each tag's peeled OID equals the intended release commit.
  • v1.0.0 is an ancestor of both maintained lines.
  • v1.1.0 is not an ancestor of support/1.0.
  • The trunk fix and support backport have different OIDs.
  • The support branch contains the backport but not the trunk fix object.
  • Each remote release tag was pushed explicitly and can be verified with ls-remote --tags.
  • The changelog contains release entries appropriate to each line.
  • No published release tag was force-moved or silently replaced.

14. Learner-written release policy

Write a short RELEASE-POLICY.md outside the disposable repository that answers:

  1. Which tag pattern identifies public releases?
  2. Are release tags annotated, signed, or both?
  3. Who may publish them, and which controls are server-enforced?
  4. What versioning convention defines compatibility meaning?
  5. How are changelog entries reviewed?
  6. Which support branches are maintained and for how long?
  7. Where is the source/backport OID relationship recorded?
  8. What happens if a release tag targets the wrong commit?

15. Cleanup

Confirm the directory before recursive deletion. All refs/remotes in this checkpoint are disposable.
cd ../..
pwd
rm -rf git-release-checkpoint

PowerShell

Set-Location ../..
Get-Location
Remove-Item -Recurse -Force git-release-checkpoint

16. Knowledge check

Question 1. Why is v1.0.1 not expected to contain the v1.1.0 feature commit?

Question 2. Why are SOURCE_FIX and BACKPORT_FIX different OIDs?

Question 3. What should CI record for an annotated release tag besides its name?

Question 4. Why push release tags explicitly in the checkpoint?

Question 5. A release tag is on the wrong commit after publication. What is the default safe policy?

17. What Chapter 11 adds to a production Git operating model

You can now create immutable release identifiers, distinguish tag refs from tag objects/peeled commits, add optional cryptographic evidence, design version/changelog policy, maintain parallel support histories, backport fixes with explicit provenance, and generate release metadata that later CI/CD automation can verify.

18. Chapter checkpoint summary

A trustworthy release is not merely a tag name. It is a stable mapping from version → tag object → source commit, combined with authorization/signature policy, changelog meaning, and support-line history that downstream systems can audit.

Next chapter

Stash, Worktrees, Temporary Work, and Parallel Development Contexts

Chapter 12 returns to developer workflow and shows how to manage temporary or parallel work without turning release/support branches into accidental scratch space.

Authoritative references

 git-tag
 git-for-each-ref
 git-rev-list
 git-push
 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.