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.
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
-
Will
v1.0.0andv1.1.0be tag objects or direct commit refs? -
If the same logical fix is cherry-picked from trunk to
support/1.0, will the support commit have the same OID? -
Should
v1.1.0be reachable fromsupport/1.0? -
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.0is an ancestor of both maintained lines. -
v1.1.0is not an ancestor ofsupport/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:
- Which tag pattern identifies public releases?
- Are release tags annotated, signed, or both?
- Who may publish them, and which controls are server-enforced?
- What versioning convention defines compatibility meaning?
- How are changelog entries reviewed?
- Which support branches are maintained and for how long?
- Where is the source/backport OID relationship recorded?
- What happens if a release tag targets the wrong commit?
15. Cleanup
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.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.