Skip to content

fix: handle exclude patterns for nested directories#3

Merged
ga1az merged 2 commits into
ga1az:mainfrom
Vader-7:fix/nested-exclude-patterns
Apr 13, 2026
Merged

fix: handle exclude patterns for nested directories#3
ga1az merged 2 commits into
ga1az:mainfrom
Vader-7:fix/nested-exclude-patterns

Conversation

@Vader-7
Copy link
Copy Markdown
Contributor

@Vader-7 Vader-7 commented Apr 13, 2026

Summary

  • Fix nested directory exclude patterns: Directory exclude patterns like .git/ and node_modules/ now correctly match at any depth in the path, not just as a prefix. For example, vendor/lib/.git/HEAD is now properly excluded by the .git/ pattern.
  • Fix GetRelativePath segment boundary: Paths like /tmp no longer incorrectly match /tmp2 due to a missing path separator check in strings.HasPrefix.

Problem

When a project contains nested .git directories (e.g., submodules, vendored repos), the exclude pattern .git/ only matched paths that started with .git/. Paths like vendor/lib/.git/objects/pack were not excluded because the isPathMatchWithInfo function only checked for prefix matches.

Before:

vendor/lib/.git/HEAD          → NOT excluded by ".git/" ❌
vendor/lib/.git/objects/pack  → NOT excluded by ".git/" ❌
packages/app/node_modules/    → NOT excluded by "node_modules/" ❌

After:

vendor/lib/.git/HEAD          → excluded by ".git/" ✅
vendor/lib/.git/objects/pack  → excluded by ".git/" ✅
packages/app/node_modules/    → excluded by "node_modules/" ✅

Changes

  • internal/digest/ingest.go: For simple (single-segment) directory patterns, also check if the pattern matches any segment of the path using strings.Contains
  • internal/fsutil/fs.go: Add path separator boundary check in GetRelativePath
  • internal/digest/ingest_test.go: Add 8 test cases for nested directory exclusion
  • internal/fsutil/fs_test.go: New test file for GetRelativePath edge cases

Test plan

  • All existing tests pass
  • New test cases for nested .git/, node_modules/, .next/, build/ directories
  • New test for GetRelativePath segment boundary
  • Verified with go test ./...

Directory exclude patterns like `.git/` and `node_modules/` now correctly
match at any depth in the path, not just as a prefix. For example,
`vendor/lib/.git/HEAD` is now properly excluded by the `.git/` pattern.

The fix checks if a simple (single-segment) directory pattern matches
any segment of the path, not just the beginning. Multi-segment patterns
like `a/b/` continue to work via prefix matching as before.

Also fixes a path segment boundary bug in GetRelativePath where
`/tmp` could incorrectly match `/tmp2` due to missing separator check.

Both fixes include test cases.

Made-with: Cursor
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes path handling so directory exclude patterns (e.g., .git/, node_modules/) match at any depth, and tightens GetRelativePath to avoid false prefix matches (e.g., /tmp incorrectly matching /tmp2).

Changes:

  • Update exclude-pattern matching to detect single-segment directory patterns anywhere within a path.
  • Add path-segment boundary check in GetRelativePath to prevent prefix false-positives.
  • Add/expand tests for nested directory exclusions and GetRelativePath edge cases.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
internal/digest/ingest.go Extends directory-pattern matching to match single-segment dir patterns at any path depth.
internal/digest/ingest_test.go Adds test cases for nested directory exclusion behavior.
internal/fsutil/fs.go Fixes GetRelativePath by requiring a path-separator boundary for prefix checks.
internal/fsutil/fs_test.go Adds tests covering GetRelativePath nested/same-dir/similar-prefix scenarios.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/fsutil/fs_test.go Outdated
Comment thread internal/digest/ingest.go
pathToCheckPrefix = parentDir + "/"
}

// Check if path starts with the pattern (e.g. ".git/HEAD" matches ".git/")
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

This comment is slightly misleading: for files, the code checks the parent directory prefix (pathToCheckPrefix), not the full file path. Consider rewording the example to reflect what is actually being compared (e.g., that a file under ".git/" has parentDir ".git/" which matches the pattern).

Suggested change
// Check if path starts with the pattern (e.g. ".git/HEAD" matches ".git/")
// Check whether the directory prefix being examined matches the pattern.
// For directories this is the directory path itself; for files it is the
// parent directory (e.g. ".git/HEAD" has parentDir ".git/", which matches ".git/").

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@ga1az ga1az merged commit 4344e94 into ga1az:main Apr 13, 2026
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.

3 participants