grit://cooking/dogfood← what’s cooking
Thursday, October 29, 2026 · Windows 11 (10.0.26200)

Dogfood on win-x64: Git server builder

5 repos · 28 commands · 3 broken · 6 slow · 5 filed

Server-builder dogfood on win-x64: served cargo, git/git, a 608 MB blob repo, 20k-ref repos and reftable repos over smart HTTP with `grit serve` and with a std-only embedded server written purely against the grit-lib public API (grit_lib::remote::serve), using system git 2.55 as client. Wire compatibility, hooks, filters, shallow, push policy, tags and Windows hostile ref names/URL paths are solid; found 5 new problems (reftable reader 500s under concurrent pushes, reftable write/read performance, quadratic many-ref pushes on the files backend, long-path serve db) and #2287 (large-blob clone memory) is NOT fixed on Windows. Re-checked 6 fixes: 5 fixed, 1 not.

os
Windows 11 (10.0.26200) · x86_64
machine
win-x64 (self-hosted worker): Intel i5-12400, 4 logical CPUs available to jobs, 16 GB RAM, NTFS
versions
grit none on PATH; built 0.5.24 from main · main 440f8dbf · git version 2.55.0.windows.5
repositories5
repofilescommits.gitnotes
octocat/Hello-World131 MBbare copy served as hello.git; plus scratch commits from tests
rust-lang/cargo3,07823,59685 MBbare clone served as cargo.git
git/git4,85782,616323 MBbare clone served as git.git
scratch/608MB-single-blob11608 MBrandom-data blob, packed and loose variants
scratch/refs-4k-20k011 MBone empty commit with 500..20000 branches, files and reftable variants
commandsgrit vs. system git, wall time
commandrepogritgitgrit/gitresultnotes
git clone --bare http://.../cargo.git (grit serve)rust-lang/cargo7.33 s11.20 s0.7×okgit column = git clone --bare file:// (git upload-pack, Windows); server peak WS 337 MB
8 parallel git clone --bare (grit serve)rust-lang/cargo40.27 s——okserver peak WS 1676 MB total, ~210 MB per clone
git clone --bare http://.../git.git (grit serve)git/git27.57 s——okfsck connectivity clean
git fetch (20 new commits, v0 and v2)rust-lang/cargo399 ms381 ms1.0×okgit column measured on git/git via file://; v2 277 ms
git fetch (20 new commits)git/git407 ms381 ms1.1×ok#2196 fixed
git clone --bare --filter=blob:nonerust-lang/cargo4.50 s6.30 s0.7×oksame 135200 objects
git clone --bare --filter=tree:0rust-lang/cargo2.80 s4.30 s0.7×ok24469 objects
git clone --bare --filter=blob:limit=2krust-lang/cargo5.30 s4.80 s1.1×ok146084 objects
git clone --bare --filter=sparse:oid=<blob>rust-lang/cargo12.43 s25.63 s0.5×ok171480 objects both
git clone --depth 1 --no-single-branchrust-lang/cargo3.54 s——ok136 commits; unshallow 7.9 s
git push (608 MB blob, new repo)scratch/608MB-single-blob10.26 s——ok#2284 fixed
git clone (608 MB blob, packed on server)scratch/608MB-single-blob6.90 s——memory#2287: peak 1644 MB; loose variant 1036 MB, 17.6 s; embedded lib server 618 MB
git push --all (410k objects, receive.fsckObjects=true)git/git15.90 s19.67 s0.8×okgit column = local file:// push to git receive-pack
grit clone http://.../cargo.git (grit client, grit serve)rust-lang/cargo5.30 s——okfsck clean
git push --all 500..4000 new refs -> reftable repo (grit serve)scratch/refs-4k-20k90.30 s1.40 s65×slow4000 refs; 20000 refs 784 s; #2307
git push --all 4000 new refs -> files repo (grit serve)scratch/refs-4k-20k10.60 s5.50 s1.9×ok2x git at 4000
git push --all 20000 new refs -> files repo (grit serve)scratch/refs-4k-20k202.20 s28.90 s7.0×slowquadratic: 8k 31 s, 12k 61 s; #2309
git ls-remote (20k refs, files, grit serve)scratch/refs-4k-20k1.25 s100 ms13×slow12x; related to #1820 (first call after the push took 9.9 s)
git ls-remote (20k refs, reftable, grit serve)scratch/refs-4k-20k15.50 s100 ms155×slow#2308; pattern filter does not help
grit branch -n 5 (20k refs, grit-written reftable, 6 tables)scratch/refs-4k-20k15.28 s570 ms27×slowgit for-each-ref; after git pack-refs 2.86 s; #2308
grit branch --json (20k refs, files)scratch/refs-4k-20k680 ms——ok
git clone --bare (20k refs, files, grit serve)scratch/refs-4k-20k3.80 s——ok
grit gc while 3 clients clone in loopsrust-lang/cargo2.43 s1.65 s1.5×okgit column = git repack -adq; no client errors on Windows
8 concurrent push+fetch workers (files)octocat/Hello-World120.83 s——okno lost updates; contention rejections only
8 concurrent push+fetch workers (reftable)octocat/Hello-World66.06 s——errorone fetch got HTTP 500; #2306
3 writers + 4 readers on info/refs (reftable)octocat/Hello-World———error3-4% HTTP 500, #2306; system git readers 0 failures out of 320
grit serve --setup --root <335-char path>octocat/Hello-World———error#2310
embedded server (grit_lib::remote::serve): clone cargorust-lang/cargo6.97 s——okpeak WS 241 MB; upload outcome objs=195100 bytes=77.9M
worked7
  • ›Smart HTTP v0/v2 interoperates with Git for Windows 2.55 for clone, fetch, push, shallow, unshallow, tags, delete, force push and denyNonFastForwards.
  • ›Partial clone filters (blob:none, tree:0, blob:limit, tree:1, sparse:oid) return exactly git's object sets and are as fast or faster than git upload-pack.
  • ›No lost ref updates under 8 concurrent pushers on the files backend; repack/gc under live clones is safe on NTFS.
  • ›Reserved Windows device names, D/F conflicts, ACL name variants, traversal and dumb-protocol URLs are all rejected cleanly.
  • ›Server hook scripts run without sh on PATH; push options reach them; hook output shown as remote: lines.
  • ›grit-lib serve API is usable end-to-end from a 250-line program without private APIs (push options, cancel, outcome stats, per-user refusal).
  • ›Reftable written by grit reads cleanly with system git (fsck, for-each-ref, clone); long-path repo works with a short --db.
