You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Diff viewer hangs on "Loading diff..." with many untracked files (per-file git subprocess in Vcs.diff) #34916
The diff viewer (GET /vcs/diff, mode: "git") hangs on "Loading diff..." for minutes when the working tree has many untracked files. It does eventually return, but the per-file git subprocess spawn makes it impractically slow. Most severe on Windows where each git subprocess spawn is ~150-165ms.
Root cause is in packages/opencode/src/project/vcs.ts:
Vcs.diff → track(git, cwd, ref, options) (vcs.ts:384). When there is no HEAD yet (freshly git init'd repo with no commits), ref is undefined, so track takes the if (!ref) branch (vcs.ts:230) and passes an empty batch (emptyBatch()) to files().
In files() (vcs.ts:178) the for loop iterates every untracked item. For each, patchForItem (vcs.ts:148) finds no batched patch and falls through to nativePatch (vcs.ts:162) → git.patchUntracked (vcs.ts:130), which spawns one git diff --no-index /dev/null <file> subprocess per file.
The MAX_TOTAL_PATCH_BYTES cap (vcs.ts:187) does not break the loop — it only swaps the patch for emptyPatch (vcs.ts:157). The stat line (vcs.ts:179) still calls git.statUntracked (another per-file subprocess) for every added item even after cap, since the cap check happens after it.
This is not fixed by having a HEAD either: diffAgainstRef (vcs.ts:201) merges untracked ?? items into the list (vcs.ts:214-217), but batchPatches (vcs.ts:96) only batch-patches tracked changes via git.patchAll (git diff --patch HEAD). Untracked items still miss the batch and fall through to per-file patchUntracked.
So any repo with a large number of untracked files (e.g. node_modules not yet gitignored, generated/synced caches) makes the diff viewer effectively unusable, regardless of HEAD presence.
Steps to reproduce
In a directory with many untracked files (700+), run git init but create no commit.
Start opencode, open the diff viewer (/diff or command palette → "Open diff viewer").
It stays on "Loading diff..." for several minutes. With ~700 files on Windows it is ~2+ minutes; with ~4000+ it never practically returns.
Windows 11 (each git subprocess spawn ~150-165ms here, which compounds the problem; less severe but still linear on macOS/Linux)
Suggested fix directions (optional)
Batch untracked-file patches in a single git invocation instead of per-file git diff --no-index (e.g. feed multiple paths, or diff the whole untracked set against an empty tree once).
In files(), break the loop once capped is true (or at least skip git.statUntracked for capped items).
Make the stat line (vcs.ts:179) respect capped before spawning git.statUntracked.
Activity
github-actions commentedon Sep 1, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.