First ci-windows run exposed four platform assumptions in the fixtures:
- smoke: the scratch repo inherited the runner's system-wide
core.autocrlf=true (Git for Windows default), so every index restore
smudged LF to CRLF and broke the byte-exact assertions — pin
core.autocrlf=false in the fixture (eol policy is not what these
destructive-op tests are about).
- git / git-worktree: Windows TEMP is the 8.3 short form
(C:\Users\RUNNER~1\...) while git reports long paths, and
realpathSync does not expand 8.3 aliases — switch the canonicalizer
to realpathSync.native (libuv resolves via GetFinalPathNameByHandle,
which does); same trick as the existing macOS /var workaround.
- bundle-route: the ETag memo revalidates on stat (mtime+size) and
Windows updates file timestamps lazily, so the equal-size rewrite
still looked unchanged — change the length too.
- market-manifest: GNU tar (Git Bash) reads the drive-letter colon of
absolute Windows paths as a remote-host spec — run it from the pack
dir with the bare tarball name instead.
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.