fix(git): bound status payload and repo discovery; add reset escape hatch (#369)

Opening the source-control panel could freeze the whole sidebar, and the
frozen layout restored itself after every reload, leaving no way out
(issue #369). Three unbounded layers compounded:

- `git status --porcelain -z --untracked-files=all` shipped every row of a
  pathological untracked set into one response; the browser main thread
  froze on response.json() plus the unvirtualized change list, and the 2s
  poll replayed the freeze. status() now caps entries at 2000 and reports
  `truncated` (the panel shows a notice, mirroring fs.read's truncation
  semantics); worktree change counts inherit the bound for free.
- repoRoots() probed every visible child directory of a non-repo cwd
  (e.g. ~) serially, once per git.* call, each with the full 30s command
  budget. Discovery now uses a 3s probe timeout, caps probes at 200
  directories, and shares one in-flight scan plus a 60s TTL cache per cwd.
- A hung layout persisted `panelOpen: true` with the git tab active, so a
  reload remounted straight back into the freeze with no escape hatch.
  Loading with `?dsh-sidebar-reset` now drops the persisted layout (and
  the shared width) and starts from the default.

statusTruncated copy synced across all 19 shipped dictionaries.
This commit is contained in:
Menghuan1918
2026-08-25 11:04:43 +08:00
parent 6f6568d29f
commit 2cbcba8d11
26 changed files with 261 additions and 20 deletions
+1
View File
@@ -90,6 +90,7 @@ export const de: Record<string, string> = {
splitDown: 'Nach unten teilen',
notRepo: 'Dieses Verzeichnis ist kein Git-Repository',
noChanges: 'Keine Änderungen',
statusTruncated: 'Zu viele Änderungen; nur die ersten 2000 Einträge werden angezeigt',
stage: 'Stagen',
unstage: 'Unstagen',
stageAll: 'Alle stagen',