A developer contributed a performance optimization to Git 2.55 that speeds up `git stash -p` by 53× in large repositories. The root cause was that `git stash -p` built a temporary index via a `git read-tree HEAD` subprocess, producing an index with no cached stat data or fsmonitor validity bits, forcing Git to `lstat()` every file before showing the first interactive prompt. The fix replaces the subprocess with an in-process function using `oneway_merge()` to copy cached index entries, allowing unchanged files to be skipped. In a monorepo with ~200,000 files, time-to-first-prompt dropped from ~35 seconds to ~0.66 seconds. The patch was developed with AI assistance (GPT 5.5 and Claude 4.8), reviewed by Git maintainer Junio Hamano, and shipped in Git 2.55 (released June 2026). A performance test with 100,000 files confirmed the improvement: mean time dropped from 6.90s to 0.55s without fsmonitor, and from 6.83s to 0.28s with it.
Questions this post answers
Why is `git stash -p` so slow in a large monorepo?
`git stash -p` was slow because it built its temporary index by spawning a `git read-tree HEAD` subprocess, which produced an index with no cached file stat data and no fsmonitor validity bits. When the patch-selection machinery later refreshed that index, Git had to `lstat()` every single file — ~200,000 in one large monorepo — before showing the first prompt. Git 2.55 fixes this by building the index in-process, reusing cached entries. Teams hitting this in large repos can track Git version rollouts on daily.dev.
What changed in Git 2.55 to make `git stash -p` faster?
Git 2.55 replaced the `git read-tree HEAD` subprocess in `stash_patch()` with an in-process function using `oneway_merge()` to copy cached index entries for paths matching HEAD. This preserves cached stat data and fsmonitor validity bits, so the index refresh can skip unchanged files. In a test repo with 100,000 files, mean time dropped from 6.90s to 0.55s without fsmonitor, and from 6.83s to 0.28s with fsmonitor enabled. Developers upgrading Git in CI or local tooling can follow Git release coverage on daily.dev.
45.8K Impressions1 Comment