Skip to content

feat(scripts): optional single-segment branch prefix for gitflow#2202

Open
gabrielhmsantos wants to merge 6 commits intogithub:mainfrom
gabrielhmsantos:feature/support-single-prefix-feature-branches
Open

feat(scripts): optional single-segment branch prefix for gitflow#2202
gabrielhmsantos wants to merge 6 commits intogithub:mainfrom
gabrielhmsantos:feature/support-single-prefix-feature-branches

Conversation

@gabrielhmsantos
Copy link
Copy Markdown
Contributor

@gabrielhmsantos gabrielhmsantos commented Apr 13, 2026

Description

Teams using gitflow (or similar) often use branch names like feat/001-my-feature or hotfix/20260319-143022-fix, while Spec Kit expects the feature segment to start with a sequential number or a YYYYMMDD-HHMMSS- timestamp. That caused check_feature_branch / prerequisite scripts to reject valid workflows and made PowerShell fall back to a literal specs/<full-branch> path instead of prefix-based resolution.

This PR adds a shared effective branch name step: when the full ref matches exactly two slash-free segments separated by a single / (^([^/]+)/([^/]+)$), validation and specs/ prefix lookup use only the second segment. Otherwise behavior is unchanged. CURRENT_BRANCH / exported values stay the raw Git (or SPECIFY_FEATURE) name; error messages show the raw name.

  • Bash: spec_kit_effective_branch_name, wired into check_feature_branch and find_feature_dir_by_prefix in scripts/bash/common.sh.
  • PowerShell: Get-SpecKitEffectiveBranchName, Test-FeatureBranch, new Find-FeatureDirByPrefix (parity with bash), and Get-FeaturePathsEnv fallbacks in scripts/powershell/common.ps1.
  • Git extension: git-common bash/ps1 aligned with core validation after normalization.
  • Removed unused get_feature_dir / Get-FeatureDir.

Testing

  • uv run pytest tests/ — 1247 passed, 20 skipped (pwsh-skipped where unavailable).

  • Tested locally with uv run specify --help

  • Ran existing tests with uv sync && uv run pytest

  • Tested with a sample project (if applicable)

AI Disclosure

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

Implementation and tests were developed with Cursor / AI-assisted editing from an agreed design (single optional path segment, no hardcoded prefix list, parity bash/PowerShell, extension alignment).

Made with Cursor

- Add spec_kit_effective_branch_name / Get-SpecKitEffectiveBranchName:
  when branch matches prefix/rest with exactly one slash, validate and
  resolve specs/ using only the rest (e.g. feat/001-my-feature).
- Wire into check_feature_branch, find_feature_dir_by_prefix (bash) and
  Test-FeatureBranch, Find-FeatureDirByPrefix + Get-FeaturePathsEnv (PS).
- Align git extension git-common with core validation; remove unused
  get_feature_dir / Get-FeatureDir helpers.
- Extend tests in test_timestamp_branches.py and test_git_extension.py.

Made-with: Cursor
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds gitflow-style support for feature branches that include a single optional prefix segment (e.g., feat/004-name) by normalizing to an “effective branch name” for validation and specs/ directory resolution, keeping exported branch values and error displays as the raw branch name.

Changes:

  • Introduces effective-branch-name normalization in bash and PowerShell, wiring it into feature-branch validation and specs/ directory lookup.
  • Adds PowerShell parity for prefix-based feature directory resolution (Find-FeatureDirByPrefix) and updates Get-FeaturePathsEnv to use it.
  • Updates core + git extension scripts and extends pytest coverage for prefixed branches.
Show a summary per file
File Description
tests/test_timestamp_branches.py Adds regression tests for single-prefix branch validation and prefix-based directory resolution (bash + pwsh skip-when-missing).
tests/extensions/git/test_git_extension.py Adds git extension tests ensuring core/extension parity for single-prefix behavior (bash + pwsh).
scripts/powershell/common.ps1 Adds Get-SpecKitEffectiveBranchName, updates branch validation to use it, adds Find-FeatureDirByPrefix, and switches feature-path resolution to prefix lookup.
scripts/bash/common.sh Adds spec_kit_effective_branch_name and uses it in branch validation and prefix-based feature dir lookup.
extensions/git/scripts/powershell/git-common.ps1 Aligns extension PowerShell branch validation with core effective-name normalization.
extensions/git/scripts/bash/git-common.sh Aligns extension bash branch validation with core effective-name normalization.

