Skip to content

fix: respect nested .gitignore files during indexing (#178)#183

Open
dLo999 wants to merge 1 commit intoDeusData:mainfrom
dLo999:fix/nested-gitignore
Open

fix: respect nested .gitignore files during indexing (#178)#183
dLo999 wants to merge 1 commit intoDeusData:mainfrom
dLo999:fix/nested-gitignore

Conversation

@dLo999
Copy link
Copy Markdown

@dLo999 dLo999 commented Mar 29, 2026

Closes #178

Summary

Fixes nested .gitignore files not being respected during file discovery. Previously only the root .gitignore was loaded — subdirectory .gitignore files were silently ignored, causing build artifacts (e.g., webapp/.output/) to be fully indexed.

Changes

  • src/discover/discover.c: walk_dir now checks for .gitignore in each subdirectory. When found, loads it and matches paths relative to that directory. The loaded gitignore is passed to recursive calls and freed on return. Root .gitignore still uses repo-relative paths (unchanged).
  • tests/test_discover.c: 3 new tests:
    • discover_nested_gitignore — basic case matching issue scenario
    • discover_nested_gitignore_deep — pattern applies to nested subdirectories
    • discover_nested_gitignore_stacks_with_root — root and nested gitignores both apply

Test results

Build: Compiles cleanly on macOS (Apple Clang, arm64)

Test suite: 2589 passed, 0 failed (incremental tests skipped — network offline). 3 new tests pass.

Behavioral verification (exact issue scenario):

Created test repo:

.gitignore          # has dist/
webapp/.gitignore   # has .output
webapp/.output/bundle.js
webapp/.output/vendor.js
webapp/src/app.js
dist/out.js

Indexed with cli index_repository, queried all nodes:

File Before fix After fix
webapp/src/app.js Indexed Indexed
webapp/.output/bundle.js Indexed (BUG) Excluded
webapp/.output/vendor.js Indexed (BUG) Excluded
dist/out.js Excluded (root .gitignore) Excluded

Edge cases:

Test Result
Root .gitignore + nested .gitignore both apply PASS — independent filtering
Pattern applies to nested subdirs (e.g., generated/ excludes webapp/src/generated/) PASS
Root directory .gitignore not re-loaded (guard: rel_prefix[0] \!= '\0') PASS

README: Line 331 already says ".gitignore hierarchy" — now accurate, no update needed.

Generated with agent-team via /issue

When walking subdirectories, load any .gitignore found in the current
directory and apply its patterns against paths relative to that
directory. The nearest ancestor gitignore is propagated to all
descendant directories so that patterns like `.output` in
`webapp/.gitignore` exclude `webapp/.output/` and everything inside it.

The root .gitignore continues to be handled separately (via the existing
`gitignore` parameter with repo-root-relative paths). walk_dir skips
re-loading it by only checking for a nested gitignore when
`rel_prefix` is non-empty (i.e. inside a subdirectory).

Adds three integration tests covering: basic nested exclusion, deep
descendant exclusion (gitignore two levels above), and stacking of root
and nested gitignores.
Copy link
Copy Markdown
Author

@dLo999 dLo999 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Implements nested .gitignore support in file discovery. walk_dir() now loads .gitignore files from subdirectories, computes relative paths for matching, and passes them through the recursion tree. Three new tests cover basic nesting, deep subdirectory propagation, and root+nested stacking.

Findings

All nits — no code changes needed:

  • [nit] src/discover/discover.c:234 — local_rel_path() skips bounds check on prefix strip (safe in practice, paths always well-formed from walk_dir)
  • [nit] src/discover/discover.c:267 — 4096-byte gi_path buffer could overflow with >4085-byte dir_path (filesystem limits prevent this)
  • [nit] tests/test_discover.c — No three-level nested gitignore test (root + sub + sub/sub). Design handles it via parameter passing but untested.
  • [nit] tests/test_discover.c:671 — Test creates main.go but doesn't assert it IS indexed (only validates exclusions)

CI Status

No CI on fork branch. Local: 2589 passed, 0 failed, 3 new tests. Behavioral verification with exact issue scenario (webapp/.output/) confirmed fix.

Verdict

APPROVE — Clean implementation, resource-safe, correctly solves the issue. All findings are minor nits consistent with existing code style.

@DeusData DeusData added the bug Something isn't working label Mar 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Nested .gitignore patterns not respected during indexing

2 participants