Skip to content

fix(detect): honor nested .gitignore/.graphifyignore files below the scan root#1847

Closed
Mohak-Agrawal wants to merge 1 commit into
Graphify-Labs:v8from
Mohak-Agrawal:fix/1206-nested-gitignore
Closed

fix(detect): honor nested .gitignore/.graphifyignore files below the scan root#1847
Mohak-Agrawal wants to merge 1 commit into
Graphify-Labs:v8from
Mohak-Agrawal:fix/1206-nested-gitignore

Conversation

@Mohak-Agrawal

Copy link
Copy Markdown
Contributor

Summary

Closes #1206.

detect() only read .gitignore/.graphifyignore files in the scan root and its ancestor directories (up to the nearest VCS root), loaded once before the walk began. A .gitignore sitting in a descendant directory — e.g. vendor/sub/.gitignore — was never read at all, so files/dirs it was meant to exclude leaked into the graph. Real git (and every other gitignore-aware tool) honors .gitignore at every directory level, not just the ancestor chain.

  • Extracted the per-directory read+parse logic (previously inlined in _load_graphifyignore's ancestor loop) into a shared _load_dir_own_ignore() helper — no behavior change to the existing ancestor-chain path.
  • detect()'s os.walk loop now calls _load_dir_own_ignore(dp) for every directory it visits (except the scan root, already covered), appending patterns before that directory's children are pruned — so a nested ignore file governs its own subtree with git's usual closer-file-wins precedence.

Test plan

  • 3 new regression tests in tests/test_detect.py: nested file exclude, nested directory prune (walk never descends into it), nested ! negation overriding a broader root-level rule
  • All 6 pre-existing .graphifyignore/ancestor-chain tests re-verified — no regressions
  • Manually exercised all 9 tests end-to-end against real temp directories (this sandbox's Python has no pytest installed) — all pass; would appreciate a CI run to confirm under the project's actual test runner

🤖 Generated with Claude Code

…scan root (Graphify-Labs#1206)

detect() only read .gitignore/.graphifyignore in the scan root and its
ancestor directories (up to the nearest VCS root), loaded once before the
walk began. A .gitignore sitting in a descendant directory — e.g.
vendor/sub/.gitignore — was never read, so files/dirs it excluded leaked
into the graph. Real git (and every other gitignore-aware tool) honors
.gitignore at every directory level, not just the ancestor chain.

Extracts the per-directory read+parse logic into a shared
_load_dir_own_ignore() helper (used by both the existing ancestor-chain
loader and the new call site) and invokes it live inside detect()'s
os.walk loop for every directory visited, before that directory's
children are pruned — so a nested ignore file governs its own subtree
with the same closer-file-wins precedence git uses.

Adds three regression tests: nested file exclude, nested directory prune
(the walk never descends into it), and nested negation overriding a
broader root-level rule.

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

Copy link
Copy Markdown
Collaborator

Landed on v8 (8a5287a, your commit preserved) plus a test follow-up (7ca43ab) — ships in 0.9.15. Thanks @Mohak-Agrawal. The fix is correct and composes cleanly with the .git/info/exclude handling from #1810: nested patterns are read during the walk and anchored to their directory, so a nearer ! re-include still wins over both a root .gitignore and info/exclude (verified). I tightened the negation test to use .py files (deterministic code bucket instead of a fuzzy document/unclassified union) and added a composition test pinning the three-source precedence.

@safishamsi safishamsi closed this Jul 13, 2026
safishamsi added a commit that referenced this pull request Jul 13, 2026
Tighten the brittle negation test to use .py files so classification
lands in the deterministic `code` bucket (was checking a fuzzy
document+unclassified union), and add a composition test asserting a
nested `.gitignore` `!` re-include outranks both a root `.gitignore` and
`.git/info/exclude` (#1810) — locking the precedence across all three
ignore sources.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
safishamsi added a commit that referenced this pull request Jul 13, 2026
…angelog

Adds the regression test the #1855 fix was missing: _rebuild_code must
produce graph.json whose clustered nodes carry community_name, guarding
against the label-stripping regression recurring. Also records #1847 and
#1855 in the 0.9.15 changelog.

Co-Authored-By: Claude Opus 4.8 (1M context) <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.

BUG: graphiphy does not respect nested .gitignore files

2 participants