Skip to content

Glob **/ patterns match nothing since the #114 separator fix: src/**/*.cs and **/*.cs filter out every path #126

Description

@matt-edmondson

What's wrong

The fix for #114 (MaskPathSeparators, TextFilter/TextFilter.cs ~L406–428) replaces / and \ with U+E000 in both the pattern and the text before DotNet.Glob sees them. That lets * and ? cross slashes as intended, but it also removes DotNet.Glob's directory-wildcard handling of **, which only applies when ** sits between path separators. After masking, **/ is just ** followed by a literal private-use character, so it no longer means "zero or more path segments". Every pattern that uses the standard **/ form now matches nothing, including paths that fit it exactly.

Reproduction

Items ["src/a.cs", "src/x/a.cs", "docs/readme.md"], glob filter:

Pattern HEAD (2ad72cb) Before the #114 fix (df1c960^)
src/**/*.cs [] [src/a.cs, src/x/a.cs]
**/*.cs [] [src/a.cs, src/x/a.cs]
**/readme.md [] [docs/readme.md]

IsMatch(..., Glob, ByWholeString) on HEAD returns false for ("src/a.cs","src/**/*.cs"), ("src/x/a.cs","src/**/*.cs"), ("src/a.cs","**/*.cs") and ("a.cs","**/*.cs"). All four returned true before the fix. Bare ** and src/** still match.

These results come from a console app that references TextFilter.csproj and was run against both commits. The test project has no test that uses **, so the regression went uncaught.

Why it matters

**/ is the most common way to write a recursive path glob. Anyone filtering file lists with it now gets an empty result and no error.

Suggested fix / acceptance criteria

Keep the #114 behaviour (*readme* matches docs/readme.md, AC* matches AC/DC) and make **/ mean "zero or more characters ending at a separator" again. Two ways to do it:

  • Rewrite ** followed by a separator before masking, so the masked glob covers both the no-directory case and the "anything, then a separator" case.
  • Translate the glob to a regex rather than relying on DotNet.Glob's separator semantics.

Tests to add:

  • src/**/*.cs matches src/a.cs and src/x/a.cs
  • **/*.cs matches a.cs and src/a.cs
  • **/readme.md matches docs/readme.md
  • GlobStarMatchesAcrossSlash, GlobFilterKeepsPathItems and GlobLiteralSlashInPatternStillMatchesSlashInText still pass

Activity

  1. matt-edmondson commented on Sep 28, 2026

    @matt-edmondson
    ContributorAuthor

    Triage


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workingreadyFully specified; implement as written

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions