Checkpoint Lab — Commit-Graphs, Multi-Pack Indexes, Maintenance, Garbage Collection, and Performance
Checkpoint an evidence-driven Git maintenance workflow: create enough history/packs to observe changes, establish invariants, write/verify acceleration structures, run safe maintenance, measure again, and recommend role-specific policy.
Learning objectives
- Predict which repository facts must remain invariant while storage representation changes.
- Create and verify MIDX/commit-graph acceleration from known-good packs.
- Run task-specific maintenance and non-pruning GC on disposable data.
- Compare repeated timings without forcing a speedup conclusion.
- Produce separate maintenance recommendations for developer, CI, and central-server repositories.
1. Checkpoint scenario — optimize storage without changing source history
You maintain a long-lived local repository that has accumulated loose objects and several packs. Your task is to prove which repository facts must stay invariant, add acceleration structures, run safe maintenance, and recommend different policies for developers, ephemeral CI, and a central server.
2. Predict before changing representation
-
After repack, MIDX, commit-graph, and maintenance operations,
should
refs/heads/trunkpoint to a different commit? -
Can the number/names of files under
.git/objects/packchange while every commit remains identical? -
Should
git fsck --fullremain successful after safe maintenance? - Can a tiny lab become slower in one timing sample even when the auxiliary structure is valid?
3. Generate history and files without huge resource use
Git Bash / Bash / zsh
mkdir git-maintenance-checkpoint
cd git-maintenance-checkpoint
git init -b trunk repo
cd repo
git config user.name "Maintenance Checkpoint"
git config user.email "maintenance-checkpoint@example.invalid"
mkdir src
for i in $(seq 1 40); do
printf "component=%s\nrevision=0\n" "$i" > "src/component-$i.txt"
done
git add src
git commit -m "seed 40 components"
for batch in 1 2 3 4; do
for n in $(seq 1 35); do
file=$(( (n % 40) + 1 ))
printf "batch=%s revision=%s\n" "$batch" "$n" >> "src/component-$file.txt"
git add "src/component-$file.txt"
git commit -m "batch $batch revision $n" >/dev/null
done
git repack -d
done
PowerShell
New-Item -ItemType Directory git-maintenance-checkpoint | Out-Null
Set-Location git-maintenance-checkpoint
git init -b trunk repo
Set-Location repo
git config user.name "Maintenance Checkpoint"
git config user.email "maintenance-checkpoint@example.invalid"
New-Item -ItemType Directory src | Out-Null
1..40 | ForEach-Object {
"component=$_`nrevision=0" | Set-Content "src/component-$_.txt"
}
git add src
git commit -m "seed 40 components"
1..4 | ForEach-Object {
$batch = $_
1..35 | ForEach-Object {
$n = $_
$file = ($n % 40) + 1
"batch=$batch revision=$n" | Add-Content "src/component-$file.txt"
git add "src/component-$file.txt"
git commit -m "batch $batch revision $n" | Out-Null
}
git repack -d
}
The result is roughly 141 commits and multiple packing opportunities—large enough to inspect structures but small enough for a workstation lab.
4. Capture immutable and mutable baselines
TIP_BEFORE=$(git rev-parse refs/heads/trunk)
COUNT_BEFORE=$(git rev-list --count trunk)
git status --short --branch
git show-ref
git count-objects -vH
git fsck --full
ls .git/objects/pack/
Immutable baseline: branch-tip OID and commit count. Mutable representation: loose-object count, pack count/names, MIDX, and commit-graph files.
5. Capture repeatable timing samples
for i in 1 2 3; do
time git rev-list --count trunk
done
for i in 1 2 3; do
time git log --oneline -- src/component-1.txt >/dev/null
done
PowerShell timing alternative
1..3 | ForEach-Object {
Measure-Command { git rev-list --count trunk | Out-Null }
}
1..3 | ForEach-Object {
Measure-Command { git log --oneline -- src/component-1.txt | Out-Null }
}
Record all samples rather than selecting the fastest. This lab cannot guarantee a measurable speedup because the repository is intentionally modest and caches may dominate.
6. Verify current packs before adding another index
for idx in .git/objects/pack/*.idx; do
git verify-pack "$idx"
done
git count-objects -vH
Optimization should begin from known-good storage. If validation fails, stop and diagnose before repacking.
7. Prediction 1 — write/verify MIDX without changing refs
git multi-pack-index write
git multi-pack-index verify
test "$(git rev-parse refs/heads/trunk)" = "$TIP_BEFORE"
test "$(git rev-list --count trunk)" = "$COUNT_BEFORE"
The auxiliary lookup layer changes; branch history does not.
8. Prediction 2 — write/verify commit-graph with path filters
git commit-graph write --reachable --changed-paths
git commit-graph verify
test "$(git rev-parse refs/heads/trunk)" = "$TIP_BEFORE"
git log --oneline -- src/component-1.txt >/dev/null
The commit-graph can now accelerate graph/path queries while commit objects remain authoritative.
9. Register maintenance in an isolated config file
git maintenance register --config-file ../checkpoint-maintenance.config
git config --file ../checkpoint-maintenance.config --get-all maintenance.repo
git config --show-origin --get maintenance.strategy
git config --show-origin --get maintenance.auto
Do not call maintenance start in the mandatory
checkpoint because it installs user scheduler entries. The
registration/config evidence is enough to understand what would be
scheduled.
10. Run safe task-specific maintenance
git maintenance run --task=commit-graph
git maintenance run --task=loose-objects
git multi-pack-index write
git maintenance run --task=incremental-repack
git commit-graph verify
git multi-pack-index verify
git count-objects -vH
Pack count can increase or decrease depending on size selection. Do not assert a specific number; assert integrity and ref/history invariants.
11. Demonstrate GC without pruning unreachable objects
git gc --no-prune
git fsck --full
test "$(git rev-parse refs/heads/trunk)" = "$TIP_BEFORE"
test "$(git rev-list --count trunk)" = "$COUNT_BEFORE"
git count-objects -vH
12. Repeat exactly the same measurements
for i in 1 2 3; do
time git rev-list --count trunk
done
for i in 1 2 3; do
time git log --oneline -- src/component-1.txt >/dev/null
done
PowerShell timing alternative
1..3 | ForEach-Object {
Measure-Command { git rev-list --count trunk | Out-Null }
}
1..3 | ForEach-Object {
Measure-Command { git log --oneline -- src/component-1.txt | Out-Null }
}
Explain the result rather than forcing a success narrative. If the difference is within noise, the correct conclusion is “this lab is too small/cached to demonstrate a stable speedup,” not “Git maintenance failed.”
13. Verification checklist
- The exact
trunktip OID is unchanged. - The commit count is unchanged.
git fsck --fullsucceeds.- All pre-maintenance pack indexes were verified before modification.
- MIDX write/verify succeeded before GC.
- Commit-graph write/verify succeeded with changed-path data.
- Maintenance registration used an isolated config file rather than real global config.
- Task-specific maintenance ran without a scheduler dependency.
-
GC used
--no-prune; no prune-now/aggressive deletion command was executed. - Timing samples were repeated under comparable conditions.
14. Produce the operating recommendation
| Repository role | Recommendation | Reason |
|---|---|---|
| Developer clone | Measure status/history; use supported working-tree caches plus incremental/geometric maintenance when size warrants | Long-lived clone can amortize auxiliary/background work |
| Ephemeral CI | Focus first on fetch/checkout depth and deterministic build provenance; avoid needless scheduled maintenance | Clone may be destroyed before maintenance pays back |
| Central bare server | Controlled commit-graph/MIDX/repack maintenance in planned windows; monitor pack/object counts and I/O | Persistent shared object database benefits from server-side lookup/storage health |
15. Recovery-aware maintenance rule
If a performance incident occurs while recovery/forensic work is active, preserve refs/reflogs/unreachable evidence first. Do not “clean up” the evidence to make the repository smaller. Maintenance windows and retention windows are operational policy, not interchangeable concepts.
16. Cleanup
cd ../..
pwd
rm -rf git-maintenance-checkpoint
PowerShell equivalent:
Set-Location ../..; Remove-Item -Recurse -Force
git-maintenance-checkpoint.
17. Knowledge check
Question 1. MIDX write changes pack lookup data. Should it change the trunk OID?
Question 2. Pack count changes after incremental repack. Is that automatically a failure?
Question 3. The after-timing is slightly slower. What should you conclude?
Question 4. Why was scheduled maintenance not installed?
Question 5. What is the first priority if maintenance and recovery goals conflict?
18. What Chapter 22 adds to a production Git operating model
You can now separate working-tree, graph-traversal, and object-store performance; measure before tuning; create and verify commit-graph/MIDX structures; choose maintenance strategies by repository lifecycle; avoid destructive pruning; coordinate background work; and validate that storage optimization preserves refs and history.
19. Chapter checkpoint summary
Healthy Git maintenance is evidence-driven housekeeping. The best optimization is often a derived index or incremental task, not an aggressive cleanup. Performance improvements remain subordinate to repository integrity, recovery retention, and predictable foreground delivery.
Authoritative references
git-maintenance
git-commit-graph
git-multi-pack-index
git-gc
git-verify-pack
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.