Skip to content

fix: honour [...] bracket expressions and backslash escapes in branch patterns [patch] - #48

Merged
matt-edmondson merged 2 commits into
mainfrom
claude/gbsc-43-bracket-expressions
Sep 28, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
claude/gbsc-43-bracket-expressions

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #43

What was wrong

BranchPattern says it matches "the way git matches one", but it only understood * and ?. A client pattern such as origin/release-[0-9]* passed TryParse, then matched nothing. Those branches dropped out of /state and /branches with no error.

Change

  • Matches still walks the pattern and the name once, with no regex. Each non-star element now goes through MatchesOne, which handles:
    • ?
    • \x: an escaped literal
    • bracket expressions: ranges ([0-9]), sets ([abc]), negation with ! or ^, a literal ] placed first ([]x], [!]]), a - at either end as a literal, and \ escapes inside the brackets
  • A [ with no closing ] is still an ordinary character. This keeps the existing "stray bracket is literal" behaviour.
  • * is now checked before a literal match, so a star in the pattern always acts as a wildcard.
  • Updated the class remarks to list the supported constructs.

Out of scope: POSIX classes such as [[:digit:]], which git's wildmatch also accepts. Nothing reported them, and they can follow if they turn up in a real StatusBranchNamePatterns.

Tests

Added 9 BranchPatternTests: the range case from the issue, sets, !/^ negation, ] placed first, - at either end, backslash escapes, an unclosed [, a bracket after * that needs backtracking, and a pathological *[a-y] × 40 pattern that must still return promptly.

  • With BranchPattern.cs reverted, 7 of the new tests fail.
  • With the fix, the full suite passes: 212/212 (dotnet test --project GitBranchStateCache.Tests).

🤖 Generated with Claude Code

https://claude.ai/code/session_01PtWVWaDh3nqJL1eKD7vFxU


Generated by Claude Code

… patterns [patch]

BranchPattern promised to match the way git branch --list does, but only
understood * and ?. A pattern such as origin/release-[0-9]* was accepted
and then matched nothing, so those branches silently dropped out of
/state and /branches.

The matcher now handles ranges, sets, negation with ! or ^, a literal ]
placed first, and \ escapes, keeping the linear no-regex walk. An
unclosed [ stays an ordinary character. A * is now checked before a
literal match, so a star always acts as a wildcard.

Fixes #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PtWVWaDh3nqJL1eKD7vFxU
Splits the range parsing out of TryMatchBracket so the method stays
under the cognitive-complexity limit. Behaviour is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PtWVWaDh3nqJL1eKD7vFxU
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 765ddd3 into main Sep 28, 2026
12 checks passed
@matt-edmondson
matt-edmondson deleted the claude/gbsc-43-bracket-expressions branch September 28, 2026 01:47
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.

Branch patterns with [...] character classes match no branches, though git's branch --list honours them

2 participants