mirror of
https://github.com/github/spec-kit.git
synced 2026-02-02 05:53:36 +00:00
fix: improve branch number detection to check all sources
- Use git ls-remote for more reliable remote branch detection - Check remote branches, local branches, AND specs directories - Match exact short-name pattern to avoid false positives - Ensures no duplicate numbers across all sources
This commit is contained in:
@@ -87,12 +87,21 @@ check_existing_branches() {
|
|||||||
# Fetch all remotes to get latest branch info (suppress errors if no remotes)
|
# Fetch all remotes to get latest branch info (suppress errors if no remotes)
|
||||||
git fetch --all --prune 2>/dev/null || true
|
git fetch --all --prune 2>/dev/null || true
|
||||||
|
|
||||||
# Find all branches matching the pattern (local and remote)
|
# Find all branches matching the pattern using git ls-remote (more reliable)
|
||||||
local branches=$(git branch -a 2>/dev/null | grep -E "feature/[0-9]+-${short_name}$" | sed 's/.*feature\///' | sed "s/-${short_name}$//" | sort -n)
|
local remote_branches=$(git ls-remote --heads origin 2>/dev/null | grep -E "refs/heads/[0-9]+-${short_name}$" | sed 's/.*\/\([0-9]*\)-.*/\1/' | sort -n)
|
||||||
|
|
||||||
# Get the highest number
|
# Also check local branches
|
||||||
|
local local_branches=$(git branch 2>/dev/null | grep -E "^[* ]*[0-9]+-${short_name}$" | sed 's/^[* ]*//' | sed 's/-.*//' | sort -n)
|
||||||
|
|
||||||
|
# Check specs directory as well
|
||||||
|
local spec_dirs=""
|
||||||
|
if [ -d "$SPECS_DIR" ]; then
|
||||||
|
spec_dirs=$(find "$SPECS_DIR" -maxdepth 1 -type d -name "[0-9]*-${short_name}" 2>/dev/null | xargs -n1 basename 2>/dev/null | sed 's/-.*//' | sort -n)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Combine all sources and get the highest number
|
||||||
local max_num=0
|
local max_num=0
|
||||||
for num in $branches; do
|
for num in $remote_branches $local_branches $spec_dirs; do
|
||||||
if [ "$num" -gt "$max_num" ]; then
|
if [ "$num" -gt "$max_num" ]; then
|
||||||
max_num=$num
|
max_num=$num
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ function Find-RepositoryRoot {
|
|||||||
|
|
||||||
function Get-NextBranchNumber {
|
function Get-NextBranchNumber {
|
||||||
param(
|
param(
|
||||||
[string]$ShortName
|
[string]$ShortName,
|
||||||
|
[string]$SpecsDir
|
||||||
)
|
)
|
||||||
|
|
||||||
# Fetch all remotes to get latest branch info (suppress errors if no remotes)
|
# Fetch all remotes to get latest branch info (suppress errors if no remotes)
|
||||||
@@ -71,13 +72,13 @@ function Get-NextBranchNumber {
|
|||||||
# Ignore fetch errors
|
# Ignore fetch errors
|
||||||
}
|
}
|
||||||
|
|
||||||
# Find all branches matching the pattern (local and remote)
|
# Find remote branches matching the pattern using git ls-remote
|
||||||
$branches = @()
|
$remoteBranches = @()
|
||||||
try {
|
try {
|
||||||
$allBranches = git branch -a 2>$null
|
$remoteRefs = git ls-remote --heads origin 2>$null
|
||||||
if ($allBranches) {
|
if ($remoteRefs) {
|
||||||
$branches = $allBranches | Where-Object { $_ -match "feature/(\d+)-$([regex]::Escape($ShortName))$" } | ForEach-Object {
|
$remoteBranches = $remoteRefs | Where-Object { $_ -match "refs/heads/(\d+)-$([regex]::Escape($ShortName))$" } | ForEach-Object {
|
||||||
if ($_ -match "feature/(\d+)-") {
|
if ($_ -match "refs/heads/(\d+)-") {
|
||||||
[int]$matches[1]
|
[int]$matches[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,9 +87,38 @@ function Get-NextBranchNumber {
|
|||||||
# Ignore errors
|
# Ignore errors
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get the highest number
|
# Check local branches
|
||||||
|
$localBranches = @()
|
||||||
|
try {
|
||||||
|
$allBranches = git branch 2>$null
|
||||||
|
if ($allBranches) {
|
||||||
|
$localBranches = $allBranches | Where-Object { $_ -match "^\*?\s*(\d+)-$([regex]::Escape($ShortName))$" } | ForEach-Object {
|
||||||
|
if ($_ -match "(\d+)-") {
|
||||||
|
[int]$matches[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
# Ignore errors
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check specs directory
|
||||||
|
$specDirs = @()
|
||||||
|
if (Test-Path $SpecsDir) {
|
||||||
|
try {
|
||||||
|
$specDirs = Get-ChildItem -Path $SpecsDir -Directory | Where-Object { $_.Name -match "^(\d+)-$([regex]::Escape($ShortName))$" } | ForEach-Object {
|
||||||
|
if ($_.Name -match "^(\d+)-") {
|
||||||
|
[int]$matches[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
# Ignore errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Combine all sources and get the highest number
|
||||||
$maxNum = 0
|
$maxNum = 0
|
||||||
foreach ($num in $branches) {
|
foreach ($num in ($remoteBranches + $localBranches + $specDirs)) {
|
||||||
if ($num -gt $maxNum) {
|
if ($num -gt $maxNum) {
|
||||||
$maxNum = $num
|
$maxNum = $num
|
||||||
}
|
}
|
||||||
@@ -178,7 +208,7 @@ if ($ShortName) {
|
|||||||
if ($Number -eq 0) {
|
if ($Number -eq 0) {
|
||||||
if ($hasGit) {
|
if ($hasGit) {
|
||||||
# Check existing branches on remotes
|
# Check existing branches on remotes
|
||||||
$Number = Get-NextBranchNumber -ShortName $branchSuffix
|
$Number = Get-NextBranchNumber -ShortName $branchSuffix -SpecsDir $specsDir
|
||||||
} else {
|
} else {
|
||||||
# Fall back to local directory check
|
# Fall back to local directory check
|
||||||
$highest = 0
|
$highest = 0
|
||||||
|
|||||||
@@ -38,14 +38,14 @@ Given that feature description, do this:
|
|||||||
git fetch --all --prune
|
git fetch --all --prune
|
||||||
```
|
```
|
||||||
|
|
||||||
b. List all branches (local and remote) that match the short-name pattern:
|
b. Find the highest feature number across all sources for the short-name:
|
||||||
```bash
|
- Remote branches: `git ls-remote --heads origin | grep -E 'refs/heads/[0-9]+-<short-name>$'`
|
||||||
git branch -a | grep -E "feature/[0-9]+-<short-name>$"
|
- Local branches: `git branch | grep -E '^[* ]*[0-9]+-<short-name>$'`
|
||||||
```
|
- Specs directories: Check for directories matching `specs/[0-9]+-<short-name>`
|
||||||
|
|
||||||
c. Determine the next available number:
|
c. Determine the next available number:
|
||||||
- Extract all numbers from existing branches (both local and remote)
|
- Extract all numbers from all three sources
|
||||||
- Find the highest number N from branches that exist
|
- Find the highest number N
|
||||||
- Use N+1 for the new branch number
|
- Use N+1 for the new branch number
|
||||||
|
|
||||||
d. Run the script `{SCRIPT}` with the calculated number and short-name:
|
d. Run the script `{SCRIPT}` with the calculated number and short-name:
|
||||||
@@ -54,8 +54,9 @@ Given that feature description, do this:
|
|||||||
- PowerShell example: `{SCRIPT} -Json -Number 5 -ShortName "user-auth" "Add user authentication"`
|
- PowerShell example: `{SCRIPT} -Json -Number 5 -ShortName "user-auth" "Add user authentication"`
|
||||||
|
|
||||||
**IMPORTANT**:
|
**IMPORTANT**:
|
||||||
- Only consider branches that still exist (local or remote)
|
- Check all three sources (remote branches, local branches, specs directories) to find the highest number
|
||||||
- If no existing branches found with this short-name, start with number 1
|
- Only match branches/directories with the exact short-name pattern
|
||||||
|
- If no existing branches/directories found with this short-name, start with number 1
|
||||||
- The JSON output will contain BRANCH_NAME and SPEC_FILE paths
|
- The JSON output will contain BRANCH_NAME and SPEC_FILE paths
|
||||||
- You must only ever run this script once per feature
|
- You must only ever run this script once per feature
|
||||||
- For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\''m Groot' (or double-quote if possible: "I'm Groot")
|
- For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\''m Groot' (or double-quote if possible: "I'm Groot")
|
||||||
|
|||||||
Reference in New Issue
Block a user