5 repos · 29 commands · 3 broken · 5 slow · 4 filed
As a pluggable-backend author on win-x64 I wrote a scratch grit-lib program against the public API only: a from-scratch HashMap ObjectStore and a per-ref-lock RefStore (both pass the shipped conformance suites), then ran commit/switch/merge/conflict/stash/log on them, differentially against a files repo and MemoryStore+MemoryRefStore, exported to system git (fsck --strict clean, SHA-1 and SHA-256), plus scaling, concurrency, commit-graph, reftable and Windows checks. Correctness and parity are good; the findings are performance cliffs in the ref-transaction layer (quadratic RefTransaction build, O(all refs) per check_transaction, reftable stack never compacted), a leaky git_dir-based refs API, and two fixed issues (#2257, #2181) that still reproduce. Filed #2279, #2281, #2282, #2285; reopened #2257 and #2181; confirmed #2184, #2264, #2269, #2263 fixed.
| repo | files | commits | .git | notes |
|---|---|---|---|---|
| octocat/Hello-World | 1 | 3 | 0.1 MB | smoke tests, JSON/markdown output, concurrent branch creation |
| rust-lang/cargo | 3,078 | 23,596 | 80.7 MB | log/status/diff/blame/rebase timings; 74 MB pack ingested into a custom store |
| scratch/hist-120k | 0 | 120,000 | 25.7 MB | bare repo from git fast-import, merge every 10th commit, commit-graph written; commit-graph benchmark |
| scratch/wide-200k | 200,000 | 1 | 8.7 MB | bare repo with one 200,000-entry directory for #2269 (tracked in tree, no worktree) |
| scratch/reftable-and-loose-ref repos | 300 | 300 | 1 MB | reftable repo written by grit (300 commits), 100k loose-ref bare repo, case/reserved-name repos |
| command | repo | grit | git | grit/git | result | notes |
|---|---|---|---|---|---|---|
| grit-lib: custom MapStore + LockedRefStore everyday scenario (stage, commit, branch, switch, merge, stash, rev_list) | scratch | — | — | — | ok | Identical trees/status/stash to files backend; git fsck --strict clean; SHA-1 and SHA-256. |
| grit-lib: refstore_conformance::run_suite / odb_conformance suites on custom stores | scratch | — | — | — | ok | |
| grit-lib: create_branch x100 per thread, 16 threads, MemoryRefStore | scratch | 922 ms | — | — | wrong | 34/1600 spurious LockHeld; 32 threads 352/3200 (#2181). |
| grit-lib: create_branch x16000 single thread, MemoryRefStore | scratch | 67.14 s | — | — | slow | quadratic (4.2 ms avg); 1000: 441 ms, 4000: 4.5 s; files backend linear (#2282). |
| grit-lib: RefTransaction::push_update x100k then prepare+commit (MemoryRefStore) | scratch | 21.16 s | — | — | slow | build of the batch is quadratic; prepare+commit of 30k is 68 ms (#2281). |
| grit-lib: backend::check_transaction one create, 100k refs in state | scratch | 13 ms | — | — | slow | 138 us at 1k refs, 38 ms at 300k (#2282). |
| grit-lib: 1000 single-ref CAS updates on reftable store | scratch/reftable | 37.20 s | 2.53 s | 15× | slow | 1002 tables vs git 3 (#2279). |
| grit-lib: 500 CAS updates of existing loose refs (FilesRefStore) | scratch | 2.34 s | 384 ms | 6.1× | slow | median 1.2-4.7 ms per update (noisy) vs git update-ref --stdin 0.77 ms and raw lock+rename 0.26 ms; creates are fine (0.6 ms). Not filed: bimodal and noisy on this machine. |
| grit-lib: rev_list(HEAD) 120k commits, custom store with attached commit-graph | scratch/hist-120k | 206 ms | 62 ms | 3.3× | ok | Equal to files backend (208 ms); git rev-list --count with graph 62 ms (process inclusive) so ~3x git for the library walk, not custom-store specific. |
| grit-lib: merge_bases_all(HEAD, side) 120k commits, custom store with graph | scratch/hist-120k | 27 ms | 50 ms | 0.5× | ok | |
| grit-lib: build_commit_graph (changed paths) 120k commits | scratch/hist-120k | 481 ms | — | — | ok | |
| grit merge-base main side | scratch/hist-120k | 71 ms | 50 ms | 1.4× | ok | |
| grit revs side..main -n 1 | scratch/hist-120k | 96 ms | 48 ms | 2.0× | ok | 2x git (no early exit on -n). |
| grit log --oneline -n 30000 | rust-lang/cargo | 222 ms | 224 ms | 1.0× | ok | |
| grit log --oneline -n 30000 -- Cargo.toml | rust-lang/cargo | 149 ms | 133 ms | 1.1× | ok | |
| grit status | rust-lang/cargo | 102 ms | 44 ms | 2.3× | ok | 2.3x git; under the 3x bar. |
| grit diff HEAD~50 | rust-lang/cargo | 14 ms | 90 ms | 0.2× | ok | |
| grit blame Cargo.toml | rust-lang/cargo | 117 ms | 151 ms | 0.8× | ok | |
| grit branch | rust-lang/cargo | 9.2 ms | 25 ms | 0.4× | ok | |
| grit show HEAD | rust-lang/cargo | 10 ms | 26 ms | 0.4× | ok | |
| grit merge-base HEAD~500 HEAD~700 | rust-lang/cargo | 28 ms | 43 ms | 0.7× | ok | |
| grit revs HEAD~2000..HEAD --count | rust-lang/cargo | 106 ms | 102 ms | 1.0× | ok | |
| grit rebase master (60 commits onto +3641) | rust-lang/cargo | 3.41 s | 2.73 s | 1.2× | ok | single run; #2263 fixed. |
| grit cat HEAD:big (200k entries) | scratch/wide-200k | 68 ms | 345 ms | 0.2× | ok | #2269 fixed. |
| grit-lib: ingest_pack_into 74 MB / 195k-object cargo pack into MapStore | rust-lang/cargo | 9.70 s | 2.71 s | 3.6× | ok | git index-pack comparison is not like-for-like (no copies in memory); RSS ~1.15x the 1.48 GB uncompressed data, expected for an in-memory store. |
| grit init --ref-format reftable + 300 grit commit | scratch/reftable | — | — | — | wrong | 314 table files remain (git: 4 after 30 commits); readable by git 2.55 (#2279). |
| grit branch aux|con|com1|lpt1|Aux.x ; grit tag con | scratch/windows-refs | — | — | — | wrong | creates refs git cannot read (#2257 not fixed); grit branch nul -> raw 'I/O error: Incorrect function (os error 1)'; grit fsck reports clean while git fsck errors. |
| 6 parallel jobs x 60 grit branch + concurrent git for-each-ref loop | octocat/Hello-World | — | — | — | ok | 0 failures in 360 creations / 406 git reads; no stale locks; git fsck clean. |
| grit status|log|branch|merge-base|reflog --json / --markdown | octocat/Hello-World | — | — | — | ok | All --json outputs parse; markdown renders. |