Why
Metadata writes rewrote the whole vole branch, one blob and one directory at a time. At 959 files a create took about 12 seconds, and each CI run added seven files to that cost. #79 has the measurements and the Phase 0 spike that predicted it.
What changed
FlatTreereads the branch with onegit cat-file --batchcall and anls-tree -r -tthat also returns directory ids.CommitFileshashes content in memory to find the paths that changed, then writes only those blobs and the directories above them. Everything else reuses the old blob and subtree ids.- A write that changes no bytes leaves the tree id exactly as it was.
- The first commit on an empty ref still writes every blob: there is no old tree to reuse.
Tests
TestBlobIDMatchesGitpins the in-memory blob id againstgit hash-object.TestBlobsBySHABinarycovers binary content, an empty blob, and duplicate requests through the batch reader.TestCommitFilesIncrementalEditsadds, changes, and deletes in one commit, checks the resulting files, and checks that an unrelated subtree id was reused.TestCommitFilesReusesTreeWhenNothingChangedpins the tree id for a no-op write.TestCommitFilesStaysProportionalToTheChangesetsGIT_TRACEand fails if a one-file write on a 200-file tree starts more than 20 git processes. The old path started over 400.BenchmarkCommitFilesOneFilemeasures about 44 ms per one-file write on a 2,000-file tree, down from 26.8 s in the scale measurement on #79.
Checks
go test ./...go test -race ./core/git ./metadata ./ci/runs ./clientgo vet ./...vole workflow checkvole workflow run verify: format, vet, build, govulncheck, packages, markdown links, and the race suite.