Skip to content

fix(scanner): exclude patterns honour .gitignore anchors - #206

Merged
JordanCoin merged 3 commits into
mainfrom
fix/192-exclude-anchoring
Oct 11, 2026
Merged

JordanCoin merged 3 commits into
mainfrom
fix/192-exclude-anchoring

Conversation

@JordanCoin

Copy link
Copy Markdown
Owner

Problem (#192)

exclude before after
tool binary and cmd/tool/main.go gone same (bare names match at any depth, unchanged)
/tool nothing excluded only the root entry tool (file or directory)
tool/ nothing excluded directories named tool at any depth; a file named tool is kept
/tool/ nothing excluded only the root directory tool

Change

One matcher, scanner/walker.go matchesPattern, now reads .gitignore anchors before falling through to the existing extension, component and glob rules. The directory-pruning walk passes isDir=true so tool/ can tell a directory from a same-named file. Every exclude consumer (--exclude, config exclude, watch daemon, topology provider, MCP find guidance) already routes through MatchesFilters → this function, so one change fixes all of them.

Patterns containing * or ? are untouched: /build/*.log is still matched as a plain glob, not anchored. README documents the four forms.

Tests

TestMatchesPattern gains 18 cases: the three forms against the issue's fixture (cmd/tool/main.go, lib.go, root tool, root tool/), the directory vs file distinction, and toolbox as the no-over-match negative. go build ./... && go test ./... && gofmt -l . clean.

Not changed: the issue's two follow-ups (--debug printing the exclude list and per-pattern removal counts; a warning when an exclude removes files in an only extension) are separate work.

Fixes #192

🤖 Generated with Claude Code

https://claude.ai/code/session_01NRaBgKRAZMX9hjbkkefA7T

A bare exclude name matched at every depth and the anchored forms matched
nothing, so excluding a root binary named tool also removed cmd/tool/ from
every view and "/tool" or "tool/" changed nothing (#192).

matchesPattern now reads a leading "/" as root-anchored and a trailing "/"
as directories-only, the way .gitignore does; bare names keep matching at
any depth. The walker passes the one fact a path alone lacks, whether it
is a directory, so "tool/" prunes the directory and keeps the file. All
callers (--exclude, config exclude, watch, topology, MCP) route through
this one function.

Fixes #192

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NRaBgKRAZMX9hjbkkefA7T
Copilot AI balanced review requested due to automatic review settings October 11, 2026 19:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@JordanCoin
JordanCoin merged commit ff7bddf into main Oct 11, 2026
12 checks passed
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.

exclude: bare names match at every depth, anchored forms (/name, name/) match nothing

2 participants