fix(scripts): keep PowerShell branch-name acronym match case-sensitive (parity with bash)#3129
Conversation
There was a problem hiding this comment.
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
|
Thanks for the review! Addressed in 1c45005 — reworded the four branch-name case-sensitivity docstrings from AI disclosure: prepared with Claude Code (Claude Opus 4.8) under my direction; I reviewed the diff before pushing. |
mnriem
left a comment
There was a problem hiding this comment.
Please resolve conflicts
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>
1c45005 to
d0dfd8e
Compare
|
@mnriem rebased onto latest Heads-up on scope: the core
|
|
Thank you! |
…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>
Description
Get-BranchName(and its bash twingenerate_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. keepGOin "Use GO now", dropgoin "Add go support").The bash scripts check the acronym case-sensitively:
The PowerShell twins used
-match, which is case-insensitive by default: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, desyncingspecs/,feature.json, and git branches across a mixed-OS team.create-new-featureis what/speckit.specifyruns for every project, andcreate-new-feature-branchbacks/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.ps1extensions/git/scripts/powershell/create-new-feature-branch.ps1Purely a correctness fix; no flags, output keys, or other behavior change.
Evidence (verified locally, both shells)
-match)-cmatch)Add go support001-support001-go-support❌001-support✅my db is slow001-slow001-db-slow❌001-slow✅Use GO now(real acronym)001-use-go-now001-use-go-now001-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
uv run specify --help(exit 0)uv sync && uv run pytest.ps1via PowerShell) produce identical branch namesAdded 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::TestCreateFeatureBashand::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 (nopwsh/detected bash), so I confirmed the behavior by running the scripts directly (table above) — the PowerShell tests fail against the pre-fix-matchand pass with-cmatch.Out of scope
While here I noticed the git-extension PowerShell script also emits a
HAS_GITkey 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
Found and fixed with Claude Code (Claude Opus 4.8) under my direction. AI located the bash/PowerShell divergence, made the
-cmatchchange, 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.