Copilot's findings

Tip

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

Comments suppressed due to low confidence (2)

scripts/powershell/common.ps1:201

  • Find-FeatureDirByPrefix writes error text and then throws when multiple matches are found. Since Get-FeaturePathsEnv is used by scripts that may expect clean stdout (e.g., JSON mode), consider emitting errors on the error stream (Write-Error/Write-Warning) and returning a non-zero/controlled failure instead of throwing (or throw without first writing to stdout).
    $names = ($dirMatches | ForEach-Object { $_.Name }) -join ' '
    Write-Output "ERROR: Multiple spec directories found with prefix '$prefix': $names"
    Write-Output "Please ensure only one spec directory exists per prefix."
    throw "Multiple spec directories for prefix '$prefix'"

scripts/powershell/common.ps1:233

  • The try/catch in Get-FeaturePathsEnv wraps both JSON parsing and the Find-FeatureDirByPrefix call. If Find-FeatureDirByPrefix throws (e.g., multiple prefix matches), the catch block just calls it again, which will rethrow and can duplicate error output. Consider narrowing the try/catch to only the JSON parsing/conversion, or handling prefix-resolution errors separately.
            } else {
                $featureDir = Find-FeatureDirByPrefix -RepoRoot $repoRoot -Branch $currentBranch
            }
        } catch {
            $featureDir = Find-FeatureDirByPrefix -RepoRoot $repoRoot -Branch $currentBranch
  • Files reviewed: 6/6 changed files
  • Comments generated: 1

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds branch-name normalization to support gitflow-style prefixes (e.g., feat/004-name) while preserving existing behavior for other branch shapes. This improves both feature-branch validation and specs/ directory resolution across Bash, PowerShell, and the bundled git extension.

Changes:

  • Introduces an “effective branch name” helper that strips exactly one leading path segment when the branch is exactly two segments (x/y).
  • Wires normalization into branch validation and specs/ prefix-based directory lookup (core scripts + git extension scripts).
  • Expands pytest coverage for single-prefix acceptance/rejection and prefix-based path resolution (including PowerShell when available).
Show a summary per file
File Description
tests/test_timestamp_branches.py Adds tests for single-prefix normalization in validation + prefix-based directory lookup; adds a pwsh availability guard.
tests/extensions/git/test_git_extension.py Adds git extension tests ensuring bash/ps1 branch validation matches core behavior after normalization.
scripts/powershell/common.ps1 Adds effective-branch helper; updates validation error messaging; adds prefix-based feature dir resolver and uses it in Get-FeaturePathsEnv.
scripts/bash/common.sh Adds effective-branch helper; applies it to check_feature_branch and find_feature_dir_by_prefix; removes unused get_feature_dir.
extensions/git/scripts/powershell/git-common.ps1 Aligns git extension PowerShell branch validation with core logic + normalization.
extensions/git/scripts/bash/git-common.sh Aligns git extension bash branch validation with core logic + normalization.

Copilot's findings

Tip

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

  • Files reviewed: 6/6 changed files
  • Comments generated: 1

Copy link
Copy Markdown
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

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

Please address Copilot feedback. If not applicable, please explain why

…r Stop)

Find-FeatureDirByPrefix: on ambiguous prefix matches, write errors to stderr
and return $null instead of throwing, matching find_feature_dir_by_prefix.

Get-FeaturePathsEnv: narrow try/catch to ConvertFrom-Json only; add
Get-FeatureDirFromBranchPrefixOrExit to mirror bash get_feature_paths
(stderr + exit 1) when prefix lookup fails, avoiding unhandled terminating
errors under $ErrorActionPreference = 'Stop' in check-prerequisites,
setup-plan, and update-agent-context.

