Repository navigation
fix(core): batch untracked file diffs instead of spawning git per file - #53449
Merged
Merged
Conversation
2 of 6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A working-tree diff ran 2 git processes per untracked file, one after another (
statUntracked+patchUntracked). In a worktree with 257 untracked eval files,/api/vcs/diffran longer than the app's 60 s request timeout. The app retried endlessly, page loads waited behind the stuck requests (blank tab), and the server eventually stalled.This is a performance-only change: output is byte-identical to
v2.flowchart LR L[files v2 would diff one by one] --> E{regular file, not huge?} E -- no --> F["per-file v2 command (unchanged)"] E -- yes --> A["GIT_INDEX_FILE=$TMP (empty) git add -N --pathspec-from-file"] A --> D["git diff --numstat / --patch against $TMP"] D --> M{"chunk header == diff --git a/f b/f?"} M -- yes --> OK[use batched result] M -- no --> Fstatus()andfiles()keep thev2flow. Before the loop,untrackedBatchprefetches results for exactly the filesv2would pass tostatUntracked/patchUntracked. Each lookup falls back to the original per-file command.git rm --cachedpaths and nested repos keep theirv2handling.git diffagainst an intent-to-add entry applies the same attributes as--no-index(text=auto, clean filters,-diff,binary, working-tree-encoding), so the patch text matches byte for byte.git addrejects.git addruns with--literal-pathspecs,--force,--sparseand-c core.splitIndex=false.Benchmark (257 untracked files, Windows)
v2diff("working")status()Parity
400 randomized repos, comparing
status()anddiff()(working, branch, committed,context: 1) betweenv2's adapter and this one:.gitand index unchangedThe repos covered
.gitattributes,git rm --cached, feature branches, nested repos,diff.mnemonicPrefix, repos without commits, staged-then-deleted files, intent-to-add-then-deleted files,core.splitIndex, symlinks, 6 MB and 11 MB files, sparse checkout, and subdirectory scopes.