The reachability bottleneck
Many Git operations need to answer "is commit X reachable from commit Y?" or "which commit is the merge base?" Naively this means walking the commit graph from raw object reads — slow on large repos. The commit-graph file precomputes parent pointers, generation numbers, and (optionally) Bloom filters into a binary side file.
Where it lives
Older Git: .git/objects/info/commit-graph (single file). Newer Git: .git/objects/info/commit-graphs/ (chained, allowing incremental writes).
Writing the graph
git commit-graph write --reachable --changed-paths
git commit-graph verify
git commit-graph write --split=replace --reachable --changed-paths
--reachable includes all ref-reachable commits. --changed-paths adds Bloom filters. --split creates incremental layers.
Auto-write
git config core.commitGraph true
git config gc.writeCommitGraph true
git config fetch.writeCommitGraph true
Enabled by default in Git 2.24+ on most installs. Verify with git config --show-origin core.commitGraph.
Generation numbers
Each commit gets a topological generation number. Comparing them lets Git skip whole graph regions during walks. The "corrected commit date" generation (Git 2.30+) further accelerates queries by combining generation with committer date.
Performance impact
On Linux's repo (over a million commits), git log --oneline | head drops from seconds to milliseconds. git merge-base drops similarly. Tag listing on huge repos becomes near-instant.
Measurement
git -c core.commitGraph=false log -100 --pretty=oneline >/dev/null
time git -c core.commitGraph=false log --oneline | head -10000 >/dev/null
time git log --oneline | head -10000 >/dev/null
Compare the two — usually 5-50x speedup.
Common mistakes
Forgetting to write the graph after a big push or rebase; fetch.writeCommitGraph=true automates it. Disabling core.commitGraph for a "fresh test" without realizing many other features depend on it. Stale graphs after rewriting history; let git maintenance handle this.
Related
See "Changed-path Bloom filters in the commit-graph" and "Background maintenance: git maintenance run/start/stop".