grit://cooking/dogfood← what’s cooking
Thursday, October 29, 2026 · Ubuntu 24.04.5 LTS (Linux 6.12.94+)

Dogfood on linux-cloud: New-CLI author

6 repos · 30 commands · 1 broken · 10 slow · 5 filed

As a new-CLI author I built a small front end ('stk') on grit-lib's public API only (status, commit, branch, switch, reset, merge, restack via start/continue/skip/abort_rebase, fetch with progress/cancel, a ref-snapshot op log with undo) and ran it on cargo, git/git and synthetic 45k/200k-file repos, plus a kill -9 matrix and CLI comparisons against git 2.43. The library API is typed and pleasant (everything compiled almost first try, errors are typed enums, conflicts are values, a long-lived Repository sees external git changes, cancel is prompt and rolls back cleanly), and I re-verified 4 fixes. I filed 5 issues: undo after a conflicted rebase is impossible, flat-directory status/diff is ~3x slower than git (no stat parallelism), fetch gives no progress for most of its runtime, checkout-style commands use 3-5x git's memory, and an integrate_branch API trap; a 6th (log memory) hit the report cap and is listed under problems.

os
Ubuntu 24.04.5 LTS (Linux 6.12.94+) · x86_64
machine
Cursor cloud VM, 4 vCPU Intel Xeon, 15 GB RAM
versions
grit 0.5.24 (curl install script) · main f9813499 · 2.43.0
repositories6
repofilescommits.gitnotes
git/git4,85782,616324 MBbare mirror clone at /tmp/dogfood/git.git plus a local clone (gitgit)
rust-lang/cargo3,07823,59681 MBalso local clones for the rebase repro (cargo2263) and 3000-branch repo (s4)
octocat/Hello-World131 MBcloned, otherwise unused
scratch/flat-200k200,000133 MB200,000 files in one directory (loose then packed by auto gc)
scratch/wide-45k45,000214 MB30 dirs x 1500 files; branch other rewrites 22.5k, main the other 22.5k; used for kill -9 matrix and checkout memory
scratch/stack repos (s1-s4, er1, u2, crlf)———small fixtures for restack, merge, errors, CRLF
commandsgrit vs. system git, wall time
commandrepogritgitgrit/gitresultnotes
grit statusgit/git10 ms8.0 ms1.3×ok2.1x memory, absolute 10 MB
grit statusrust-lang/cargo19 ms7.0 ms2.7×ok2.7x time but 12 ms absolute; untracked scan is 11 of ~13 ms in-process
grit statusscratch/flat-200k176 ms60 ms2.9×slow2.9x; single directory -> serial stat; filed #2276
grit diffscratch/flat-200k168 ms54 ms3.1×slow3.1x; #2276
grit add .scratch/flat-200k231 ms122 ms1.9×ok1.9x
grit statusscratch/wide-45k18 ms14 ms1.3×ok
grit log --oneline (full)rust-lang/cargo223 ms182 ms1.2×memory2.8x RSS, grows linearly with commits; not filed (report cap)
grit log --oneline (full)git/git784 ms693 ms1.1×memory2.8x RSS; --json 277 MB (4.1x)
grit log --oneline -- src/cargo/corerust-lang/cargo236 ms208 ms1.1×ok
grit revs --count HEADgit/git773 ms576 ms1.3×memory2.0x RSS, 1.34x time
grit revs --count HEAD~5000..HEADrust-lang/cargo168 ms143 ms1.2×ok
grit cat HEAD:data (200k-entry tree)scratch/flat-200k73 ms76 ms1.0×memorytime fixed (#2269) but RSS 3.7x human, 5.5x json (103 MB)
grit merge other (22.5k files each side)scratch/wide-45k1.41 s922 ms1.5×memory4.2x RSS, 1.5x time; filed #2280
grit switch other (22.5k files)scratch/wide-45k714 ms1.28 s0.6×memory3.8x RSS; #2280
grit reset --hard other (22.5k files)scratch/wide-45k741 ms995 ms0.7×memory4.7x RSS; #2280
grit stash pop (22.5k files)scratch/wide-45k515 ms826 ms0.6×memory2.6x RSS; #2280
grit switch --detach HEAD~20000 (5,223 files)git/git327 ms155 ms2.1×ok2.1x time
grit switch --detach HEAD~6000 (3,314 files)rust-lang/cargo159 ms130 ms1.2×ok
grit rebase --update-refs head master (60 commits)rust-lang/cargo430 ms307 ms1.4×okflat in commit count; #2263 verified fixed
grit fetch origin (file://, empty dst)rust-lang/cargo4.25 s4.26 s1.0×ok1.9x RSS (borderline); progress nearly absent #2278
grit fetch origin (file://, empty dst)git/git25.67 s21.88 s1.2×ok1.8x RSS, 1.17x time; 17.5 s with no progress events #2278
grit clone file://rust-lang/cargo4.27 s4.19 s1.0×ok
grit branchrust-lang/cargo (3001 branches)13 ms16 ms0.8×ok
stk restack (library start_rebase, 3000 other branches)rust-lang/cargo358 ms149 ms2.4×okgit rebase master; grit CLI rebase 323 ms / 46 MB vs git 149 ms / 22 MB
stk restack + continue/skip/abort (library)scratch/stack———okconflicts as typed values, skip/abort correct, fsck clean
grit history undo (after conflicted rebase --continue)scratch/stack———error#2274
kill -9 matrix switch/reset/merge/stash pop/pick/rebasescratch/wide-45k———okfsck clean, HEAD never half-moved, stash retained, typed stale-lock error
cancel at 300 ms: switch / reset --hard (library)scratch/wide-45k———okrolled back, tree clean, no lock
create_commit x4 threads x30 (library)scratch———okonly typed ExpectedMismatch losses, history consistent (Linux sanity for #2261)
CRLF/autocrlf/eol checkout round trip (reset --hard) vs gitscratch/crlf———okworktree bytes identical to git for autocrlf=true/input/false and core.eol=crlf with text=auto/eol=lf/eol=crlf/binary attrs
worked8
  • ›grit-lib public API is typed and discoverable: the 500-line stk front end compiled almost first try and needed nothing from grit-cli
  • ›Rebase session API: conflicts are values (RebaseOutcome::Stopped with typed Conflict kinds), continue/skip/abort behave like git and leave fsck-clean repos; typed refusals for dirty worktree and branches checked out in linked worktrees
  • ›Cancellation is prompt and transactional for checkout paths (switch/reset --hard roll back fully) and for fetch (nothing written)
  • ›Long-lived Repository sees external git writes (refs, packed-refs, config, index, stash) with no stale caches
  • ›Crash safety: kill -9 across switch/reset/merge/stash pop/pick/rebase never left refs ahead of the worktree, stash entries are retained, stale lock errors are typed and name the dead pid
  • ›CRLF/eol/attribute checkouts byte-identical to git; change-ids preserved across rebase/amend
  • ›HEAD reflog is now written by rebase --continue on main (#2154 looks fixed there)
  • ›23 of 24 CLI commands emit valid --json and non-empty --markdown on cargo
problems10
  • ›FILED #2274: grit history undo / undo_last_rewrite fails after a rebase that stopped on conflicts and was finished with --continue (history-last records the detached stop HEAD)
  • ›FILED #2276: status/diff stat 200k files in one directory serially, 2.9-3.1x slower than git, --threads has no effect
  • ›FILED #2277: integrate_branch short-name into_ref gives misleading RefStore ExpectedMismatch; form undocumented (also ContinueOptions lacks Default)
  • ›FILED #2278: Remote::fetch from local/file:// emits no progress for ~70% of the run and a single set() for the copy; three identical CopyingObjects phases
  • ›FILED #2280: switch/reset --hard/merge/stash pop rewriting 22.5k files use 2.6-4.7x git's RSS (90-108 MB vs 22-26 MB)
  • ›NOT FILED (report cap): grit log --oneline / --json log memory grows linearly with history, 187 MB vs git 67 MB on git/git (2.8x), 277 MB for --json (4.1x); -n 1000 38 MB vs 17 MB
  • ›NOT FILED (borderline/duplicate area): grit cat of a 200k-entry tree is fast again but RSS 70 MB human / 103 MB json vs git 19 MB; whole-repo fetch/clone RSS 1.8-1.9x git (cargo 308 vs 163 MB, git/git 972 vs 533 MB)
  • ›NOT FILED (minor): `grit tag --json` is unbounded (131 KB on cargo); --filter jq subset lacks @tsv; WouldOverwrite error carries a presentation message string; RefTransaction::push_update accepts invalid ref names until commit; grit log abbreviates to 7 chars where git auto-picks 9 on cargo/git; status() mutates (interrupted-rewrite recovery) which is surprising for a 'read' call in a refresh loop though documented
  • ›NOT FILED (app-level gap): no library helper to detect/clear an in-progress operation (rebase-merge, MERGE_HEAD) when an op-log undo rewinds refs underneath it; reflog messages must be supplied by the caller for hand-built ref transactions
  • ›Could not verify on Linux: #2257 and #2261 (Windows-only); only Linux sanity checks done and recorded
bugs filed5
#2274 #2276 #2277 #2278 #2280already reported: #2142 #2154 #2268 #2036 #1884 #2103 #2127 #2128 #2131
next time
  • ›Re-test merge/commit/stash cancellation after #2142 and cancel during the silent send-set phase of push
  • ›Build the op log properly on reflogs + history-last and check undo of commit/merge/switch/stash through library calls with pre-existing in-progress operations (needs a lib API to clear sequencer state)
  • ›Run a throttled HTTPS/ssh fetch of git/git against grit-http-server and measure ReceivedObjects/bytes progress and server RSS
  • ›Custom ObjectStore + injected RefStore end to end once #2128/#2131 are fixed: commit, merge, fetch, export to disk, git fsck
  • ›Retest #2274 after the fix for skip_rebase and for a 3-branch stack, and check undo_last_rewrite after continue/skip with a dirty worktree
  • ›Streaming log API: measure a 100k-row UI list through load_commits_with_decorations vs a callback walk; compare memory with git log on git/git
  • ›Windows/macOS: core.ignorecase, aux/con refs after #2257, concurrent create_commit after #2261
  • ›status() recovery side effects in a refresh loop with a competing kill -9'd rebase apply