Skip to content

Potential bug with the create-new-feature.ps1 script that ignores existing feature branches when determining next feature number #975

@fgalarraga

Description

@fgalarraga

Description

The PowerShell script .specify/scripts/powershell/create-new-feature.ps1 only checks the specs/ directory on the current branch to determine the next feature number, but does not check existing branch names. This causes numbering conflicts when working with multiple feature branches that haven't been merged to main.

Expected Behavior

When running the script from main, it should:

  1. Check the specs/ directory for existing spec folders with pattern \d{3}-*
  2. Also check git branch output for existing branches with pattern \d{3}-*
  3. Use the highest number found from either source
  4. Increment by 1 to determine the next feature number

Current Behavior

The script only checks step 1 (specs directory on current branch). If feature branches exist but haven't been merged to main, the script will reuse feature numbers, creating conflicts.

Reproduction Steps

  1. Initialize a new spec-kit project
  2. From main branch, run the script to create feature 001:
    .\.specify\scripts\powershell\create-new-feature.ps1 -ShortName "first-feature"
    • Creates branch 001-first-feature
    • Creates specs/001-first-feature/ directory
  3. Push branch 001-first-feature to remote (do NOT merge to main)
  4. Checkout main again
  5. Run the script to create feature 002:
    .\.specify\scripts\powershell\create-new-feature.ps1 -ShortName "second-feature"

Expected: Creates branch 002-second-feature
Actual: Creates branch 001-second-feature (reuses 001)

Root Cause

Looking at lines 82-92 of create-new-feature.ps1:

$existingSpecs = Get-ChildItem -Path $specsDir -Directory -ErrorAction SilentlyContinue |
    Where-Object { $_.Name -match '^\d{3}' } |
    ForEach-Object {
        if ($_.Name -match '^(\d{3})') {
            [int]$matches[1]
        }
    } |
    Sort-Object -Descending |
    Select-Object -First 1

The script only checks directories in $specsDir, not branch names via git branch.

Suggested Fix

Add branch checking logic before determining feature number:

# Get highest number from specs directory
$existingSpecs = Get-ChildItem -Path $specsDir -Directory -ErrorAction SilentlyContinue |
    Where-Object { $_.Name -match '^\d{3}' } |
    ForEach-Object {
        if ($_.Name -match '^(\d{3})') {
            [int]$matches[1]
        }
    } |
    Sort-Object -Descending |
    Select-Object -First 1

# Get highest number from branch names
$existingBranches = git branch -a | 
    ForEach-Object { $_.Trim() -replace '^\*?\s+', '' -replace '^remotes/origin/', '' } |
    Where-Object { $_ -match '^\d{3}-' } |
    ForEach-Object {
        if ($_ -match '^(\d{3})') {
            [int]$matches[1]
        }
    } |
    Sort-Object -Descending |
    Select-Object -First 1

# Use the highest number from either source
$highestExisting = [Math]::Max(
    $(if ($existingSpecs) { $existingSpecs } else { 0 }),
    $(if ($existingBranches) { $existingBranches } else { 0 })
)

$featureNumber = $highestExisting + 1

Workaround

Until fixed, merge spec directories to main after creating each feature branch, so the next run can see the previous feature number in the specs directory.

Environment

  • OS: Windows 11
  • PowerShell Version: 7.5.4
  • spec-kit: v0.0.20

Metadata

Metadata

Assignees

No one assigned

    Labels

    templatesRelated to template definition and not the CLI.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions