Context
Raised by Greptile review on PR #2511 (adding target to the ignore-dir lists).
The incremental/scoped-rebuild fast path in both engines reconstructs its file set purely from persisted state, never from a filtered directory walk:
- TypeScript:
tryFastCollect() in src/domain/graph/builder/stages/collect-files.ts — rebuilds allFiles from file_hashes DB rows plus journal deltas (journal.changed/journal.removed). It applies include/exclude globs and .gitignore patterns, but never references IGNORE_DIRS/buildIgnoreSet.
- Rust:
try_fast_collect() in crates/codegraph-core/src/domain/graph/builder/stages/collect_files.rs — same pattern using db_files plus journal deltas and build_glob_set, never referencing DEFAULT_IGNORE_DIRS.
The full walk (collectFilesUtil/collect_files(), the non-incremental branch) is the only place either ignore-dir list is applied.
Impact
Any file that was indexed into file_hashes by a prior build — because it matched a directory that wasn't yet in the ignore list at the time, or slipped in through any other means — survives every subsequent incremental rebuild indefinitely. The fast path only self-heals when bypassed entirely: empty/invalid journal, empty file_hashes, or an explicit full/--no-incremental rebuild.
This is a general characteristic of the incremental design, not specific to any one ignore-dir entry — it applies equally to every existing entry (node_modules, dist, vendor, etc.) and to the newly added target from #2374. docs/guides/incremental-builds.md already documents --no-incremental as the escape hatch after an upgrade, but there's no schema-version or ignore-list-hash invalidation tied specifically to ignore-dir changes.
Suggested fix
Have tryFastCollect/try_fast_collect filter their reconstructed file set (or the journal deltas they add) against the current ignore-dir set before returning it, mirroring the full walk's behavior — so a build-tool upgrade that adds a new ignore-dir entry self-heals on the next incremental build rather than requiring a manual --no-incremental rebuild.
Out of scope for #2374 / PR #2511, since fixing it properly means changing the fast path for every ignore-dir entry, not just target.
Context
Raised by Greptile review on PR #2511 (adding
targetto the ignore-dir lists).The incremental/scoped-rebuild fast path in both engines reconstructs its file set purely from persisted state, never from a filtered directory walk:
tryFastCollect()insrc/domain/graph/builder/stages/collect-files.ts— rebuildsallFilesfromfile_hashesDB rows plus journal deltas (journal.changed/journal.removed). It appliesinclude/excludeglobs and.gitignorepatterns, but never referencesIGNORE_DIRS/buildIgnoreSet.try_fast_collect()incrates/codegraph-core/src/domain/graph/builder/stages/collect_files.rs— same pattern usingdb_filesplus journal deltas andbuild_glob_set, never referencingDEFAULT_IGNORE_DIRS.The full walk (
collectFilesUtil/collect_files(), the non-incremental branch) is the only place either ignore-dir list is applied.Impact
Any file that was indexed into
file_hashesby a prior build — because it matched a directory that wasn't yet in the ignore list at the time, or slipped in through any other means — survives every subsequent incremental rebuild indefinitely. The fast path only self-heals when bypassed entirely: empty/invalid journal, emptyfile_hashes, or an explicit full/--no-incrementalrebuild.This is a general characteristic of the incremental design, not specific to any one ignore-dir entry — it applies equally to every existing entry (
node_modules,dist,vendor, etc.) and to the newly addedtargetfrom #2374.docs/guides/incremental-builds.mdalready documents--no-incrementalas the escape hatch after an upgrade, but there's no schema-version or ignore-list-hash invalidation tied specifically to ignore-dir changes.Suggested fix
Have
tryFastCollect/try_fast_collectfilter their reconstructed file set (or the journal deltas they add) against the current ignore-dir set before returning it, mirroring the full walk's behavior — so a build-tool upgrade that adds a new ignore-dir entry self-heals on the next incremental build rather than requiring a manual--no-incrementalrebuild.Out of scope for #2374 / PR #2511, since fixing it properly means changing the fast path for every ignore-dir entry, not just
target.