Skip to content

fix(detect): scope nested ignore patterns to their own subtree#1885

Closed
Alwyn93 wants to merge 1 commit into
Graphify-Labs:v8from
Alwyn93:fix/nested-ignore-anchor-scope
Closed

fix(detect): scope nested ignore patterns to their own subtree#1885
Alwyn93 wants to merge 1 commit into
Graphify-Labs:v8from
Alwyn93:fix/nested-ignore-anchor-scope

Conversation

@Alwyn93

@Alwyn93 Alwyn93 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #1873 — nested .gitignore/.graphifyignore patterns applied outside their own subtree, which can zero an entire scan.

_is_ignored() matched non-anchored patterns against the path relative to the scan root first, so patterns from a nested ignore file leaked out of their directory. In-the-wild trigger: the hypothesis library auto-writes .hypothesis/.gitignore containing a bare * — with nested-ignore support (8a5287a, #1206) that single file ignored the whole repository and detect() returned 0 files.

Fix

Per gitignore semantics, patterns from A/.gitignore apply only to paths under A. The patch matches every pattern against the path relative to its own anchor:

  • target outside the pattern's anchor → pattern cannot match (continue)
  • anchor directory itself is exempt (rel_anchor == ".") — an ignore file governs its directory's contents, not the directory
  • anchored (/-prefixed) and non-anchored patterns unified on the same anchor-relative path; last-match-wins and ! negation behavior unchanged

Tests

  • tests/test_detect.py: 143 passed — including the existing nested-ignore, nested-negation-beats-root, and git info/exclude precedence tests
  • Two new regressions:
    • test_nested_gitignore_star_does_not_ignore_outside_its_dir — the .hypothesis scenario; fails on v8 HEAD (total_files == 0), passes with the fix
    • test_nested_gitignore_patterns_still_apply_inside_their_dir — guard that nested ignore files still work within their subtree
  • Full-suite note: the 15 failures in tests/test_skillgen.py (11) and tests/test_ollama_retry_cap.py (4) are pre-existing at v8 HEAD (verified on a clean checkout) and unrelated to this change.

Also verified on a real repo: a scan that returned 0 files at HEAD returns 204/230 with the fix.

Related

🤖 Generated with Claude Code

…ify-Labs#1873)

Non-anchored patterns from a nested .gitignore/.graphifyignore were
matched against root-relative paths first, so a nested ignore file's
patterns leaked outside its directory. In the wild, .hypothesis/.gitignore
(a bare "*" auto-written by the hypothesis library) ignored the entire
repository and detect() returned 0 files.

Per gitignore semantics, patterns from A/.gitignore apply only to paths
under A. Match every pattern against the path relative to its own anchor
(the anchor dir itself exempt — an ignore file governs its directory's
contents, not the directory), and skip patterns whose anchor does not
contain the target.

Regression introduced with nested-ignore support in 8a5287a (Graphify-Labs#1206).
tests/test_detect.py: 143 passed, including the existing nested-ignore
and nested-negation tests plus two new regressions.

Fixes Graphify-Labs#1873

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@safishamsi

Copy link
Copy Markdown
Collaborator

Landed on v8 as fb4d452, ships in 0.9.16. Thanks @Alwyn93 - subtree-scoping fix was exactly right and also resolved the #1880 update-emits-0-nodes symptom.

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.

Nested .gitignore rules apply outside their own subtree, zeroing the scan

3 participants