Skip to content

fix(scripts): keep PowerShell branch-name acronym match case-sensitive (parity with bash)#3129

Merged
mnriem merged 2 commits into
github:mainfrom
jawwad-ali:fix/powershell-branch-name-acronym-case
Jun 25, 2026
Merged

fix(scripts): keep PowerShell branch-name acronym match case-sensitive (parity with bash)#3129
mnriem merged 2 commits into
github:mainfrom
jawwad-ali:fix/powershell-branch-name-acronym-case

Conversation

@jawwad-ali

Copy link
Copy Markdown
Contributor

Description

Get-BranchName (and its bash twin generate_branch_name) drop words shorter than 3 characters when deriving the feature branch / spec-directory name from a description — unless the word appears as an UPPERCASE acronym in the original (e.g. keep GO in "Use GO now", drop go in "Add go support").

The bash scripts check the acronym case-sensitively:

# scripts/bash/create-new-feature.sh
elif echo "$description" | grep -q "\b${word^^}\b"; then        # keep only if UPPERCASE form present
# extensions/git/scripts/bash/create-new-feature-branch.sh
elif echo "$description" | grep -qw -- "${word^^}"; then

The PowerShell twins used -match, which is case-insensitive by default:

} elseif ($Description -match "\b$($word.ToUpper())\b") {   # matches the lowercased word too!

So PowerShell kept every short word regardless of case — contradicting its own adjacent comment ("Keep short words if they appear as uppercase in original (likely acronyms)") and diverging from the bash twin. The result: the same description yields different branch and specs/ directory names depending on which shell ran, desyncing specs/, feature.json, and git branches across a mixed-OS team. create-new-feature is what /speckit.specify runs for every project, and create-new-feature-branch backs /speckit.git.feature.

Fix

Use the case-sensitive -cmatch (the word is already .ToUpper()-ed) so a short word is kept only for a genuine uppercase acronym — matching bash. Two one-token changes:

  • scripts/powershell/create-new-feature.ps1
  • extensions/git/scripts/powershell/create-new-feature-branch.ps1

Purely a correctness fix; no flags, output keys, or other behavior change.

Evidence (verified locally, both shells)

Description bash (correct) PowerShell before (-match) PowerShell after (-cmatch)
Add go support 001-support 001-go-support 001-support
my db is slow 001-slow 001-db-slow 001-slow
Use GO now (real acronym) 001-use-go-now 001-use-go-now 001-use-go-now

Isolation check: 'Add go support' -match '\bGO\b'True (bug); 'Add go support' -cmatch '\bGO\b'False (fixed); 'Use GO now' -cmatch '\bGO\b'True (acronym preserved).

Testing

  • Tested locally with uv run specify --help (exit 0)
  • Ran existing tests with uv sync && uv run pytest
  • Verified both scripts end-to-end (bash directly; the fixed .ps1 via PowerShell) produce identical branch names

Added regression tests (assert a lowercase short word is dropped and an uppercase acronym is kept), covering both fixed scripts on both shells:

  • tests/test_timestamp_branches.py::TestSequentialBranch (core, bash) and ::TestSequentialBranchPowerShell (core, pwsh)
  • tests/extensions/git/test_git_extension.py::TestCreateFeatureBash and ::TestCreateFeaturePowerShell (git extension)

uvx ruff check src/ <changed tests> clean. The new bash/PowerShell tests run on the CI matrix (ubuntu bash, windows pwsh); on my local host they skip (no pwsh/detected bash), so I confirmed the behavior by running the scripts directly (table above) — the PowerShell tests fail against the pre-fix -match and pass with -cmatch.

Out of scope

While here I noticed the git-extension PowerShell script also emits a HAS_GIT key in its JSON/text output that the bash twin doesn't — a separate, lower-impact output-parity nit. Happy to follow up in its own PR to keep this one focused.

AI Disclosure

  • I did not use AI assistance for this contribution
  • I did use AI assistance (describe below)

Found and fixed with Claude Code (Claude Opus 4.8) under my direction. AI located the bash/PowerShell divergence, made the -cmatch change, and wrote the regression tests; I reproduced the differing branch names on both shells, confirmed the fix produces parity, and reviewed the diff before submitting. I'll disclose if any review responses are AI-assisted as well.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a cross-shell parity bug in branch/spec-directory name derivation by making the PowerShell implementations treat “uppercase acronym” detection as case-sensitive (matching the existing bash behavior). This prevents mixed-OS teams from generating different specs/ directory names and feature branches from the same description.

Changes:

  • Switch PowerShell regex matching from -match (case-insensitive) to -cmatch (case-sensitive) when deciding whether to keep short words as acronyms.
  • Add regression tests covering lowercase short-word dropping vs uppercase acronym retention for both core and git-extension scripts across bash and PowerShell.
Show a summary per file
File Description
tests/test_timestamp_branches.py Adds core regression tests for acronym case-sensitivity behavior in both bash and PowerShell paths.
tests/extensions/git/test_git_extension.py Adds git-extension regression tests ensuring bash and PowerShell derive identical branch names.
scripts/powershell/create-new-feature.ps1 Fixes acronym detection to be case-sensitive (-cmatch) and documents the rationale/parity intent.
extensions/git/scripts/powershell/create-new-feature-branch.ps1 Fixes acronym detection to be case-sensitive (-cmatch) for git extension parity with bash.

Copilot's findings

Tip

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

  • Files reviewed: 4/4 changed files
  • Comments generated: 4

Comment thread tests/test_timestamp_branches.py
Comment thread tests/test_timestamp_branches.py
Comment thread tests/extensions/git/test_git_extension.py
Comment thread tests/extensions/git/test_git_extension.py
@jawwad-ali

Copy link
Copy Markdown
Contributor Author

Thanks for the review! Addressed in 1c45005 — reworded the four branch-name case-sensitivity docstrings from an UPPERCASE acronym to an acronym in UPPERCASE so the indefinite article reads cleanly. Docstring-only; no behavior change. ruff clean.

AI disclosure: prepared with Claude Code (Claude Opus 4.8) under my direction; I reviewed the diff before pushing.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 0 new

@mnriem mnriem left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please resolve conflicts

jawwad-ali and others added 2 commits June 25, 2026 13:25
Get-BranchName keeps a sub-3-character word only when it appears as an
UPPERCASE acronym in the description. The bash twin checks this
case-sensitively (grep "\b${word^^}\b" / grep -qw -- "${word^^}"), but the
PowerShell twin used -match, which is case-INSENSITIVE, so it kept EVERY
short word regardless of case -- contradicting its own comment and diverging
from bash. The same description then produced different spec-directory and
branch names on Windows/PowerShell vs macOS/Linux (e.g. "Add go support" ->
001-go-support instead of 001-support), desyncing specs/, feature.json, and
git branches across a mixed-OS team.

Use the case-sensitive -cmatch so a short word is kept only for a genuine
uppercase acronym, matching bash. Applied to both the core
scripts/powershell/create-new-feature.ps1 and the git extension's
create-new-feature-branch.ps1.

Add bash + PowerShell regression tests (core and git-extension) asserting a
lowercase short word is dropped while an uppercase acronym is kept.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address review: 'an UPPERCASE acronym' -> 'an acronym in UPPERCASE' across the four branch-name case-sensitivity test docstrings (the indefinite article reads cleanly before 'acronym'). Docstring-only; no behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jawwad-ali jawwad-ali force-pushed the fix/powershell-branch-name-acronym-case branch from 1c45005 to d0dfd8e Compare June 25, 2026 08:26
@jawwad-ali

Copy link
Copy Markdown
Contributor Author

@mnriem rebased onto latest main and resolved the conflict (force-pushed d0dfd8e).

Heads-up on scope: the core scripts/powershell/create-new-feature.ps1 fix has already landed on main (it now uses -cmatch), so that part of the conflict was a no-op — I kept main's version. This PR now carries the still-needed half: the git-extension create-new-feature-branch.ps1 was still using case-insensitive -match (line 255), which I switched to -cmatch for parity with the bash twin, plus the regression tests for both the core and extension paths.

ruff clean; the PS case-sensitivity tests run on the Windows/pwsh CI leg (they skip locally without pwsh).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new

@mnriem mnriem self-requested a review June 25, 2026 12:56
@mnriem mnriem merged commit 9fe1c4c into github:main Jun 25, 2026
12 checks passed
@mnriem

mnriem commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Thank you!

HeroSizy pushed a commit to HeroSizy/spec-kit that referenced this pull request Jun 25, 2026
…e (parity with bash) (github#3129)

* fix(scripts): keep PowerShell branch-name acronym match case-sensitive

Get-BranchName keeps a sub-3-character word only when it appears as an
UPPERCASE acronym in the description. The bash twin checks this
case-sensitively (grep "\b${word^^}\b" / grep -qw -- "${word^^}"), but the
PowerShell twin used -match, which is case-INSENSITIVE, so it kept EVERY
short word regardless of case -- contradicting its own comment and diverging
from bash. The same description then produced different spec-directory and
branch names on Windows/PowerShell vs macOS/Linux (e.g. "Add go support" ->
001-go-support instead of 001-support), desyncing specs/, feature.json, and
git branches across a mixed-OS team.

Use the case-sensitive -cmatch so a short word is kept only for a genuine
uppercase acronym, matching bash. Applied to both the core
scripts/powershell/create-new-feature.ps1 and the git extension's
create-new-feature-branch.ps1.

Add bash + PowerShell regression tests (core and git-extension) asserting a
lowercase short word is dropped while an uppercase acronym is kept.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: fix article grammar in branch-name docstrings

Address review: 'an UPPERCASE acronym' -> 'an acronym in UPPERCASE' across the four branch-name case-sensitivity test docstrings (the indefinite article reads cleanly before 'acronym'). Docstring-only; no behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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