fix(git): the file tree survives repositories larger than 1 MB of paths - #36
Open
gustavo-depaula wants to merge 1 commit into
Open
fix(git): the file tree survives repositories larger than 1 MB of paths#36gustavo-depaula wants to merge 1 commit into
gustavo-depaula wants to merge 1 commit into
Conversation
getWorkingTreeFiles and getTreeFingerprint called execFileSync without a maxBuffer, so they inherited Node's 1 MB default. In a monorepo whose git ls-files output is 2.3 MB across ~29k files, every call died with spawnSync git ENOBUFS and the UI showed 'Failed to get tree' — the file browser and any tour that reads the tree were unusable. exec.ts already had the 50 MB ceiling these calls needed, but only for its string-command helpers; tree.ts passes argv arrays, which it should, because a repository path can contain a space or a quote. So this adds execFileLarge as the argv form of execLarge, names the shared constant, and routes tree.ts through it.
gustavo-depaula
force-pushed
the
fix/tree-enobufs-large-repos
branch
from
August 17, 2026 21:30
15fb0ff to
ad21099
Compare
Author
|
@nilbuild What do you think of this? |
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.
Addresses #24 (deliberately not
Closes, see the last section).What happens
On a large repository, the file tree fails to load and the UI shows:
Reproduced on a monorepo with ~29,000 tracked files, where
git ls-filesemits 2.3 MB./api/treeand/api/tree/fingerprintboth return 500, so the file browser is unusable and so is any tour, since the tour view reads the tree.Why
getWorkingTreeFilesandgetTreeFingerprintinpackages/git/src/tree.tscallexecFileSyncwithout amaxBuffer, so they inherit Node's 1 MB default. Any repository whose listing exceeds that kills the child process before it can return.packages/git/src/exec.tsalready had the 50 MB ceiling these calls needed — but only on its string-command helpers (execLarge,execWithStdin), andtree.tsnever used them.The fix
tree.tspasses argv arrays rather than shell strings, and it should keep doing that: a repository path can contain a space or a quote, and building a shell string out ofdirPathwould break on both. So rather than converting these calls toexecLarge, this adds the argv form of it:execFileLarge(command, args)inexec.ts, alongside the existing helpers50 * 1024 * 1024becomes a namedMAX_BUFFER, with a comment saying what overruns the defaultexecFileSynccalls intree.tsroute through the new helperNet effect is that the whole class of failure is gone from that file, not just the one call that happened to be hit first.
Testing
packages/git/tests/get-tree-large-repo.test.tsbuilds a temp repository whose listing crosses 1 MB and assertsgetTree()returns every file. It follows the fixture style ofget-diff-files.test.ts.Error: spawnSync git ENOBUFS— the exact error from the report.@diffity/gitis 7/7 and the full suite is 75/75 across the three packages.tscis clean.One note on the test: the fixture is deliberately over the limit, and
git commitnames every file it creates, so the setup helper needs the same headroom as the code under test. Without that it fails inbeforeAllfor its own reasons rather than testing anything.What this does not fix
#24 reports two things, and this PR only fixes one of them. The reporter also notes that the failure takes down views that do not need the file tree at all:
That is a separate defect — a
/api/tree500 should degrade the file browser, not replace the whole app with an error page. A tour has its own data and can render without the tree. This PR does not touch the error boundary, so the issue should stay open for that half if you agree it is worth fixing; hence no closing keyword above.Also worth a look
packages/github/src/pr.tsuses a 10 MB buffer forgh api ... --paginateon PR comments. That is far more headroom than this was, so it is likely fine, but it is the same pattern of a per-call literal rather than the shared constant.