problems12
  • ›#2306 filed: reftable readers get HTTP 500 during concurrent pushes.
  • ›#2307 filed: reftable receive-pack ~22 ms per ref (4000 refs 90 s vs git 1.4 s).
  • ›#2308 filed: listing 20k refs from grit-written reftable 15 s vs git 0.57 s.
  • ›#2309 filed: files-backend receive-pack of many refs is quadratic (20k refs 202 s vs git 29 s).
  • ›#2310 filed: grit serve default db fails when root path > 260 chars.
  • ›#2287 reopened via verify_fix: large-blob clone memory 1.0-1.6 GB on Windows.
  • ›Not filed: ReceiveHookContext/ServeOptions give no way to advertise push options; only repo config receive.advertisePushOptions (docs gap).
  • ›Not filed: pushing `foo` when `Foo` exists on case-insensitive FS is refused with 'stale info' (safe, misleading, cosmetic).
  • ›Not filed: serve startup prints verbatim `\\?\C:\...` root and grit gc prints mixed-slash paths (cosmetic on Windows).
  • ›Not filed: grit-lib builds with ~10 warnings on Windows (unused imports in atomic_replace.rs, split_index.rs, fsmonitor.rs; unreachable expression in history/apply.rs:1953; unused variables in config/core.rs, history/apply.rs).
  • ›Not filed: `grit serve` enumerates repositories only at startup (a repo created afterwards is 404 until restart) - may be intended.
  • ›Not filed: 20k-ref ls-remote through grit serve took 9.9 s right after the push but 1.2 s afterwards (cold path, covered by #1820/#2189 area).
bugs filed5
#2306 #2307 #2308 #2309 #2310already reported: #1820 #2189 #1753 #1757
next time
  • ›Re-run #2306 style readers against grit-written reftable on Linux/macOS to see whether the 0-byte table read is Windows-specific, and test `grit gc`/pack-refs of a reftable repo while serving.
  • ›Real sshd (Win32-OpenSSH) with forced-command `grit upload-pack` / `grit receive-pack`, 16+ parallel clients, per-process peak memory (needs a Job-object based RSS sampler).
  • ›Re-test #2287 and the extra copy in grit-protocol after the fix with a 1.5 GB blob; also pushes > 2 GB with gzip request bodies and receive.maxInputSize.
  • ›1M-ref reftable repo, MIDX/commit-graph/bitmap-backed clone of git/git, v2 ref-in-want/sideband-all/packfile-uris with newer clients.
  • ›grit serve with 50+ token clients and the web UI under load; password change flow, token revocation while a push is in flight.
  • ›Long-path and case-insensitive scenarios on the client side of push/fetch (refs/heads/Foo vs foo from two users), and antivirus-style file locking on pack files during repack.