Made-with: Cursor
@mnriem mnriem requested a review from Copilot April 13, 2026 16:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds gitflow-friendly branch-name normalization (optional single-segment prefix stripping) so feature-branch validation and specs/ directory resolution work with branches like feat/001-... while preserving raw branch names in exported values and error messages.

Changes:

  • Introduces an “effective branch name” helper in bash and PowerShell and wires it into branch validation + prefix-based specs/ directory lookup.
  • Aligns the bundled git extension’s git-common scripts with the core validation logic after normalization.
  • Expands pytest coverage for single-prefix branches across bash, PowerShell (when available), and the git extension.
Show a summary per file
File Description
tests/test_timestamp_branches.py Adds tests for single-prefix branch validation and prefix-based feature dir resolution (bash + optional pwsh).
tests/extensions/git/test_git_extension.py Adds git extension tests to ensure git-common matches core behavior with single-prefix branches.
scripts/powershell/common.ps1 Adds effective-name normalization, implements prefix-based feature dir resolution, and updates validation + path resolution flow.
scripts/bash/common.sh Adds effective-name normalization and applies it to branch validation and prefix-based feature dir lookup.
extensions/git/scripts/powershell/git-common.ps1 Aligns git extension PowerShell branch validation with core (including normalization).
extensions/git/scripts/bash/git-common.sh Aligns git extension bash branch validation with core (including normalization).

Copilot's findings

Tip

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

  • Files reviewed: 6/6 changed files
  • Comments generated: 1

@mnriem mnriem requested review from Copilot and mnriem April 13, 2026 16:32
Copy link
Copy Markdown
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

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

Please address Copilot feedback

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds gitflow-friendly branch name normalization (strip exactly one leading path segment) so feature-branch validation and specs/ prefix directory resolution work with branches like feat/001-x while preserving raw branch names for exports and error messages.

Changes:

  • Introduces “effective branch name” normalization in core bash and PowerShell scripts and wires it into branch validation + prefix-based feature dir lookup.
  • Aligns git extension git-common bash/PowerShell validation logic with core behavior.
  • Expands test coverage for single-segment prefix branches and cross-branch prefix resolution.
Show a summary per file
File Description
tests/test_timestamp_branches.py Adds tests for single-segment prefixed branch validation and prefix-based directory resolution; adds pwsh-dependent integration test.
tests/extensions/git/test_git_extension.py Adds git extension tests ensuring core/extension parity for single-segment prefixed branches (bash + pwsh).
scripts/powershell/common.ps1 Implements effective-branch normalization, updates Test-FeatureBranch, adds prefix-based directory resolution helpers, and updates Get-FeaturePathsEnv fallback behavior.
scripts/bash/common.sh Implements effective-branch normalization and applies it to branch validation and prefix-based feature dir lookup.
extensions/git/scripts/powershell/git-common.ps1 Aligns git extension PowerShell branch validation with core (effective name + malformed timestamp rules).
extensions/git/scripts/bash/git-common.sh Aligns git extension bash branch validation with core (effective name + malformed timestamp rules).

Copilot's findings

Tip

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

  • Files reviewed: 6/6 changed files
  • Comments generated: 2

@mnriem mnriem self-requested a review April 13, 2026 16:38
Copy link
Copy Markdown
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

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

Please address Copilot feedback

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds gitflow-compatible branch normalization (optional single path prefix) so branch validation and specs/ prefix directory resolution work consistently across bash, PowerShell, and the bundled git extension.

Changes:

  • Introduces an “effective branch name” normalization step that strips exactly one leading segment for ^([^/]+)/([^/]+)$ branch names.
  • Wires normalization into bash + PowerShell feature-branch validation and specs/ directory lookup (core + git extension).
  • Expands pytest coverage for prefixed branches and cross-branch prefix directory resolution, including PowerShell coverage when pwsh is available.
