grit://cooking/changelog← what’s cooking
Sunday, October 25, 2026 · release v0.5.20

72 changes landed on main

58 issue fixes · 14 other changes

v0.5.20 is mostly a performance and memory release for add, gc/repack, clone, status, blame and revwalks, plus fixes to diff, ignore, merge, fetch and push.

  • ›Faster add/commit on large trees: quadratic sorting and per-path scans removed (#1674, #1673, #1682)
  • ›gc/repack, clone, upload-pack and https clone use far less memory and time (#1690, #1038, #1672, #1744)
  • ›Faster status, switch and checkout on Windows, plus fixed hook execution (#1702, #1613, #1742)
  • ›Faster revwalks, blame, rebase, tag --contains and diff rename detection (#1680, #1752, #1689, #1683)
  • ›Fixes: no-arg and path-limited diff show staged changes, re-included dirs, reset orphans, merge --continue (#1655, #1703, #1650, #1687)
  • ›SSH push hang, large HTTP push 413, partial fetch on ref conflicts, custom ODB and ref store fixes (#1656, #1740, #1654, #1735)
$ git log d3efb57d..v0.5.20217 commits on GitHub ↗300+ files +9,982 −4,524
Highlightsmeasured by the reviewers, before → after
grit repack/gc on rust-lang/cargo: 18-111s and 3.5-3.7 GB RSS (git repack -adf: 5-6s / 450 MB, git gc: 1.2s)
rust-lang/cargo mirror repack wall time (origin/main vs branch no-op)13980× better████████████████████████ 153.8 seconds █ 0.011 seconds
grit-lib RevWalk::walk/rev_list ignores max_count and commit-graph: -n10 takes 500ms on git/git (git: 3ms)
git/git RevWalk max_count=10, old-default-equivalent to branch default median1410× better████████████████████████ 924.7 ms █ 0.656 ms
grit gc on already-packed git/git: 47s vs git gc 6.2s; prune with 0 loose objects alone takes 13s (git: 0.00s)
git/git prune wall time with zero loose objects1382× better████████████████████████ 13.8 seconds █ 0.010 seconds
MemoryRefStore deadlocks (hangs forever) when a for_each_ref / for_each_reflog_ref callback calls back into the store
Exact deadlock reproduction completion669× better████████████████████████ 2.0 seconds (baseline timed out at exit 124; branch exited 0) █ 0.003 seconds (baseline timed out at exit 124; branch exited 0)
Windows: clean-tree grit status re-reads every tracked file (1.25 s vs git 16 ms on 240 MB); 3.5-5x slower on cargo/git
60×4 MiB tracked-only status, origin/main → branch272× better████████████████████████ 641.7 ms median, 25 runs █ 2.4 ms median, 25 runs
issues fixed58
  • ›grit diff help says no-argument diff shows uncommitted changes but it shows only unstaged changes#16558658d348

    No-argument `grit diff` now uses the same HEAD-to-worktree scope for patch, stat, name-only, name-status, and numstat output. Staged-only files therefore appear alongside unstaged files, while explicit path-limited behavior is preserved.

  • ›Files inside a re-included dir (`*` + `!pkg/`) are treated as not ignored: status lists them, add stages them#1650393c7fa3

    Directory-only ignore patterns now participate only when the queried path is a directory. This prevents `!pkg/` from accidentally overriding an earlier `*` for files below `pkg`, so status, ignore check, and add agree with Git.

  • ›grit reset --json always reports orphaned_commits: [] even when commits become unreachable#16529becd2af

    Reset orphan detection now recognizes the worktree whose HEAD is being moved even when repository discovery and worktree enumeration spell the same path differently. This prevents that old HEAD tip from being hidden as externally reachable, allowing reset output to report the commits it actually makes unreachable.

  • ›grit clone/fetch of an empty repository over ssh fails (exit 128/1); push to it prints a spurious fatal#1657a92df362

    Adds regression coverage around empty bare repositories served by system Git over the SSH transport. It covers advertisement parsing, handshake completion, no-op fetch, clone success and empty-remote messaging, and successful push without receive-pack’s spurious hung-up diagnostic; production behavior is unchanged.

  • ›grit push over ssh to `grit receive-pack` updates the remote but the client hangs forever#1656a92df362

    Receive-pack now finds the exact end of one incoming pack instead of waiting for the SSH input stream to close. It verifies the pack trailer, ingests the update, and emits report-status while the push client still holds its write side open.

    No-EOF regression completion time: 5.2 seconds → 0.030 seconds (173× better)
  • ›grit fetch aborts all ref updates on a directory/file ref conflict and doesn't suggest --prune#1654386262d6

    Fetch now keeps successful tracking-ref updates when one ref is blocked by a file/directory namespace collision or lock. The blocked row becomes a typed rejection with a reason and, when the blocker is stale, guidance to prune; local, network, and bundle fetch paths share the behavior.

  • ›grit add of 5000 new small files into a fresh repo takes 660ms (git add -A: 300ms), CPU-bound, ignores --threads#1651origin/m

    Bulk staging now reads, converts, hashes, compresses, and stores new worktree blobs in one parallel worker pass, while batching large index insertion. The round-3 correction keeps the fast all-new path for untracked files but restores existing-loose checks for tracked restage and gives every concurrent loose write its own temporary file.

    5,000-file grit add --threads 4 median: 681.1 ms → 564.0 ms (21% better)5,000-file grit add --threads 1 median: 707.4 ms → 693.7 ms (2% better)System git add -A control median: 312.2 ms → 331.5 ms (6% worse)
  • ›grit log -n <N> -S fails with "revision not found" on commits that change a submodule gitlink#1667acbaf6b7

    Gitlink entries are now counted from their synthetic `Subproject commit <oid>` bytes before the pickaxe occurrence cache can read the referenced OID. This prevents bounded `-S` history walks from trying to load submodule commits from the superproject object database.

  • ›grit add . aborts with 'index contains unmerged entries' (stages nothing) while any conflicted file still has markers#167099aaa522

    Broad adds during a conflicted merge now stage resolved and unrelated files, persist those index changes, and reject only files that still contain conflict markers. The failure names every rejected repository-relative path and appears consistently in human, JSON, and Markdown CLI modes.

  • ›grit clone writes index without TREE (cache-tree) ext: diff 8x, status 2-4x slower than git until rewritten#1676d41f277f

    Populated checkout now carries its known result tree through index writing and rebuilds the cache-tree when bulk index replacement cleared it. Fresh grit clones therefore write the standard TREE extension immediately, avoiding repeated full index/tree reconstruction in later status and diff operations.

    10k-file grit status median: 0.061 seconds → 0.022 seconds (2.8× better)10k-file grit diff median: 0.042 seconds → 0.015 seconds (2.9× better)10k-file clone median (5 repeats): 0.154 seconds → 0.157 seconds (2% worse)
  • ›grit-lib RevWalk::walk/rev_list ignores max_count and commit-graph: -n10 takes 500ms on git/git (git: 3ms)#1680caaf6f46

    Default `RevListOptions` now selects the existing bounded walk and commit-graph paths, so library callers using `RevWalk::walk` no longer materialize all history for a small max-count. The options are normalized against repository commit-graph configuration, and public docs/tests describe and verify the behavior.

    git/git RevWalk max_count=10, old-default-equivalent to branch default median: 924.7 ms → 0.656 ms (1410× better)git/git full RevWalk, old-default-equivalent to branch default median: 920.7 ms → 900.8 ms (2% better)git/git max_count=10, system Git to branch default median: 1.5 ms → 0.656 ms (2.2× better)git/git full listing, system Git to branch default median: 106.9 ms → 900.8 ms (88% worse)
  • ›Windows main: grit switch tag<->master on git/git takes 0.9-18s, highly erratic (git: 1.5s steady); #1193 not fixed#1613bfb15c09

    This change removes expensive Windows switch-preparation metadata patterns while preserving checkout safety. It narrows unstaged worktree diffing to paths proven suspicious, serializes the default Windows stat preload, and retains safe wholesale-delete scanning, including mixed stat-drift and racily dirty paths.

  • ›create_commit accepts "Name <email>" author (as in rustdoc examples) and writes commits that fail git fsck#1681428cc977

    Commit creation now accepts documented contact-form identities, expands them to timestamped Git headers, rejects control-character injection, and validates serialized identity headers before writing an object. The round-2 correction preserves Git-style author-date override behavior for inherited malformed/non-numeric date tails.

  • ›grit add/commit of many new files is quadratic: 20k files 9s, 40k 35s, 200k never finishes (git: 9s)#1674ec64fca1

    This change replaces comparator-time linear index scans with one stage-0 path-to-position map, then sorts stage outcome paths using constant-time map lookups. It also adds a reproducible 20k-file initial-add benchmark and records a baseline for the docs site.

    20k initial grit add wall time: 8.4 seconds → 0.720 seconds (12× better)20k auto-stage commit wall time: 9.0 seconds → 1.2 seconds (7.3× better)20k initial grit add peak RSS: 42,660 KiB → 42,924 KiB (1% worse)20k auto-stage commit peak RSS: 43,080 KiB → 43,684 KiB (1% worse)
  • ›grit rebase of 20 commits onto a moving main on git/git takes 3.1s (git: 0.15s), 140MB RSS#1668696d4b1f

    Rebase planning now enumerates only commits reachable from the feature tip while hiding the fork’s ancestors, then topologically orders that small set. It reuses the range across planning stages and makes the bounded walk honor repository grafts consistently.

    git/git rebase --check median wall time: 3,132 ms → 92.5 ms (34× better)git/git rebase --check peak RSS: 136,972 KiB → 32,532 KiB (4.2× better)
  • ›v0.5.18 Windows: 49k-file deep tree, 100 files touched: diff 3.1-4.8x, add 3.1x, commit 2.4x slower than git#1622e60d0833

    Routes update and explicit-path staging through a directory-grouped tracked scan, preserving an explicit empty restriction when no tracked index path matches. It also avoids redundant staged-commit and Windows path-stat work while retaining index/tree correctness, with regression and metadata-budget coverage.

    Explicit tracked add, 49k files (git baseline 25.583 ms): 57.4 ms median → 30.4 ms median (89% better)Explicit untracked add, 49k files (git baseline 24.009 ms): 62.0 ms median → 33.5 ms median (85% better)Staged commit, 49k files (git baseline 53.798 ms): 83.4 ms median → 58.1 ms median (44% better)Default add, 49k files (git baseline 57.957 ms): 105.6 ms median → 103.7 ms median (2% better)
  • ›grit add of 49k new files into a fresh repo takes 55 s (git add -A: 2 s): quadratic in file count#1673dba9c630

    This replaces the quadratic add-outcome sorter with one stage-0 path-position map, making each comparison a constant-time lookup. It also maps lossy display bytes for non-UTF-8 paths, preserving tracked-scan ordering that the first review found could otherwise regress.

    49,152-file grit add wall time: 45.4 seconds → 2.0 seconds (22× better)49,152-file grit add / system Git wall-time ratio: 16.1 ratio → 0.717 ratio (22× better)
  • ›grit gc/repack of loose objects is ~7-10x slower than git gc (and up to 2x larger pack) on Windows#1653ed7ead36

    This change restructures repack planning around shared payloads, reuses delta indexes and selected encodings, parallelizes loose-blob reads, and co-generates trusted pack-index rows. It also repairs the bitmap streaming writer so it retrieves real object bytes instead of serializing empty planned entries.

    600-loose-object gc median: origin/main to review branch: 1,954 ms → 410.6 ms (4.8× better)600-loose-object gc median: system git to review branch: 91.6 ms → 410.6 ms (78% worse)Median pack size: origin/main to review branch: 107,496 bytes → 105,515 bytes (2% better)Median pack size: system git to review branch: 87,418 bytes → 105,515 bytes (17% worse)
  • ›grit merge --continue after resolving by editing (no grit add) re-prints CONFLICT and fails; grit commit accepts it#1687e12b42ed

    Merge continuation now uses the same configurable auto-stage policy as normal commits. After users edit away conflict markers, the default flow stages the resolved worktree in memory and records the merge instead of reporting the old conflicts again; the CLI now surfaces genuine continuation errors rather than synthesizing a second conflict outcome.

  • ›grit add after editing 5000 tracked files in a 200k-file repo takes 5.9s (git add -A: 0.63s), cost grows with index size#1679f38d3b39

    Add outcomes now build one stage-0 path-to-index-position map and use constant-time comparator lookups instead of rescanning the full index for every comparison. The round-2 correction keys that map with the same UTF-8/lossy strings exposed by StageOutcome, preserving index order for legal non-UTF-8 paths.

    50k tracked / 5k modified add median (3 fresh clones): 1.1 seconds → 0.628 seconds (72% better)patched grit versus system git add median: 0.649 seconds → 0.628 seconds (3% better)50k/5k peak RSS median: 77,604 KiB → 79,448 KiB (2% worse)
  • ›grit diff between two tags on git/git is 9-12x slower than git (2.5-3.6 s vs 0.26-0.78 s): inexact rename detection#1683be76731a

    Caches each blob’s normalized rename-line hash/weight table once and reuses it across all inexact rename and copy candidate comparisons. This preserves existing grit results while removing repeated per-pair line hashing from the hot path.

    git/git name-status rename mean: 2,518 ms → 917.0 ms (2.7× better)rename slowdown versus system git: 8.9 x → 3.3 x (2.7× better)git/git name-status peak RSS: 83,648 KiB → 90,512 KiB (8% worse)git/git no-renames mean: 11.2 ms → 10.6 ms (6% better)
  • ›grit-lib: common failures (no work tree, file not in revision, empty message) are Error::Message strings, inconsistent#16852f61644f

    Common embedder failures now expose stable typed errors instead of message strings. The round-two fix makes missing blame paths consistent across blame_file and compute_blame by classifying the error in their shared compute path, while preserving the caller-facing revision label.

  • ›grit reset (every mode, even --dry-run) fails 'corrupt object' in repos with a tag pointing to a blob, e.g. git/git#168859f59dea

    Reset's orphan calculation now peels every non-moving ref and worktree tip and retains it only when it names a commit. The shared two-sided reachability painter also skips non-commit tips defensively, preventing blob/tree tags from being interpreted as commits.

  • ›grit gc/repack on a fresh clone: 275s/3.4GB RSS on cargo (git: 1.7s), OOM-killed on git/git#1038c0587011

    This change avoids rebuilding an already consolidated clone while preserving garbage-collection semantics. A single-pack/no-loose repository skips repack only after proving that the active prune policy would not remove any packed object; full rewrites without loose objects use existing packed bytes instead of an expensive fresh delta search.

    Cargo clone gc wall time: 104.2 seconds → 4.1 seconds (25× better)Cargo clone gc peak RSS: 3,679,372 KB → 169,892 KB (22× better)Wall-time ratio versus system Git: 58.4 x → 2.3 x (25× better)Peak-RSS ratio versus system Git: 21.8 x → 1.0 x (22× better)
  • ›grit clone checkout of a 200k-file repo peaks at 537 MB RSS and is 1.5x slower than git (git: 57 MB, 3.8s)#1678b63c4c7f

    Initial checkout now walks a populated tree in bounded chunks instead of retaining a full-tree diff, while preserving conversion attributes and promisor-object fetching across both bulk and fallback materialization. It returns a Git-clean worktree and complete index for large repositories.

  • ›grit revs A..B walks the entire history: 800ms/126MB on git/git for a 20-commit range (git rev-list: 2ms/12MB)#16696410249f

    Plain revision counts with exclusion tips now stop at the hidden ancestry boundary instead of materializing the whole include and exclude histories. The CLI inherits the improvement through the existing RevWalk::count API, with no CLI, public API, or repository-format change.

    HEAD~20..HEAD median wall time: 103.0 ms → 6.2 ms (17× better)HEAD~20..HEAD peak RSS: 30,868 KB → 20,760 KB (49% better)Slowdown versus system Git median: 54.1 x → 3.2 x (17× better)
  • ›grit diff -- <path> ignores staged changes ('No changes', --exit-code 0) while plain grit diff shows them#1703ad2ffd6d

    Path-limited default diffs now preserve grit's documented “all uncommitted changes” scope. A staged-only file is visible in human and JSON output and causes `--exit-code` to return 1, while the pathspec still excludes unrelated files.

  • ›CRLF conversion ignores /anchored, [class] and dir-scoped * attribute patterns: binary files corrupted on add/checkout#1698d2e27ff7

    CRLF clean/smudge decisions now use the canonical attributes matcher instead of a duplicate simplified glob implementation. Anchored, bracket-class, and directory-scoped `.gitattributes` rules therefore protect binary content correctly during add and checkout.

  • ›grit clone over https peaks at 1.7GB RSS on git/git and 475MB on cargo (git: ~98MB / ~45MB)#167216d15f75

    Pack ingestion now hashes whole objects incrementally, bounds concurrent inflated bytes, limits delta-resolution batches, and avoids materializing the full pack while deciding whether it is thin. The round-two patch prevents oversized-object deadlock and restores SHA-256 thin-pack detection.

    149.9 MB pack index peak RSS, 2 threads: 787,680 KB → 593,960 KB (33% better)149.9 MB pack index elapsed time, 2 threads: 4.7 seconds → 5.4 seconds (14% worse)cargo HTTPS clone peak RSS: system git vs branch: 45,652 KB → 339,872 KB (87% worse)cargo HTTPS clone elapsed: system git vs branch: 4.3 seconds → 4.4 seconds (2% worse)
  • ›Windows: clean-tree grit status re-reads every tracked file (1.25 s vs git 16 ms on 240 MB); 3.5-5x slower on cargo/git#170227cab42f

    This change lets Windows clean-tree status trust matching index metadata instead of rereading tracked file contents, while preserving content verification for racily clean entries. It also avoids a duplicate hash after a non-racy stat refresh and adds Git-oracle regressions for the performance and racy-correctness paths.

  • ›grit repack/gc on rust-lang/cargo: 18-111s and 3.5-3.7 GB RSS (git repack -adf: 5-6s / 450 MB, git gc: 1.2s)#1690eeea226d

    This change adds a GC/repack fast path for already packed repositories and chooses on-disk delta reuse for pack-only rewrites. It also adds a public force-recompression option, updates stats to distinguish skipped writes, and documents/tests the behavior.

    rust-lang/cargo mirror repack wall time (origin/main vs branch no-op): 153.8 seconds → 0.011 seconds (13980× better)rust-lang/cargo mirror GC wall time (origin/main vs branch): 297.8 seconds → 3.7 seconds (80× better)rust-lang/cargo actual rewrite wall time (system git -adf vs branch two-pack rewrite): 9.5 seconds → 146.6 seconds (93% worse)
  • ›grit add right after grit clone of git/git fails ~60% of runs: 'could not store <path>: No such file or directory'#1677b6dd22de

    Clean tracked files are now hashed before any loose-object write, so a clean add after clone refreshes index metadata without duplicating packed blobs. Parallel loose publication uses per-object/process/thread/attempt temporary names and bounded ENOENT retries, while preserving required loose materialization for objects found only in cruft packs.

    Clean add median on 4,857-file git/git checkout (origin/main → branch, 5 runs each): 161 ms → 153 ms (5% better)Clean add median against system Git on the same checkout (system Git → reviewed branch, 5 runs each): 166 ms → 153 ms (8% better)
  • ›grit tag --contains <rev> never finishes on cargo (124 tags, >250s CPU) and git/git (git: 0.16s / 0.5s)#168982c7b306

    Replaces the super-linear stack propagation used by ref `--contains` queries with one shared generation/date-ordered heap walk carrying merged tip bitsets. The round-2 correction keeps commit dates strictly as heap ordering data, restoring generation semantics for merge-base and other callers.

    Cargo tag --contains HEAD~5000 wall time (origin/main timeout lower bound → patch median): 30.0 seconds → 0.211 seconds (142× better)
  • ›grit add <paths> on a 48k-file tree scales ~3.5ms per path: 98 paths 360-540ms (git: <10ms); add . 4x, commit 4x#1682cda8b5bb

    Routes ordinary literal add pathspecs through a tracked-index scan narrowed to matching paths, instead of repeatedly matching every pathspec against the entire large index. Validation retains conflict-stage correctness through direct stage 1–3 lookups and one shared unmerged-path list, while tracked refresh now preserves file↔symlink type changes when core.filemode is false.

    48k fixture, 1 dirty file and 1 pathspec: 32.1 ms median → 28.0 ms median (15% better)48k fixture, 1 dirty file and 98 pathspecs: 222.5 ms median → 46.6 ms median (4.8× better)1-to-98 pathspec scaling: 6.9 x → 1.7 x (4.1× better)98 dirty files, branch grit vs system git: 73.7 ms median (system git before, branch grit after) → 52.6 ms median (system git before, branch grit after) (40% better)
  • ›grit repack/gc on rust-lang/cargo: 18-111s and 3.5-3.7 GB RSS (git repack -adf: 5-6s / 450 MB, git gc: 1.2s)#169007fc2518

    Reuse-only repacks now enumerate reachable objects without retaining every object body in memory. Traversal still reads commits, trees, and tags as needed and preserves the send list, while blob payloads remain on disk until pack serialization.

    Fresh Grit-clone Cargo repack wall time: 7.7 seconds → 3.8 seconds (100% better)Fresh Grit-clone Cargo repack peak RSS: 2,174,928 KiB → 595,576 KiB (3.7× better)Fresh Grit-clone Cargo resulting pack size: 82,547 KiB → 82,550 KiB (0% worse)
  • ›Follow-up: Fix #1653: grit gc/repack of loose objects is ~7-10x slower than git gc (and up to 2x larger pack) on Windows#1653

    This change makes loose-object gc pack selection deterministic, routes pack serialization through configured zlib compression (including true level 0), and avoids parallel preparation overhead for packs below 2,048 entries. It relocates the issue-1653 CLI regression to grit-cli so Cargo supplies the binary, but currently deletes and relaxes an existing library regression.

    600-object gc median: 619.4 ms → 626.4 ms (1% worse)600-object pack size: 112,534 bytes → 90,502 bytes (24% better)pack-size ratio versus system Git: 1.6 ratio → 1.3 ratio (24% better)
  • ›Follow-up: Fix #1682: grit add <paths> on a 48k-file tree scales ~3.5ms per path: 98 paths 360-540ms (git: <10ms); add . 4x, commit 4x#1682649461ed

    This change ensures a blob-to-symlink type change is restaged even when core.filemode=false and the worktree object ID equals the index object ID. It adds a system-Git index oracle plus strict fsck regression, and the final commit message now satisfies review policy.

    48k one-path add: 32.5 ms → 32.0 ms (1% better)48k one-dirty-file, 98-path add: 49.8 ms → 53.3 ms (6% worse)
  • ›Follow-up: Fix #1690: grit repack/gc on rust-lang/cargo: 18-111s and 3.5-3.7 GB RSS (git repack -adf: 5-6s / 450 MB, git gc: 1.2s)#1690ff616edc

    This change makes GC’s fast single-pack skip conditional on being an automatic GC optimization with no requested repack side effects. It also strengthens the bitmap regression so it proves GC actually rebuilt the pack instead of accepting a bitmap created by fixture setup.

  • ›grit-http-server: every push larger than ~2 MB fails with HTTP 413 (axum default body limit)#1740b4087912

    This change removes Axum's effective 2 MiB receive-pack request cap by streaming push bodies into grit-protocol on a blocking reader. It keeps fetch requests capped at 32 MiB and adds a typed gzip expansion guard for pushes, allowing normal large gzip streams while refusing bombs and malformed streams with deliberate client errors.

  • ›fetch into a repo with a custom ODB primary returns Ok but writes a pack to disk; fetched objects are 'not found'#17359d84c67d

    Custom-primary repositories now fail safely and immediately when fetch, push, fsck, or unbundle would bypass their configured object store. Bulk staging and auto-stage commits now write through the custom primary, while files-backed transport behavior remains unchanged.

    10k-file add median: 173.6 ms → 175.3 ms (1% worse)file fetch median (1,001 commits, 333,031-byte pack): 2.3 ms → 2.4 ms (4% worse)
  • ›ObjectStore::lookup_prefix default allocates a hex String per object: abbreviate = 19ms at 200k objects#173612306622

    Adds a parsed object-id prefix that compares digest bytes without per-object hex allocation and exposes exact lower/upper bounds for indexed custom stores. Abbreviation now scans the minimum prefix once and derives the unique length from the candidates, while all built-in stores share the same prefix representation.

    MemoryStore: abbreviate 200 ids over 200k objects: 3,970 ms → 152.4 ms (26× better)Default lookup: abbreviate 200 ids over 200k objects: 3,919 ms → 239.2 ms (16× better)Files ODB: abbreviate 200 ids over 200k packed objects: 719.0 µs → 609.1 µs (18% better)grit log --oneline -n 5000 median, main to branch: 104.8 ms → 101.7 ms (3% better)
  • ›porcelain commit/switch ignore Repository::with_ref_store: refs, HEAD and reflogs written to .git on disk#17334af3b2ad

    Porcelain ref mutations now consistently use the Repository's configured RefStore instead of reopening .git-backed files. The round-two fix closes the remaining false-success switch path by installing symbolic or detached HEAD even when the injected store initially has no valid HEAD.

  • ›Windows: every hook fails (exit 1, no output) - hook script path passed to sh as \\?\C:\... verbatim path#17425794bc47

    Hook scripts now receive usable child-process paths and an explicitly resolved interpreter on Windows instead of an MSYS-incompatible verbatim path. Spawn failures are typed and retain their OS cause, while post-commit failures are surfaced as non-fatal diagnostics after the commit has already succeeded.

  • ›grit add <paths> on a 48k-file tree scales ~3.5ms per path: 98 paths 360-540ms (git: <10ms); add . 4x, commit 4x#1682ceaa8b64

    This makes literal pathspec matching fast when macOS Unicode precomposition is enabled and resolves many argv pathspecs without reloading config or probing `.git` for every argument. It adds a Repository-scoped typed resolver, routes library and thin CLI call sites through it, and tests both Unicode correctness and cached resolution.

    48k fixture, 98-path overhead: 50.8 ms → 47.5 ms (7% better)48k fixture, 1-to-98 pathspec scaling: 1.8 x → 1.6 x (13% better)48k fixture, 98 dirty paths staged by grit: 50.2 ms → 48.7 ms (3% better)48k fixture, grit/system-git ratio for 98 dirty paths: 0.740 x → 0.690 x (7% better)
  • ›grit-lib rev_list/RevWalk full-history walk ignores the commit-graph: git/git 700 ms vs git rev-list 105 ms (6.6x)#17452f66d757

    Graph-backed full-history walks now use commit-graph parent and committer-time data without inflating every commit merely to cache its subject or tree. Subjects and commit payloads remain lazy for callers that render rows, while graph lookup reuse removes repeated binary searches.

    git/git graph-backed full-history rev_list median: 832.4 ms → 125.1 ms (6.7× better)rev_list slowdown versus system git (82 ms median): 10.2 x → 1.5 x (6.7× better)
  • ›grit clone over https peaks at 1.7GB RSS on git/git and 475MB on cargo (git: ~98MB / ~45MB)#16720b8996ff

    This branch replaces lifetime-retained inflated pack objects with pack-backed delta metadata, iteratively resolves deep chains, streams whole-object hashing through the hash abstraction, and restores bounded two-worker resolution. The latest follow-up selectively restores owned inflated bases to regain speed, but that selection currently retains enough payloads to exceed a gigabyte on the cargo pack.

    cargo pack index median RSS: origin/main to branch: 344,848 KB → 1,041,716 KB (67% worse)cargo pack index median elapsed: origin/main to branch: 2.5 seconds → 3.3 seconds (24% worse)cargo pack index median RSS: system Git to branch: 29,940 KB → 1,041,716 KB (97% worse)cargo pack index median elapsed: system Git to branch: 3.6 seconds → 3.3 seconds (11% better)
  • ›grit gc on already-packed git/git: 47s vs git gc 6.2s; prune with 0 loose objects alone takes 13s (git: 0.00s)#17474b8c7800

    Garbage collection now avoids object-graph walks when a fresh single pack or the loose-object grace window makes them unnecessary. When a walk is needed, repack and prune share one lazy reachable set, while gc preserves existing commit-graph Bloom-filter policy instead of paying to create filters on first write.

    git/git gc wall time: 50.2 seconds → 1.4 seconds (37× better)git/git gc peak RSS: 437,388 KB → 104,828 KB (4.2× better)git/git prune wall time with zero loose objects: 13.8 seconds → 0.010 seconds (1382× better)git/git prune peak RSS with zero loose objects: 415,980 KB → 18,644 KB (22× better)
  • ›RefStore backends disagree: Memory/Reftable accept invalid ref names; all accept Direct(zero oid)#1738acd9f3ef

    All built-in ref stores now reject malformed transaction names and all-zero direct object IDs at prepare time, before locking or writing. The behavior is covered across files, memory, and reftable, with a files-backend round-trip proving rejected writes leave a repository clean for system Git.

    10k files-ref transaction median: 18.7 seconds → 18.5 seconds (1% better)10k reftable transaction median: 1.9 seconds → 2.0 seconds (4% worse)10k memory transaction median: 0.188 seconds → 0.172 seconds (9% better)
  • ›grit-lib has no typed way to create trees/commits: Objects::write accepts unsorted trees and commits git fsck rejects#1746b204f63a

    Adds safe, typed ways for embedders to create Git trees and commits without an index or worktree. Raw `Objects::write` now rejects malformed structured objects before storage, while an explicit literal-write escape hatch remains for corruption tests.

    10k-entry validated tree write: 1,130 µs/op → 894.5 µs/op (26% better)
  • ›macOS: documented OdbBuilder/RepositoryBuilder example fails under default $TMPDIR (/var -> /private/var mismatch)#1749cdf7bb22

    RepositoryBuilder now treats symlinked, relative, and canonical spellings of the same object directory as identical. It canonicalizes both sides of the custom ODB comparison, retains rejection of genuinely different directories, and turns the previously stale documentation snippet into a compiled example.

    Valid symlinked objects-directory spellings accepted: 1 of 2 measured scenarios → 2 of 2 measured scenarios (2.0× better)
  • ›MemoryRefStore deadlocks (hangs forever) when a for_each_ref / for_each_reflog_ref callback calls back into the store#1750af071649

    MemoryRefStore iteration no longer holds its non-reentrant mutex while invoking caller callbacks. Walks retain an Arc snapshot, allowing callback reads, nested walks, and writes without deadlocking while preserving a stable in-progress view.

    Exact deadlock reproduction completion: 2.0 seconds (baseline timed out at exit 124; branch exited 0) → 0.003 seconds (baseline timed out at exit 124; branch exited 0) (669× better)for_each_ref over 100k refs, median of 5 runs: 2,425 microseconds → 2,473 microseconds (2% worse)for_each_ref prefix miss, median of 5 runs: 0.066 microseconds → 0.077 microseconds (14% worse)for_each_reflog_entry over 1k entries, median of 5 runs: 1.4 microseconds → 1.1 microseconds (22% better)
  • ›Windows: clean-tree grit status re-reads every tracked file (1.25 s vs git 16 ms on 240 MB); 3.5-5x slower on cargo/git#1702dfd36404

    This change makes clean status trust valid index stat data, persists verified racy-index refreshes, and removes avoidable tracked/untracked filesystem probes. It also preserves correctness for smudged entries and symlinked ignore files, with Git-compatible regression coverage.

    60×4 MiB clean status, origin/main → branch: 642.0 ms median, 25 runs → 2.6 ms median, 25 runs (252× better)60×4 MiB tracked-only status, origin/main → branch: 641.7 ms median, 25 runs → 2.4 ms median, 25 runs (272× better)3,000-file nested clean status, origin/main → branch: 21.9 ms median, 25 runs → 4.9 ms median, 25 runs (4.4× better)3,000-file nested tracked-only status, origin/main → branch: 20.8 ms median, 25 runs → 3.8 ms median, 25 runs (5.4× better)
  • ›grit blame Makefile on git/git: 1.87 s / 885 MB vs git 0.53 s / 283 MB (3.5x time, 3.1x memory) on macOS arm64#1752cbdb7341

    Blame now coalesces pending lines by commit and path in a date-ordered suspect queue, avoiding repeated traversal of shared merge ancestry. It also bounds retained blob and diff-map data, fixes an empty-parent panic for merges that introduce a path, and adds Git-parity coverage plus a realistic merge-heavy benchmark.

    git/git Makefile median wall time: 2.7 seconds → 1.2 seconds (2.3× better)git/git Makefile median peak RSS: 803,268 KiB → 338,228 KiB (2.4× better)system Git vs branch median wall time: 1.0 seconds → 1.2 seconds (12% worse)system Git vs branch median peak RSS: 290,608 KiB → 338,228 KiB (14% worse)
  • ›grit upload-pack serving a full clone of cargo takes 97s and 3.6 GB RSS (git upload-pack: 5.4s, 165 MB)#1744ad2d1292

    Caches reverse-index offset lookup, keeps reusable packed payloads on disk, avoids redundant object-walk path/payload work, and streams upload-pack output through sideband instead of materializing the full response. The round-2 amendment correctly traverses trees whose directory mode has non-canonical permission bits.

    cargo full-clone upload-pack server time: 95.1 seconds → 2.9 seconds (33× better)cargo full-clone upload-pack peak RSS: 3,673,560 KB → 427,760 KB (8.6× better)server time relative to system git: 30.1 x → 0.920 x (33× better)peak RSS relative to system git: 22.2 x → 2.6 x (8.6× better)
  • ›receive-pack: receive.denyNonFastForwards=true rejects genuine fast-forward pushes as non-fast-forward#1741f46d0e2d

    Receive-pack now evaluates branch ancestry through the quarantine-aware ODB, so newly pushed commits are visible before migration. The new exact two-sided paint walk remains correct under non-monotonic commit dates and can use corrected commit-graph generations as a safe bound.

    50k no-graph fast-forward median: 6.1 ms (before wrongly refused; after accepted; system git 10.022 ms) → 6.5 ms (before wrongly refused; after accepted; system git 10.022 ms) (6% worse)50k commit-graph fast-forward median: 6.4 ms (before wrongly refused; after accepted; system git 10.591 ms) → 6.3 ms (before wrongly refused; after accepted; system git 10.591 ms) (1% better)
  • ›Follow-up: Fix #1672: grit clone over https peaks at 1.7GB RSS on git/git and 475MB on cargo (git: ~98MB / ~45MB)#1672e71b04fa

    Replaces breadth-first pack delta rounds with per-root depth-first walks. Workers release parent payloads after their final child, cap retained ancestor bytes at 16 MiB per worker, and rebuild evicted ancestors only when a later sibling needs them.

    cargo pack index time: current main to branch (2 threads, median of 3): 2.8 seconds → 1.9 seconds (48% better)cargo pack peak RSS: current main to branch (2 threads, median of 3): 402,644 KB → 150,384 KB (2.7× better)cargo pack index time: system Git to branch (2 threads, median of 3): 4.6 seconds → 1.9 seconds (2.4× better)cargo pack peak RSS: system Git to branch (2 threads, median of 3): 33,528 KB → 150,384 KB (78% worse)
  • ›grit-lib: add::stage of a new file and commit_worktree fail with UnsupportedObjectStore on a custom ODB#1748a363027e

    Porcelain add and commit can now stage new and bulk-restaged files into a custom object-store primary instead of requiring filesystem loose-object writes. Repository fsck now validates objects provided by a custom primary, and tests prove those objects stay out of `.git/objects` and remain valid when exported for system Git.

    20k-file tracked add, grit release mean: 334.1 ms → 340.5 ms (2% worse)20k-file tracked add, branch versus system git mean: 451.5 ms → 340.5 ms (33% better)20k-file tracked add peak RSS median: 47.5 MiB → 47.9 MiB (1% worse)
  • ›grit-lib serve API: whole packs buffered in memory, no policy callbacks, string-typed results, no server docs/example#1757d23f3c22

    Push packs are streamed to a quarantine temp file, then unpacked or indexed without the old whole-pack Vec/copy/reverify path. Embedders gain typed refusal/unpack outcomes and Rust policy hooks, receive-pack scripts get GIT_DIR=., and a tested server example plus network docs make the public API discoverable.

    77.8 MB Cargo push wall time: current main vs branch: 10.6 seconds → 4.5 seconds (2.3× better)77.8 MB Cargo push peak RSS: current main vs branch: 1,000,528 KiB → 338,380 KiB (3.0× better)77.8 MB Cargo push wall time: system Git vs branch: 5.0 seconds → 4.5 seconds (10% better)77.8 MB Cargo push peak RSS: system Git vs branch: 175,996 KiB → 338,380 KiB (48% worse)
other changes14
  • ›Quality #26: Deduplicate8cc0174b

    Adds one typed, kind-checked path for reading a commit or only its root tree, exposed on both Odb and repository-scoped Objects. It replaces private read/check/parse helpers across history, stash, merge, pull, bitmap, commit-graph, fixtures, examples, and docs, cutting 200 net lines.

    stash-push-pop-10000 median: 353.8 ms → 372.9 ms (5% worse)merge-10000 median: 72.3 ms → 73.2 ms (1% worse)history-reword-smoke repeated median: 14.5 ms → 15.0 ms (3% worse)
  • ›Speed: log/oneline-100@git-git4a8382ed

    This change removes fixed startup work by deferring clap construction to the selected command, while preserving full-tree help and completions. It also reduces allocations in bounded retained revwalks and reuses the trusted single-pack reader within a thread-scoped ODB read context.

    log/oneline-100 time: 5.4 ms median (20 runs) → 4.4 ms median (20 runs) (23% better)log/oneline-100 peak RSS: 22.3 MiB → 22.1 MiB (1% better)log/json-100 time: 5.5 ms median (20 runs) → 5.2 ms median (20 runs) (6% better)log/json-100 peak RSS: 23.9 MiB → 22.7 MiB (5% better)
  • ›Main keeper: make CI on main green (scripts, test, coverage, rustdoc)dba965bc

    This branch repairs the CI failures across CLI contracts/snapshots, rustdoc/public API checks, and merge dry-run exit behavior. Round 2 also makes ephemeral snapshot-path redaction portable beyond Linux and fixes the one prohibited commit subject.

  • ›Main keeper: make CI on main green (test-threaded, test, public-api)ec64fca1

    Restores the CLI schema/doc validation infrastructure needed by CI, refreshes affected committed contracts, and synchronizes the public API snapshot. The round-two correction ensures clone validation and drift checks use the published v3 contract rather than v2.

  • ›Main keeper: make CI on main green (public-api, test, test-threaded)74b03d6e

    This branch repairs the main-CI regressions around add hunk context, config unset argument validation, generated snapshots, and the grit-lib public API snapshot. The round-2 amendment preserves the frozen add v1 JSON contract and introduces add v2 for the newly stable `staged_hunks` and `staged_lines` keys.

    committed add schema versions: 1 schema documents → 2 schema documents (2.0× better)
  • ›Main keeper: make CI on main green (test)fba4b9f8

    This change lets the shared argv preprocessor recognize `add` as a command eligible for attached diff-flag normalization, rewriting `-U0` to clap's explicit `-U=0` shape before parsing. It also adds a direct unit test for the `grit add --hunks … -U0` argument sequence.

  • ›Speed: branch/list-json@many-refsad6fad99

    Branch and tag queries now reuse the files ref store's stamp-validated packed-refs view instead of mapping and indexing the same large file multiple times. Branch listing also avoids unused per-tip peels and parallel-thread-policy setup for a single listed branch, while preserving peeling whenever reachability or points-at filters need it.

    branch/list-json direct wall: 3.8 ms median, 200 runs → 3.4 ms median, 200 runs (10% better)branch/list-json direct peak RSS: 13.7 MiB → 13.4 MiB (2% better)branch/list direct wall: 3.7 ms median, 200 runs → 3.2 ms median, 200 runs (14% better)
  • ›Quality #27: Simplify98cb0fd1

    Deletes the second, flattened repository-fsck facade from maintenance and leaves repository_fsck as the single supported API. Existing tests now call that canonical API directly, including explicit progress/cancellation and severity evaluation, while the ref-formatting coverage moves beside the implementation it exercises.

  • ›Quality #28: Library API qualityd6712925

    Linked-worktree add, remove, move, lock, unlock, and repair now expose structured WorktreeError values instead of free-form Error::Message strings. The refactor also centralizes registered-worktree lookup, reuses BranchError and Odb::commit_tree, and adds public-API compatibility tests against system Git.

    worktree add median wall: 145.9 ms → 141.4 ms (3% better)
  • ›Main keeper: make CI on main green (test)c8a94981

    This corrects tracked-file staging when an indexed gitlink is replaced by a regular file. The replacement is now staged as a normal blob with regular-file mode, including when `core.filemode=false`, while actual directory-backed submodules keep their existing path.

  • ›Quality #29: Move logic into grit-libf530ca7c

    Adds a presentation-free grit-lib operation that verifies an annotated tag by short name and returns its ref oid, target oid, and verification report. The CLI now only invokes that operation, translates typed errors, and renders the existing output.

    git.git verify digest, main→branch: 81.2 ms mean → 76.7 ms mean (6% better)git.git verify signed, main→branch: 75.0 ms mean → 78.2 ms mean (4% worse)Chromium synth verify digest, main→branch: 3.9 ms mean → 4.0 ms mean (2% worse)
  • ›Quality #30: Dead code and dependencies3b3553cd

    Removes obsolete grit-lib helper APIs left over from the retired Git-compatible CLI and coverage-only test calls, then deletes their now-unreachable private implementations. The result is 1,732 net lines smaller, with no production call path changed.

    Lines in the 18 changed source files: 16,220 lines → 14,660 lines (11% better)Public API snapshot entries/lines: 25,716 lines → 25,639 lines (0% better)Net review diff size: 1,761 removed vs added lines → 29 removed vs added lines (61× better)
  • ›Speed: restore/hunks@large-file949c4c50

    This removes per-line ownership and repeated intermediate conversions from the xdiff path used by hunk restore, makes hunk application borrow untouched preimage rows, and avoids writing an unreachable loose blob merely to derive its object ID. The external library and CLI APIs are unchanged; compatibility tests confirm selected restore content, clean full restore, ident expansion, fsck validity, and absence of the synthetic loose object.

    restore/hunks@large-file median time: 50.1 ms → 18.6 ms (2.7× better)restore/hunks@large-file median peak RSS: 40.1 MB → 24.3 MB (65% better)restore/hunks time / system git: 5.7 x → 2.1 x (2.7× better)restore/hunks RSS / system git: 6.2 x → 3.8 x (65% better)
  • ›Speed: remote/show@many-refs6cb3c91f

    Remote inspection now loads each standard remote-tracking prefix once and classifies advertised branches by set membership, eliminating repeated packed-ref parsing. The round-2 correction limits that cache to directory-like wildcard destinations and preserves direct resolution for unusual prefixes, retaining correctness on both files and reftable backends.

    remote/show@many-refs median: 535.5 ms → 22.2 ms (24× better)remote/show@many-refs vs system git: 11.9 x → 0.585 x (20× better)remote/show@many-refs peak RSS: 19,079,168 bytes → 18,853,888 bytes (1% better)remote/list@small median: 3.3 ms → 2.2 ms (49% better)
$ git log --oneline d3efb57d..v0.5.20compare on GitHub ↗
d23f3c22docs: serving fetches and pushes from grit-lib, with a server example
ad721e3aserve: stream pushed packs to disk, type refusals, add ReceiveHook
1cabc14chooks: run receive-pack hook scripts with GIT_DIR=.
a363027efsck: validate objects in a custom primary store
8e5f4c44worktree_batch: skip loose compression when staging into a custom primary
e71b04faMerge branch 'factory/clone-rss-owned-base'
1f618e37pack index: keep the hygiene scanner able to strip the test module
6291596dtest: keep the 3002-deep ofs chain check against git index-pack
4bc1f621docs: describe the depth-first delta resolver and its memory bound
6ae92c4ctest: deep branching git repack chains index byte-identically to git
91c1efcdpack index: resolve deltas depth-first per base instead of in rounds
f46d0e2dMerge branch 'factory/receive-pack-ff-quarantine'
fff78134docs: state that denyNonFastForwards only guards branches
320ab4bfreceive-pack: accept fast-forwards under receive.denyNonFastForwards
7aa76bfemerge_base: make the plain-ODB ancestry walk exact and bounded
ad2d1292Merge branch 'factory/upload-pack-reuse'
220280bcpublic-api: regenerate the snapshot in cargo-public-api order
49da4f7ebench: serve a full clone of git.git without a pack bitmap
5ea3c3a5pack-objects: build walk paths only for objects seen the first time
c891269eupload-pack: build packs with Git's serve settings and stream them
3bda9945pack-objects: keep packed payloads on disk and stream the pack
e4d4cd81pack: decode the offset-to-row table once per pack index
cbdb7341Merge branch 'factory/blame-merge-queue'
3b898495docs: describe blame's date-ordered walk and memory bound
a5286c2ebench: add a merge-heavy blame scenario and refresh the blame baseline
4342edfbdiff: intern blame's xdiff lines with LineInterner
986dcf14blame: walk suspects in one date-ordered queue that merges per commit
dfd36404Merge branch 'factory/status-clean-tree-speed'
6cb3c91fRecord remote show many-refs benchmark before and after
1484192dClassify remote show branches from one tracking-ref listing
3e0f5615docs: describe clean-tree status checks and record the benchmarks
2a7b9422status: hash racily smudged entries even when stat matches
ea6f9875status: persist the index when that clears racy entries
30e48efcworktree scan: stat tracked paths directly outside Windows
c5197567worktree scan: check symlinked ancestors per directory in the scan workers
4f366ac5status: drop per-directory path probes from the untracked walk
42b056b7status: trust matching stat regardless of core.filemode and for empty blobs
af071649refs: let MemoryRefStore iteration callbacks re-enter the store
de59f6b9Merge branch 'factory/fetch-transfer-summary'
fbab2cf8Show clone's transfer summary on fetch and pull
cdf7bb22docs: compile the custom object store repository example
7968f4d8repo: accept any path naming objects/ in RepositoryBuilder::odb_builder
b204f63aobjects: cut tree validation and serialization cost
c6e724d1examples: create trees and commits through the typed object API
4d27bd50objects: validate Objects::write and add typed tree and commit writers
3bda42a5commit: keep the sign of sub-hour negative UTC offsets
acd9f3efMerge branch 'factory/refstore-name-validation'
660c4a55refs: validate transactions the same way on every ref backend
4b8c7800Merge branch 'factory/gc-skip-redundant-walks'
55f7c65bbench: refresh maintenance baseline after the gc walk changes
60dcb023gc: walk the object graph at most once, and only when a step needs it
0b8996ffMerge branch 'factory/clone-pack-rss-1672'
2f66d757revwalk: walk full history from the commit-graph without reading commits
a23491debench: cover full-history default-order walks
ceaa8b64Keep literal pathspec lookups under core.precomposeunicode
38da7254Resolve argv pathspecs without reloading config per path
5794bc47hooks: run scripts through a resolved interpreter and report spawn failures
17c4d71fenvironment: pass captured variables through to hook subprocesses
4af3b2adMerge branch 'factory/porcelain-injected-ref-store'
b49a02cdTest porcelain on injected, files and reftable ref stores; document the guarantee
82132303refs: route porcelain ref, HEAD and reflog writes through the repository's ref store
12306622docs: prefix lookup cost and range overrides for custom stores
c76ad4f8rev-parse: abbreviate with one prefix lookup per id
1a4bb738objects: match object id prefixes on raw bytes in every store
9d84c67dremote: refuse fetch and push on a custom primary object store
a4ab8e83odb: route bulk staging writes through a custom primary store
b4087912grit-http-server: bound gzip expansion of streamed push bodies
d0a2cc0agrit-protocol: expose request stream failures of receive-pack
1f4af44bgrit-http-server: stream push bodies instead of buffering them
379cdd5egrit-protocol: accept receive-pack request bodies as a stream
389e8e5cserve: return the pushed pack without copying it
98972e19public-api: record ObjectPayloadHasher surface
32bb52e9pack index: owned bases on delta chains and ObjectPayloadHasher streaming
b8f5a7bapack index: iterative delta chains, cycle detection, parallel resolve
f7e31a8dpack index: re-resolve delta bases from pack instead of retaining inflated bytes
949c4c50Keep diff compare keys and interned lines as plain slices
14f899a7Borrow unchanged rows when applying hunks to a blob
96be0274Test restore_hunks against git on many hunks and ident files
54d275a8Do not store a blob when restoring hunks in the worktree
b51395ccBorrow diff lines and intern into a compact id table
dcb70963Diff lines without per-line copies in the xdiff pipeline
3b3553cdgrit-lib: remove public helpers only reachable from coverage sweeps
ff616edcMerge branch 'factory/repack-gc-skip-7655'
707b4f67Fixes #1690: force_recompress disables delta reuse; tighten gc repack tests
649461edFix type-change restage when oid matches and filemode is false
f530ca7cMerge branch 'factory/tag-verify-by-name'
0042d9ebtag: verify annotated tags by name in grit-lib
1cdf6fdeGc repack round 4: deterministic deltas, pack.compression=0, issue #1653
07fc2518Update public-api for PackEnumerateOptions::prefetch_walk_objects
5049f27aFix repack memory by skipping blob prefetch on reuse-only repack
c8a94981Stage gitlink-to-file typechanges in tracked-scan add path
d6712925worktree: cover typed refusals through the public API
81348133worktree: report refusals as a typed WorktreeError
98cb0fd1maintenance: remove the flattened fsck wrapper
cda8b5bbFix tracked-scan staging for blob/symlink typechanges with filemode false
5ce972a7Improve grit add perf test failure diagnostics
0ac46b47Fix pathspec validation scaling on large indexes
18062a45Address review feedback on add pathspec perf
b67f7450Fix add perf for many literal pathspecs on large indexes
fba4b9f8Merge branch 'factory/fix-add-hunks-u0'
ad6fad99Merge branch 'factory/branch-list-many-refs'
ed11f28cfix(add): normalize attached -U on grit add --hunks
82c7b306Keep commit_rank_for_walk generation-only without commit-graph
3d95a50aFixes #1689: heap-ordered shared walk for ref --contains
5eec0863bench: record branch and tag daily rows on many-refs around the packed-refs view reuse
ae3e958frefs: build packed-refs peel snapshots from the files store's cached view
2972d4e2branch: skip per-tip peels and thread setup the listing does not use
20898d92refs: list packed refs through the store's cached packed-refs view
74b03d6efix(add): bump stable hunk map keys to add --json v2 schema
91cdb705test(cli): refresh clone network snapshots for clone --json schema
14eaa1f9test(cli): refresh output snapshots after add --json shape
70d6e665test(add): expect empty staged_hunks lines on plain add --json
46bf52c4docs(add): refresh JSON example and add snapshot for stable keys
18029edechore: refresh grit-lib public-api snapshot
ce478550fix(add): always emit staged_hunks and staged_lines in --json
c20fd35afix(config): reject extra value on hot-path --unset
826511b0fix(add): wire -U for hunk staging to match diff context
b6dd22deFixes #1677: harden parallel loose writes after clone add
eeea226dGate repack skip on auto_skip and requested side effects
e58ab060Fixes #1690: skip no-op repack in gc and reuse on-disk deltas
27cab42fMerge branch 'factory/fix-1702-windows-status-stat-f8bb'
16d15f75Merge branch 'factory/pack-index-memory-3836'
b0559f59Fixes #1702: Windows stat trust on clean status without re-reading blobs
d2e27ff7Merge branch 'factory/crlf-attr-patterns-1698'
ef84d054Fix pack index inflight deadlock and SHA-256 thin detection
24dc4ce8Fixes #1672: bound pack index-pack RSS on HTTPS clone
ad2ffd6dMerge branch 'factory/fix-diff-path-staged-1703'
da27226bFixes #1698: route CRLF gitattributes through attributes matcher
6410249fMerge branch 'factory/rev-range-count-fast'
b63c4c7fFix populated-tree checkout prefetch and fallback attribute rules
e395f1b1Fixes #1678: stream populated-tree checkout in chunks
c0587011Merge branch 'factory/gc-repack-perf-1038'
088ca99fFix grit diff path limits ignoring staged-only changes
59f59deaFixes #1688: skip non-commit tips in reset orphan walk
2f61644fMerge branch 'factory/embedder-errors-1685'
b3efd9f2Fix gc auto-skip: repack when pack holds prunable unreachable objects
cb551a7dFixes #1038: skip gc repack on single pack; reuse on-disk bytes when repacking
be76731aMerge branch 'factory/rename-line-table-cache'
f38d3b39Merge branch 'factory/add-sort-index-order-2116'
e12b42edMerge branch 'factory/fix-1687-merge-continue-autostage'
e81d9263Address review: typed missing-path blame in compute_blame
ed7ead36Merge branch 'factory/gc-repack-perf-1653'
0fad0768Docs: note typed embedder error variants in embedding guide
d8e4723bFixes #1685: typed errors for work tree, blame path, empty commit, deep parent
dba9c630Merge branch 'factory/fix-add-index-sort-1673'
e60d0833Fix explicit add staging unrelated tracked paths when pathspec matches only untracked files
a8e14fb8Fixes #1622: faster add/commit on deep trees
696d4b1fMerge branch 'factory/rebase-bounded-revwalk-c990'
004b0831Fixes #1683: cache rename line tables per blob for inexact detection
d728ff85Fixes #1679: stage-0 path map for add outcome sorting
1993c3a2Fixes #1653: gc repack prefetch and skip redundant pack verify
296f07e9Fixes #1653: repack streaming payloads and trusted pack index
f47a72d1Fixes #1653: speed loose-object gc repack.
3851013eFixes #1687: merge --continue auto-stages resolved conflicts
b2b3a6adMerge branch 'factory/ci-green-3811'
c03e18e4Fixes #1673: regression tests for add outcome index-order sort
eb456671Honor grafts in hide-aware revwalk used by rebase
5a985feaFixes #1668: bound rebase revwalk to fork..tip range
ec64fca1Merge branch 'factory/fix-add-quadratic-1674'
428cc977Fixes #1681: normalize commit author and committer identities
bfb15c09Merge branch 'factory/fix-1613-switch-windows-perf'
5b1bbd2efix(schemas): load clone live contract from v3, not v2
8f368ec2fix(ci): complete JSON schema registry and snapshot coverage
beaac55cfix(ci): restore doc JSON schema checks and public-api snapshot
caaf6f46Fixes #1680: RevListOptions defaults use commit-graph and bounded -n
e10d034aFixes #1674: make stage outcome path sort linear in index size
df005560Run racy content hash after stat drift in switch prepare
1d223802Fix switch stat scan collecting all mismatch paths before narrow diff
b1f4034dFixes #1613: cut switch prepare metadata storms on Windows
d41f277fMerge branch 'factory/clone-cache-tree-a63f'
ae421699Fixes #1669: bounded rev-walk count for A..B ranges
a4400489Fixes #1676: persist cache-tree on populated checkout and clone
99aaa522Update public API snapshot for UnmergedConflictMarkers
4b3115e0Fix partial grit add during merge conflicts
acbaf6b7Merge branch 'factory/pickaxe-gitlink-n-1667'
cd1d1f2dblog: roadmap two results and dogfood mode
77f27fa7Fixes #1651: parallelize bulk untracked add and trim loose write overhead
00f83c8aFixes #1667: pickaxe -S with -n skips gitlink ODB reads
386262d6Fixes #1654: partial fetch ref apply on namespace conflict
a92df362Merge branch 'factory/fix-1657-ssh-empty-remote'
074d7bb7Fixes #1656: read one push pack without waiting for stdin EOF
3452ca08Fixes #1657: regression tests for empty SSH remote clone/fetch/push
9becd2afFixes #1652: reset orphan walk skips moving worktree by canonical path
393c7fa3Merge branch 'factory/fix-ignore-reincluded-dir-3783'
dba965bcMerge branch 'factory/ci-green-3701'
544e01b1Merge branch 'bench-network-http'
c13edef7grit-bench daily: run network scenarios end to end over git http-backend
6e37dfb1test: redact tempfile paths via runtime temp_dir prefix
e7553816test: raise root pub mod budget for ident/list_limit/line_range
1a1a333btest: raise root pub mod budget for ident/list_limit/line_range
da1560f8fix: unborn HEAD resolve_ref_name and align clone cleanup test
0bdd2d80test: register network snapshot tempfile redaction after upstream label
a79408e0test: refresh grit skill snapshot after main doc updates
9a607117test: apply tempfile snapshot redaction after repo path labels
aaa7a00fchore: drop stale CLI contract limit exceptions for branch and reflog
99114b82test: redact tempfile paths in snapshots and refresh reflog output
28e2043bdocs(clone): add required remote fields to JSON examples
49aff016fix: dedupe canonical ident map entry and repair main rustdoc gates
2a345b46fix(merge): exit 0 on --dry-run conflicts per documented contract
a6179f6ctest: add list_limit module rust doctest for public API gate
ebf5693dfix(rustdoc): link exit code slugs to published docs URL
bacd0002fix(rustdoc): qualify notes plan_add/plan_remove intra-doc links
c970d54aFix ignore: directory-only rules skip file paths
4a8382edMerge branch 'factory/log-oneline-speed'
8658d348Merge branch 'factory/fix-diff-default-uncommitted-1655'
95104695Fixes #1655: default diff list formats use full uncommitted scope
8cc0174bdocs: read commits with Objects::read_commit in examples and guides
c1b183fcodb: share commit reading through Odb::read_commit and Odb::commit_tree
0e41dfb5bench: record log page and startup rows before and after
bae2b3eepack: reuse the single local pack across object reads
509e0b3erevwalk: keep retained log pages lean
31a2f66acli: build subcommand arguments only when that subcommand is parsed
f89a6633Merge branch 'bench-scenario-detail'
62305f55grit-bench daily: record every run and how each scenario is measured
c60187a3GRIT_TRACE: append the span tree to a file when given an absolute path
8a37368eMerge pull request #1647 from gitbutlerapp/readme-verify-releases
8d24c9cbREADME: how to verify release tags with grit tag -v