* fix(source-control): keep huge change sets responsive
* Fix cancellation and retry handling for capped status
* Harden capped status for conflict-heavy repositories
* Harden capped status recovery and cancellation
* fix(source-control): preserve capped status correctness
* fix(source-control): translate submodule status at render time
---------
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
* feat(git-status): batch, cancel, and cache git status polling to cut idl
- Add a single duty-cycled refresh scheduler (activity debounce + 60s
safety timer) replacing multiple overlapping intervals, so status
polling no longer runs near-continuously on large repos (#7983).
- Let safety refreshes reuse cached numstat line counts instead of
re-running diff --numstat every cycle, invalidated by head change,
known mutations, and a bounded TTL.
- Thread AbortSignal/request-token cancellation through IPC, RPC, and
relay layers so a superseded or backgrounded git:status call is
killed instead of finishing wastefully.
- Fix automatic upstream/status apply ordering so a slow, older
refresh can no longer clobber a newer result, and so an earlier
refresh still applies when a later one fails.
* Fix aborted git status scans being mistaken for completed empty results
- An aborted scan/numstat pass now always rejects instead of silently
resolving, so a cancelled request can't look like a valid empty status.
- Stop clearing the line-stats cache key on abort, since an aborted pass
never wrote to it — clearing was evicting a concurrent scan's healthy
snapshot and forcing a redundant numstat recompute.
* Fix aborted git status scans resolving as completed results
Cancelled scans could still resolve with partial or stale data instead of
rejecting, letting callers treat an aborted refresh as a valid status. Also
stop counting aborted scan duration toward catch-up refresh pacing, which
was stretching the next refresh interval by the full length of a cancelled
(often slow) scan.
* Add cancellable, generation-aware git status polling to cut stale scans
- Route git.status through an abortable subscription per requestToken so
cancelStatus can actually abort the remote scan instead of being a
no-op, preventing wasted work and stale responses overwriting fresher
state.
- Bump the git status polling generation on push-target changes so an
in-flight refresh against the old remote/branch can't apply stale
upstream data to the new one.
- Guard the stale-conflict poller against writes after unmount.
- Retire pre-purge line-stat scans in the cache so an older in-flight
scan can't repopulate a key after a token-scoped purge.
* Fix untracked line-stat cache thrash and add source-control scale benchmark (#8013)
The untracked line-stat cache capped at 2,048 entries while a git status
scan can carry up to DEFAULT_GIT_STATUS_LIMIT (10,000) untracked entries.
A sequential scan over more files than the cap FIFO-evicted every entry
before the next poll revisited it (~0% hit rate), so every 3s status poll
re-read every untracked file's full contents. Measured with 64KB files:
warm rescan cost per file was 17x higher just past the cap.
- Size the cache to 2x the status entry limit and make eviction LRU
(delete-before-set on hit and refresh) so a hot worktree's entries
survive another worktree's scan.
- Add tests/e2e/source-control-large-file-count.spec.ts: a 5-scenario
Playwright benchmark (pnpm run test:e2e:source-control-scale) that
reproduces #8013 deterministically — event-loop stall, DOM node count,
JS heap, and OS-level renderer working set at 5k/9.5k/11k changed files,
plus a clean-repo control and a cache-effectiveness gate. Scenarios
asserting bounded row mounting go green with the SourceControl
virtualization fix (#7619).
Co-authored-by: Orca <help@stably.ai>
* Address review: historical cache comment + fixture cleanup on partial setup failure
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>
* Add per-file line counts to the source control sidebar
Show +N/-N (green/red) next to each file in the Changes, Untracked, and
Committed-on-branch sections so the magnitude of a change is visible at a
glance. Counts are computed per staging area via `git diff --numstat`;
untracked/new files count their full contents as additions and binary
files show no count.
Consolidate numstat parsing and binary-buffer detection into shared
modules reused by the local status path, the SSH/relay path, and the
existing branch-compare code. Include added/removed in the status-entry
equality check so the sidebar doesn't re-render on unchanged polls.
* fix: harden source control line counts
---------
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>