Show a summary per file
File Description
scripts/bash/common.sh Adds spec_kit_effective_branch_name and uses it in branch validation + prefix-based feature dir resolution.
scripts/powershell/common.ps1 Adds Get-SpecKitEffectiveBranchName, updates Test-FeatureBranch, and introduces prefix-based dir resolution for Get-FeaturePathsEnv.
extensions/git/scripts/bash/git-common.sh Aligns git extension bash validation with core via effective-name normalization.
extensions/git/scripts/powershell/git-common.ps1 Aligns git extension PowerShell validation with core via effective-name normalization.
tests/test_timestamp_branches.py Adds tests for prefixed branches and prefix-based specs/ lookup; adds pwsh availability gating.
tests/extensions/git/test_git_extension.py Adds regression tests ensuring extension validation matches core for prefixed branches (bash + pwsh).

Copilot's findings

Tip

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

Comments suppressed due to low confidence (1)

scripts/powershell/common.ps1:239

  • Get-FeaturePathsEnv now exits the whole PowerShell process when .specify/feature.json JSON parsing fails. In bash, a malformed/pretty-printed feature.json effectively falls back to branch-based directory resolution; exiting here is a behavior change and can make recovery harder (especially if the file is temporarily corrupted). Consider emitting a concise stderr warning/error and falling back to prefix-based resolution (or returning an error to the caller) instead of calling exit from inside this shared helper.
        $featureJsonRaw = Get-Content -LiteralPath $featureJson -Raw
        try {
            $featureConfig = $featureJsonRaw | ConvertFrom-Json
        } catch {
            [Console]::Error.WriteLine("ERROR: Failed to parse .specify/feature.json: $_")
            exit 1
        }
  • Files reviewed: 6/6 changed files
  • Comments generated: 3

Comment on lines +202 to +213
# Branch-based prefix resolution; mirrors bash get_feature_paths failure (stderr + exit 1).
function Get-FeatureDirFromBranchPrefixOrExit {
param(
[Parameter(Mandatory = $true)][string]$RepoRoot,
[Parameter(Mandatory = $true)][string]$CurrentBranch
)
$resolved = Find-FeatureDirByPrefix -RepoRoot $RepoRoot -Branch $CurrentBranch
if ($null -eq $resolved) {
[Console]::Error.WriteLine('ERROR: Failed to resolve feature directory')
exit 1
}
return $resolved
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

Get-FeatureDirFromBranchPrefixOrExit calls exit 1 from inside a function in common.ps1. Since common.ps1 is dot-sourced by multiple entrypoint scripts, exiting here prevents those callers from handling the error uniformly (and makes the function hard to reuse in other contexts). Prefer returning $null/throwing a terminating error and letting the top-level scripts decide when/how to exit (mirroring the bash pattern where get_feature_paths returns non-zero and the caller handles termination).

Copilot uses AI. Check for mistakes.
gabrielhmsantos and others added 2 commits April 13, 2026 14:47
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds gitflow-compatible branch handling by introducing an “effective branch name” normalization step (strip a single leading segment like feat/ when the branch is exactly two segments), aligning branch validation and specs/ prefix resolution across core scripts and the bundled git extension.

Changes:

  • Bash + PowerShell: normalize branch names for validation and prefix-based feature directory lookup using only the second segment for x/y branch names.
  • PowerShell: add prefix-based feature-dir resolution helper (parity with bash) and wire it into Get-FeaturePathsEnv.
  • Tests: expand coverage for single-prefix branches in core scripts and the git extension (bash + pwsh when available).
Show a summary per file
File Description
tests/test_timestamp_branches.py Adds coverage for single-segment gitflow prefixes in branch validation and prefix-based feature-dir resolution, plus bash/pwsh integration coverage.
tests/extensions/git/test_git_extension.py Adds parity tests for git extension git-common (bash + pwsh) with single-prefix acceptance.
scripts/powershell/common.ps1 Implements effective branch normalization + prefix-based feature-dir resolution and integrates it into Test-FeatureBranch/Get-FeaturePathsEnv.
scripts/bash/common.sh Implements effective branch normalization and uses it in check_feature_branch and find_feature_dir_by_prefix.
extensions/git/scripts/powershell/git-common.ps1 Aligns extension PS branch validation with core via effective branch normalization + stderr errors.
extensions/git/scripts/bash/git-common.sh Aligns extension bash branch validation with core via effective branch normalization + raw-branch error messages.

Copilot's findings

Tip

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

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

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