From 9fe8791dda55650d191372bd965f21562e9439fc Mon Sep 17 00:00:00 2001 From: Milos Vasic Date: Tue, 18 Aug 2026 21:14:19 +0200 Subject: [PATCH] diag(extraction): log when the git-based scan falls back to a filesystem walk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getGitVisibleFiles() silently returned null on ANY exception (git missing, a rev-parse/ls-files timeout or buffer overrun under load, an unreadable repo, etc.), sending every caller to the independent scanDirectoryWalk() filesystem-walk fallback with zero signal that the fast, fully git-delegated path was skipped. That makes a report like "codegraph walked into a directory a nested (non- root) .gitignore excludes for git" nearly untriageable after the fact: both scanning implementations exist to respect .gitignore correctly on their own reading, but there is currently no way to tell which of the two actually ran for a given index/init/sync — so a maintainer investigating such a report has to re-instrument the source themselves to even confirm the fallback fired. This adds one logDebug() call (the project's existing CODEGRAPH_DEBUG-gated convention, already used elsewhere in this same file) naming the exception before falling back, with zero behavior change otherwise. Context: reported against v1.5.0 in a real ~63x file-count blowup (509 -> 32,260 files) on a project with git-confirmed-correct nested .gitignore exclusions (git check-ignore -v: frontend/.gitignore:10 and extension/.gitignore:2 both correctly exclude their node_modules trees). Neither scanning path in the current source could be shown to mis-handle a synthetic nested-.gitignore fixture in isolation (tested up to 63 nested .gitignore files / 960 excluded files / .bin symlinks against the actual v1.5.0 binary), so this defensive-hardening diagnostic is offered instead of a speculative behavioral fix for the reported regression itself. See the linked issue for full reproduction evidence. --- src/extraction/index.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/extraction/index.ts b/src/extraction/index.ts index 22108d1d1..a2f0a047f 100644 --- a/src/extraction/index.ts +++ b/src/extraction/index.ts @@ -1074,7 +1074,21 @@ function getGitVisibleFiles(rootDir: string): Set | null { // Git, but still wanted in the graph.) for (const f of collectIncludedFilesForRoot(rootDir)) visible.add(f); return visible; - } catch { + } catch (error) { + // Any failure here (git missing, a `git rev-parse`/`ls-files` timeout or + // buffer overrun under load, an unreadable repo, etc.) silently sent every + // caller to the `scanDirectoryWalk` filesystem-walk fallback with zero + // signal that the fast, fully git-delegated path was skipped — making a + // report like "the index walked into a nested-.gitignore-excluded + // directory" nearly untriageable, since there was no way to tell which of + // the two independent ignore implementations actually ran. Log it (gated + // by the project's existing CODEGRAPH_DEBUG convention, see logDebug) so a + // future report at this scale can confirm or rule out the fallback path + // in one step instead of re-instrumenting the source to find out. + logDebug('git-based file listing unavailable — falling back to filesystem walk', { + rootDir, + error: error instanceof Error ? error.message : String(error), + }); return null; } }