Chapter 15Lesson 05~160 minutes

Checkpoint Lab — Advanced Revision Selection, Log Search, Path History, and Ancestry Analysis

Checkpoint revision analysis by building a merged deployment history with a rename, answering five audit questions, tracing first-parent and ancestry paths, and saving equivalent human-readable and machine-readable reports.

CheckpointDeployment auditQuery verificationReports

Learning objectives

  • Predict and verify merge-parent, unique-branch, first-parent, and rename-history behavior.
  • Write and verify five concrete revision expressions against one deterministic graph.
  • Trace deployment-line first-parent history and source-branch divergence.
  • Save human-readable and machine-readable reports representing the same selected set.
  • Document each history query in plain language so its semantics are auditable.

1. Checkpoint scenario — audit a deployment graph with a renamed file

You will construct a small release history with two topic branches, merge one topic into the deployment line, leave another branch unmerged, rename an operational file, and answer five concrete audit questions. You will then save a human report and a machine report and explain why they serve different consumers.

2. Predictions before building the graph

  1. After a --no-ff merge, should the merge commit have two parents?
  2. If experiment/cache remains unmerged, should trunk..experiment/cache contain its two commits?
  3. Should first-parent deployment history include the merge event but omit the individual feature commits?
  4. Can git log --follow show history under the file's old name in a single-file linear branch?

3. Build the disposable repository

Git Bash, Bash, or zsh

mkdir git-revision-checkpoint
cd git-revision-checkpoint
git init -b trunk repo
cd repo
git config user.name "Revision Checkpoint"
git config user.email "revision-checkpoint@example.invalid"

mkdir -p services/api docs deploy
printf "port=8080\nmode=stable\n" > services/api/config.txt
printf "# Operations\n" > docs/ops.md
printf "env=dev\n" > deploy/state.txt
git add .
git commit -m "A: baseline"
A=$(git rev-parse HEAD)

printf "health=/ready\n" >> services/api/config.txt
git add services/api/config.txt
git commit -m "B: health endpoint"
B=$(git rev-parse HEAD)

git branch feature/settings
git branch experiment/cache

printf "env=staging\n" > deploy/state.txt
git add deploy/state.txt
git commit -m "T1: staging deployment"
T1=$(git rev-parse HEAD)

printf "owner=platform\n" >> docs/ops.md
git add docs/ops.md
git commit -m "T2: platform ownership"
T2=$(git rev-parse HEAD)

PowerShell setup alternative

New-Item -ItemType Directory git-revision-checkpoint | Out-Null
Set-Location git-revision-checkpoint
git init -b trunk repo
Set-Location repo
git config user.name "Revision Checkpoint"
git config user.email "revision-checkpoint@example.invalid"

New-Item -ItemType Directory -Force services/api,docs,deploy | Out-Null
@('port=8080','mode=stable') | Set-Content services/api/config.txt
Set-Content docs/ops.md '# Operations'
Set-Content deploy/state.txt 'env=dev'
git add .
git commit -m "A: baseline"
$A = git rev-parse HEAD

Add-Content services/api/config.txt 'health=/ready'
git add services/api/config.txt
git commit -m "B: health endpoint"
$B = git rev-parse HEAD

git branch feature/settings
git branch experiment/cache

Set-Content deploy/state.txt 'env=staging'
git add deploy/state.txt
git commit -m "T1: staging deployment"
$T1 = git rev-parse HEAD

Add-Content docs/ops.md 'owner=platform'
git add docs/ops.md
git commit -m "T2: platform ownership"
$T2 = git rev-parse HEAD

4. Rename and extend the feature file

git switch feature/settings
git mv services/api/config.txt services/api/settings.txt
git commit -m "F1: rename API configuration"
F1=$(git rev-parse HEAD)

printf "timeout=30\n" >> services/api/settings.txt
git add services/api/settings.txt
git commit -m "F2: add timeout"
F2=$(git rev-parse HEAD)

5. Create the unmerged experiment

git switch experiment/cache
mkdir -p services/cache
printf "cache=enabled\n" > services/cache/cache.txt
git add services/cache/cache.txt
git commit -m "E1: cache prototype"
E1=$(git rev-parse HEAD)

printf "ttl=120\n" >> services/cache/cache.txt
git add services/cache/cache.txt
git commit -m "E2: cache TTL"
E2=$(git rev-parse HEAD)

6. Create the deployment integration line

git switch trunk
git tag -a deploy-1 -m "Deployment before settings" "$T2"

git merge --no-ff feature/settings -m "M: integrate settings"
M=$(git rev-parse HEAD)

printf "env=production\n" > deploy/state.txt
git add deploy/state.txt
git commit -m "R: production deployment"
R=$(git rev-parse HEAD)
git tag -a deploy-2 -m "Production deployment" "$R"

git log --graph --decorate --oneline --all

Verify prediction 1:

git show --no-patch --format='%H %P %s' "$M"
git rev-list --parents -n 1 "$M"

The merge line should contain the merge OID plus exactly two parent OIDs.

7. Audit question 1 — what is unique to the unmerged experiment?

git log --oneline trunk..experiment/cache
git rev-list --count trunk..experiment/cache

Expected: two commits, E1 and E2. Verify prediction 2.

8. Audit question 2 — where did trunk and experiment diverge?

