7 repos · 39 commands · 0 broken · 9 slow · 4 filed
Large-monorepo persona on scott-mbp (macOS arm64, APFS): synthetic 300k and 1.02M-file repos, git/git with 82k extra branches, a 2.2 GiB pack straddling the 2^31 offset, case-collision checkouts, and a grit-lib program for status/cancel/concurrency. Grit matches or beats git on most daily-loop commands (status, diff, switch, rebase, stash, merge, clone, initial import, gc) and the four re-checked fixes hold. Real gaps: reset --hard / merge --abort over 30-60k-file diffs (#2311), 3.3x memory on a conflicted wide merge (#2312), status ignores Cancel inside the scan (#2313), merge refuses a detached HEAD (#2314).
| repo | files | commits | .git | notes |
|---|---|---|---|---|
| scratch/300k-files | 300,000 | 1 | 498 MB | 1000 dirs x 300 small text files, plus wa/wb/wc/wnc/topic branches; .git 1208 MB while loose |
| scratch/1m-files | 1,020,000 | 1 | 368 MB | 3400 dirs x 300 files; 4105 MB while loose |
| git/git | 4,857 | 82,616 | 325 MB | plus 82k synthetic branch refs in one copy |
| scratch/bigpack | 20,003 | 1 | 2,400 MB | 3x800 MB random blobs + 20k small files, 2.23 GiB single pack |
| scratch/case-collide | 8 | 1 | 0 MB | README/readme, Foo.c/foo.c, symlink, exec bit, aux.txt |
| scratch/untracked-ignored | 2 | 1 | 0 MB | 60k untracked + 60k ignored files |
| scratch/200k-wide-dir | 200,000 | 1 | 0 MB | 200k entries in one directory |
| command | repo | grit | git | grit/git | result | notes |
|---|---|---|---|---|---|---|
| grit status (clean) | scratch/300k-files | 340 ms | 330 ms | 1.0× | ok | bimodal 340/600 ms on repeated runs; not filed |
| grit status (5 files touched) | scratch/300k-files | 1.73 s | 1.22 s | 1.4× | ok | first run after edits; repeat runs 600 ms |
| grit status (5k modified) | scratch/300k-files | 670 ms | 990 ms | 0.7× | ok | |
| grit diff --stat (5k modified) | scratch/300k-files | 1.04 s | 1.56 s | 0.7× | ok | |
| grit add (5k modified) | scratch/300k-files | 1.81 s | 660 ms | 2.7× | ok | 2.7x, 2x RSS; #1884 family |
| grit commit -m (5k staged) | scratch/300k-files | 1.30 s | 490 ms | 2.7× | ok | 2.65x, 2.2x RSS |
| grit commit -m (auto-stage 5k) | scratch/300k-files | 1.18 s | 550 ms | 2.1× | ok | git commit -a |
| grit reset --hard (clean tree) | scratch/300k-files | 880 ms | 860 ms | 1.0× | ok | #2268 fixed |
| grit reset --hard wnc (60k files differ) | scratch/300k-files | 20.58 s | 7.34 s | 2.8× | slow | 2.8x, 1.8x RSS; #2311 |
| grit switch wb (60k files differ) | scratch/300k-files | 3.70 s | 6.97 s | 0.5× | ok | faster than git |
| grit merge wc (35k paths, clean) | scratch/300k-files | 1.02 s | 2.37 s | 0.4× | ok | same tree |
| grit merge wb (3000 conflicts, 33k paths) | scratch/300k-files | 5.72 s | 6.16 s | 0.9× | memory | 3.3x RSS; #2312 |
| grit merge --check wb | scratch/300k-files | 1.18 s | — | — | ok | no git equivalent; correct rc=1 |
| grit merge --abort (after conflicted merge) | scratch/300k-files | 7.63 s | 3.10 s | 2.5× | slow | 2.5x, 2.2x RSS; #2311 |
| grit reset --hard (after conflicted merge) | scratch/300k-files | 12.29 s | 3.74 s | 3.3× | slow | 3.3x; #2311 |
| grit rebase wa (5 commits, upstream moved 30k files) | scratch/300k-files | 2.41 s | 6.41 s | 0.4× | ok | identical tree hash |
| grit stash / stash pop (5k dirty) | scratch/300k-files | 1.41 s | 3.13 s | 0.5× | ok | pop 420 ms vs 1330 ms |
| grit commit (initial import 300k files) | scratch/300k-files | 40.59 s | 170.00 s | 0.2× | ok | git add -A 161.6 s + commit 8.4 s; identical tree |
| grit commit (initial import 1.02M files) | scratch/1m-files | 176.60 s | — | — | ok | 1.02M loose objects, then detached gc --auto ~14 min / ~1 GB RSS |
| grit status (1.02M files) | scratch/1m-files | 3.08 s | 2.99 s | 1.0× | ok | first run after a git-written index 6.0 s / 422 MB |
| grit commit 1 file (1.02M files) | scratch/1m-files | 4.52 s | 2.96 s | 1.5× | ok | 2x RSS; #1884 family |
| grit commit 1 file (300k, no TREE ext) | scratch/300k-files | 1.13 s | 550 ms | 2.1× | memory | 3x RSS; 2x time; #1884 |
| grit status (300k, no TREE ext) | scratch/300k-files | 650 ms | 560 ms | 1.2× | memory | 2.1x RSS |
| grit clone (local file://) | git/git | 10.11 s | 17.11 s | 0.6× | ok | same HEAD, fsck clean (one tag missingTaggerEntry warning, same as git) |
| grit log -- builtin/commit.c | git/git | 320 ms | 330 ms | 1.0× | ok | #1619 not reproduced on this build |
| grit blame Makefile | git/git | 1.09 s | 530 ms | 2.1× | ok | 2x; ~1% lines attributed differently on ambiguous hunks |
| grit blame builtin/commit.c | git/git | 450 ms | 300 ms | 1.5× | ok | |
| grit branch (82k branches) | git/git | 970 ms | 1.55 s | 0.6× | ok | branch -n 20 still 940 ms (reads all refs) |
| grit switch --detach v2.30.0 / v1.6.0 | git/git | 630 ms | 480 ms | 1.3× | ok | |
| grit gc (82k loose refs) | git/git | 20.11 s | 70.59 s | 0.3× | ok | pack-refs 9.3 s + reflog-expire 8.8 s of it; git pack-refs alone 21.8 s, reflog expire 36 s |
| grit cat main:z/f19999.txt (offset > 2^31) | scratch/bigpack | 10 ms | 50 ms | 0.2× | ok | |
| grit fsck (2.2 GiB pack) | scratch/bigpack | 2.18 s | 8.65 s | 0.3× | memory | 2.0x RSS; #2287 family |
| grit clone file:// (2.2 GiB pack) | scratch/bigpack | 45.40 s | 19.90 s | 2.3× | slow | 2.3x time incl. checkout, 2x RSS; #2287 |
| grit gc repack -f (2.2 GiB pack) | scratch/bigpack | 3.89 s | 5.91 s | 0.7× | ok | 2.0x RSS; git verify-pack/fsck accept output |
| grit cat HEAD:d (200k entries) | scratch/200k-wide-dir | 70 ms | 60 ms | 1.2× | ok | #2269 fixed |
| grit clean --dry-run | scratch/untracked-ignored | 500 ms | 130 ms | 3.8× | slow | 3.8x, tiny absolute; Windows #2242 not testable |
| grit status --ignored | scratch/untracked-ignored | 100 ms | 50 ms | 2.0× | ok | |
| libprog: porcelain::status x3 + cancel + 10 handles | scratch/300k-files | 330 ms | — | — | ok | 10 concurrent handles: 1.75 s each, 610-715 MB total; cancel latency issue #2313 |
| libprog: porcelain::status (1.02M files) | scratch/1m-files | 3.08 s | — | — | ok | RSS creeps ~15-25 MB per repeated call on the same Repository handle |