Skip to content

fix: a single negation (!) in .graphifyignore no longer disables all directory pruning - #1276

Merged
safishamsi merged 1 commit into
Graphify-Labs:v8from
papinto:fix/graphifyignore-negation-pruning
Jun 12, 2026
Merged

fix: a single negation (!) in .graphifyignore no longer disables all directory pruning#1276
safishamsi merged 1 commit into
Graphify-Labs:v8from
papinto:fix/graphifyignore-negation-pruning

Conversation

@papinto

@papinto papinto commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Fixes #1274

Problem

A single ! rule in .graphifyignore set a blanket has_negation flag
(detect.py:1047) that disabled directory-level pruning for every ignored
directory during the os.walk in detect() (detect.py:1051). One unrelated
!docs/** therefore made the walk descend node_modules/, bin/, obj/,
wwwroot/, … on large repos — a major slowdown.

Output stayed correct (the per-file _is_ignored filter still excluded those
files), so this is a walk-performance bug, not a correctness one — but the
detection pass visited the entire tree unnecessarily.

Fix

Remove the has_negation bypass and prune purely on _is_noise_dir +
_is_ignored. The bypass was unnecessary: _is_ignored already honours
negations correctly —

  • last-match-wins lets !dir/ un-ignore a directory, so it isn't pruned, and
  • gitignore's parent-exclusion rule means a ! cannot rescue a file beneath an
    excluded directory,

so descending an ignored directory to find a re-included file is never needed.

Test

Adds a regression test that tracks os.walk and asserts the ignored directory
is never descended while the negation still re-includes its target.

A single `!` rule in .graphifyignore set a blanket `has_negation` flag that
disabled directory-level pruning for EVERY ignored directory during the
os.walk in detect(). One unrelated `!docs/**` therefore made the walk descend
bin/, obj/, wwwroot/, generated/, … on large repos — a pathological slowdown.
Output stayed correct (the per-file `_is_ignored` filter still excluded those
files), but the walk visited the entire tree.

The bypass was unnecessary: `_is_ignored` already honours negations correctly —
last-match-wins lets `!dir/` un-ignore a directory (so it is not pruned), and
the gitignore parent-exclusion rule means a `!` cannot rescue a file beneath an
excluded directory, so descending an ignored dir to find a re-included file is
never needed. Prune purely on `_is_noise_dir` + `_is_ignored`.

Adds a regression test that tracks os.walk and asserts the ignored dir is never
descended while the negation still re-includes its target.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A single negation (!) rule in .graphifyignore disables all directory pruning

2 participants