BASE=$(git merge-base trunk experiment/cache)
git show --no-patch --oneline "$BASE"
git log --left-right --graph --oneline trunk...experiment/cache
git rev-list --left-right --count trunk...experiment/cache

The merge base should be B. The left/right log lists work unique to both sides.

9. Audit question 3 — what integration events reached deploy-2 after deploy-1?

git log --first-parent --oneline deploy-1..deploy-2
git rev-list --first-parent deploy-1..deploy-2

Verify prediction 3: the report includes merge M and deployment R but not F1/F2 as separate first-parent commits.

10. Audit question 4 — which commits lie on ancestry paths from F1 to deploy-2?

git log --ancestry-path --oneline "$F1..deploy-2"
git rev-list --ancestry-path "$F1..deploy-2"

Expected descendants include F2, M, and R. T1/T2 are reachable from R but are not descendants of F1.

11. Audit question 5 — trace settings history before and after the rename

git log --follow --name-status feature/settings -- services/api/settings.txt
git show "$B:services/api/config.txt"
git show "$F2:services/api/settings.txt"

Verify prediction 4: the single-file follow query should cross the rename in this linear feature branch. The two show commands independently prove exact old/new snapshot content.

12. Save a human-readable deployment report

Git Bash / Bash / zsh

git log --first-parent --graph --decorate --date=short \
  --format='%h %ad %d %s' deploy-1..deploy-2 \
  > deployment-human.txt
cat deployment-human.txt

PowerShell

git log --first-parent --graph --decorate --date=short `
  --format='%h %ad %d %s' deploy-1..deploy-2 |
  Set-Content deployment-human.txt
Get-Content deployment-human.txt

This format optimizes reading: abbreviated IDs, decorations, graph characters, and subjects. It is not ideal as a machine protocol.

13. Save a machine-readable commit report

Use full IDs and explicit fields. The file below uses tab-separated rows for easy inspection; production software may prefer NUL-delimited or structured serialization.

git log --first-parent \
  --format='%H%x09%P%x09%ct%x09%s' \
  deploy-1..deploy-2 > deployment-machine.tsv

Record the query endpoints too:

git rev-parse deploy-1^{commit}
git rev-parse deploy-2^{commit}
git rev-list --first-parent deploy-1..deploy-2

14. Explain why the two reports differ

Property Human report Machine report
Object IDs Abbreviated Full
Ref decorations Useful visual labels Omitted unless explicitly needed
Graph glyphs Helpful Avoided
Timestamp Readable date Numeric commit timestamp
Parsing stability Low priority High priority

15. Verify the same commit set independently

git rev-list --first-parent deploy-1..deploy-2 > deployment-oids.txt
git log --first-parent --format='%H' deploy-1..deploy-2 > deployment-log-oids.txt

Git Bash / Bash / zsh

diff -u deployment-oids.txt deployment-log-oids.txt

PowerShell

Compare-Object (Get-Content deployment-oids.txt) (Get-Content deployment-log-oids.txt)

No differences should appear. This cross-check proves the display command and plumbing enumeration selected the same set/order.

16. Verification checklist

  • The merge commit has two parents; M^1=T2 and M^2=F2.
  • trunk..experiment/cache contains exactly E1 and E2.
  • The merge base of trunk and experiment/cache is B.
  • Three-dot log labels unique commits from both sides.
  • First-parent deploy range contains M and R without expanding F1/F2.
  • Ordinary deploy range can reach F1/F2 through M.
  • --ancestry-path F1..deploy-2 excludes unrelated pre-merge trunk commits.
  • --follow crosses the single-file rename in the linear feature history.
  • Exact old/new file content can be retrieved with show commit:path.
  • Human and machine reports store the same selected first-parent commits.

17. Write five query definitions in plain language

For each audit question, save one sentence that names the endpoints, membership rule, path scope, and ordering. Example: “Deployment report = commits reachable from deploy-2 and not deploy-1, traversing first parents only, newest first.” This sentence is the durable specification; the Git command is its implementation.

18. Cleanup

Copy the reports outside the disposable directory first if you want to retain them.

Git Bash / Bash / zsh

cd ../..
pwd
rm -rf git-revision-checkpoint

PowerShell

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

19. Knowledge check

Question 1. Why do deploy-1..deploy-2 and its first-parent variant have different memberships?

Question 2. Which expression answers “commits only on experiment/cache relative to trunk”?

Question 3. Why store full IDs in deployment-machine.tsv?

Question 4. A path log omits a merge-side event you expected. What should you test?

Question 5. What makes a history query reproducible?

20. What Chapter 15 adds to a production Git operating model

You can now express release, deployment, incident, divergence, and path-history questions as auditable Git queries. Operational automation can store full IDs and explicit ranges, while human reports can use topology and decoration without confusing presentation with semantics.

21. Chapter checkpoint summary

The central skill is not memorizing git log flags. It is translating a question into a commit set, verifying the endpoints, selecting the traversal/path rules, and cross-checking the answer with object-level evidence.

Next chapter

Bisect, Blame, Pickaxe Search, Merge Bases, and Repository Forensics

Chapter 16 builds on precise revision selection to locate regressions, attribute lines cautiously, search for content-introducing commits, and reconstruct incident evidence.

Authoritative references

 gitrevisions
 git-rev-list
 git-log
 git-show
 gitglossary pathspec

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.