chadtmiller.com/knotless
git that lives in your Atmosphere account
Mirrors keep a commit-graph, so walks of history read one file
MergedAfter a sync that moves a mirror's refs, or finds a mirror with no commit-graph, this runs git commit-graph write --reachable --split. It also adds a has_graph check, a test assertion and a design-note paragraph. The change is small and does what it says. I found nothing that must change.
One thing to consider: the graph is only an optimisation, but ? on self.git.graph() makes a failed write fail the whole sync. This happens after the refs have already been updated. A disk-full or lock error would then surface as a sync error on every attempt. Logging the failure and carrying on would keep syncs working, and has_graph would retry the write on the next sync. Your call.
crates/knotless/src/mirror.rsline 116
} | |
self.git.tidy(PACKS).await?; | |
if moved || !self.git.has_graph() { | |
self.git.graph().await?; |
A failed graph write fails the sync even though the refs are already updated and the graph is only an optimisation. Consider logging the error and continuing.
8 passed, 2 skipped
What changes
Mirrors keep a commit-graph. A sync that moves a mirror's refs, or finds a mirror with no commit-graph, runs
git commit-graph write --reachable --splitafterwards. That file holds each commit's parents and date beside the packs. gix reads it on its own during any walk of history, so the commits page, each entry's last change on the code page, and the client's mirrors all walk from that file instead of reading each commit out of the packs. Split, the write adds only the commits the graph does not hold yet.The storage design note says so, under mirrors.
Why
This is groundwork for a commit count on the code page's History button, which takes a walk of a ref's whole history. It also speeds up every walk serve already makes. Mirrors never had a commit-graph: syncs index packs and repack them, and neither writes one.
Timed with the same gix version and features serve uses, counting the whole history (three runs each):
Writing rust's graph from scratch took 8 s on a Mac. A write with nothing new took 20 ms.
On prod (idle, load 0.5), on a copy of its largest mirror (864 commits):
git rev-list --all --counttook 25–28 ms before and 7–10 ms after, both counting git's own start-up. The first write took 32 ms and a write with nothing new 7 ms. Prod's repositories are small today, so the gain there is small; it grows with the history.Writing only when the refs moved keeps a sync that finds nothing new from starting a process.
How it was checked
The library test that syncs a mirror now asserts it has a graph afterwards. Everything else is left to CI.
Shortcomings
--changed-paths(Bloom filters for a path's history) yet. It is unmeasured, and the gain depends on whether gix reads them.Changeset: none
🤖 Generated with Claude Code