Skip to content

fix(source-control): huge-status flag permanently disabled all status refresh — commits in the terminal never surfaced - #8570

Merged
brennanb2025 merged 1 commit into
stablyai:mainfrom
moseoh:fix/huge-status-flag-deadlock
Jul 14, 2026
Merged

brennanb2025 merged 1 commit into
stablyai:mainfrom
moseoh:fix/huge-status-flag-deadlock

Conversation

@moseoh

@moseoh moseoh commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Once git status hits the 10,000-entry limit (DEFAULT_GIT_STATUS_LIMIT), the huge flag (gitStatusHugeByWorktree) disabled every status-refresh lane for that worktree — interval polling, the 30s terminal-only backstop, file-watch refreshes, and the push signals (repo-metadata watcher, terminal command-finished). But the flag only clears when a fresh status result arrives with didHitLimit=false, so the worktree deadlocked into permanently stale Source Control and file-explorer badges: commits made in the integrated terminal were never reflected until an app restart. The remaining escape hatches (the one-shot .gitignore toast, a git mutation through Orca's UI) don't fire for terminal-driven workflows, and the toast doesn't appear at all when the over-limit state was transient (findHugeFoldersToIgnore finds nothing).

Repro (before this fix): create >10,000 untracked files in a worktree → banner appears → remove/commit them from the integrated terminal → git status is clean but the panel and explorer badges keep the stale entries indefinitely; only an app restart recovers.

The fix splits the gate in useGitStatusPolling:

  • shouldPollActiveWorktreeGitStatus (includes the huge check) still gates evidence-free interval polling — the [Bug]: Continuous full-untracked Git polling consumes CPU in large monorepos on v1.4.130 #7983 idle-CPU protection is preserved: while huge, no timers run.
  • canFetchActiveWorktreeGitStatus (everything except the huge check) now gates runFetchStatus and the push-signal subscription, so signals that carry evidence of a change (a commit's .git metadata write, a finished shell command) ride the coalesced change-signal lane, run one status, and let a non-huge result clear the flag and resume normal polling.
  • A visibilitychange catch-up listener (active only while huge pauses polling) covers signals dropped behind a hidden window — e.g. an agent committing while Orca is minimized — matching the becoming-visible catch-up semantics the normal lane already has via installWindowVisibilityInterval.

File-watch refreshes stay gated on the huge flag (unchanged): file churn is high-frequency on exactly the repos that trip the limit. Push signals are low-frequency and paced by the coalescer's 3s floor plus the slow-task backoff.

Screenshots

No visual change (the existing "too many changes" banner now clears itself once a signal-triggered status runs).

Testing

  • pnpm lint
  • pnpm typecheck
  • pnpm test — all renderer suites pass (right-sidebar: 150 files / 1,259 tests). 17 pre-existing failures in src/main/src/relay real-git-binary integration tests reproduce identically on a pristine main checkout on this machine (git 2.55.0, macOS) and are unrelated to this renderer-only change.
  • pnpm build
  • Added regression tests (written first, red on the old gate): with the huge flag set, no interval polling is installed, but (1) a repo-metadata push signal still triggers a git status refresh, and (2) a hidden→visible transition triggers a catch-up refresh.

AI Review Report

Ran an adversarial review of the branch (Codex, plus the authoring agent's own pass). Focus areas and results:

  • Correctness of the gate split — confirmed sound: runFetchStatus no longer checks the huge flag, so a trailing coalesced run can clear it; push subscriptions stay keyed to repo/worktree identity; no stale closures or listener leaks found; worktree-switch traces (huge→huge, huge→non-huge, hidden transitions) behave correctly.
  • document availability — the review flagged that the new visibility effect accessed document unguarded, unlike installWindowVisibilityInterval; fixed by adding the same defensive existence check.
  • Cross-platform (macOS/Linux/Windows) — renderer-only change; no shortcuts, labels, paths, shell, or Electron platform APIs touched. visibilitychange/document.visibilityState are standard DOM APIs identical across platforms.
  • SSH/remote/local — the gate keeps the existing isActiveConnectionReady condition, so disconnected SSH targets still skip refreshes; push signals for remote repos flow through the same IPC channels as before.
  • Performance vs [Bug]: Continuous full-untracked Git polling consumes CPU in large monorepos on v1.4.130 #7983 — while huge, idle cost remains zero (no timers). Under continuous terminal signals on a still-huge repo the change-signal backoff (1× previous run duration, 3s floor) bounds worst-case duty cycle; see Notes for the residual trade-off the review flagged.

Security Audit

No input handling, command execution, path handling, auth, secrets, or dependency changes. The change rearranges existing renderer-side gating of already-established IPC subscriptions (worktrees:onChanged, worktrees:onGitStatusMetadataChanged, DOM visibilitychange); no new IPC surface, no new data crosses the preload bridge, and payload handling (repoId comparison) is unchanged.

Notes

Two residual limitations surfaced by the adversarial review, left out of scope to keep this PR minimal (both are strictly better than the current permanently-stuck behavior; happy to follow up if maintainers have a preferred pacing design):

  1. File-only recovery: if a huge worktree becomes non-huge purely through file changes made outside any terminal (e.g. deleting a generated folder in Finder) while the window stays visible, no push signal fires and the flag clears only on the next signal (any terminal command / metadata write / window reveal). A low-frequency probe lane while huge would close this.
  2. Terminal-signal pacing while still huge: terminal command-finished events fire for every command, so a chatty agent on a genuinely-still-huge repo can drive status runs at up to ~50% duty cycle (bounded by the 1× slow-task backoff). Distinct huge-mode pacing for terminal-finished signals (metadata signals keeping short latency) would tighten this.

…e huge flag is set

Once git status hit the 10,000-entry limit, the huge flag disabled every
status-refresh lane — including the push signals (repo metadata watcher,
terminal command-finished) that carry the evidence needed to clear it.
The flag only clears when a fresh non-huge status result arrives, so the
worktree deadlocked into stale Source Control and explorer badges until
an app restart.

Split the gate: evidence-free interval polling stays paused while huge
(preserving the stablyai#7983 idle-CPU fix), but push-signal refreshes now ride
the coalesced change-signal lane, so a commit made in the integrated
terminal clears the flag and resumes normal polling. A visibilitychange
listener (active only while huge pauses polling) catches up signals
dropped behind a hidden window, matching the becoming-visible catch-up
the normal lane already has.
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 703e6a33-4df2-4f9c-a629-56c7de79d675

📥 Commits

Reviewing files that changed from the base of the PR and between 7b3103f and a2ba9bd.

📒 Files selected for processing (2)
  • src/renderer/src/components/right-sidebar/useGitStatusPolling.test.ts
  • src/renderer/src/components/right-sidebar/useGitStatusPolling.ts

📝 Walkthrough

Walkthrough

Git status polling now separates base fetch conditions from the huge-status interval guard. Interval polling pauses while the huge flag is active, while repository change signals can still trigger status refreshes. A visibility-change listener retries status fetching when a hidden window becomes visible. Tests add document stubbing and cover both push-signal refreshes during huge-status pauses and visibility-triggered catch-up.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: fixing huge-status refresh deadlock in source control.
Description check ✅ Passed The description directly explains the bug, fix, and tests, and is fully aligned with the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@brennanb2025

Copy link
Copy Markdown
Contributor

Taking a look!

@brennanb2025
brennanb2025 merged commit 6c489a4 into stablyai:main Jul 14, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants