mirror of
https://github.com/github/spec-kit.git
synced 2026-01-30 04:32:02 +00:00
Merge pull request #1237 from Mearman/fix/branch-number-collision-bug
fix: use global maximum for branch numbering to prevent collisions
This commit is contained in:
@@ -128,32 +128,23 @@ get_highest_from_branches() {
|
|||||||
|
|
||||||
# Function to check existing branches (local and remote) and return next available number
|
# Function to check existing branches (local and remote) and return next available number
|
||||||
check_existing_branches() {
|
check_existing_branches() {
|
||||||
local short_name="$1"
|
local specs_dir="$1"
|
||||||
local specs_dir="$2"
|
|
||||||
|
|
||||||
# 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 using git ls-remote (more reliable)
|
# Get highest number from ALL branches (not just matching short name)
|
||||||
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)
|
local highest_branch=$(get_highest_from_branches)
|
||||||
|
|
||||||
# Also check local branches
|
# Get highest number from ALL specs (not just matching short name)
|
||||||
local local_branches=$(git branch 2>/dev/null | grep -E "^[* ]*[0-9]+-${short_name}$" | sed 's/^[* ]*//' | sed 's/-.*//' | sort -n)
|
local highest_spec=$(get_highest_from_specs "$specs_dir")
|
||||||
|
|
||||||
# Check specs directory as well
|
# Take the maximum of both
|
||||||
local spec_dirs=""
|
local max_num=$highest_branch
|
||||||
if [ -d "$specs_dir" ]; then
|
if [ "$highest_spec" -gt "$max_num" ]; 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)
|
max_num=$highest_spec
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Combine all sources and get the highest number
|
|
||||||
local max_num=0
|
|
||||||
for num in $remote_branches $local_branches $spec_dirs; do
|
|
||||||
if [ "$num" -gt "$max_num" ]; then
|
|
||||||
max_num=$num
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Return next number
|
# Return next number
|
||||||
echo $((max_num + 1))
|
echo $((max_num + 1))
|
||||||
}
|
}
|
||||||
@@ -247,7 +238,7 @@ fi
|
|||||||
if [ -z "$BRANCH_NUMBER" ]; then
|
if [ -z "$BRANCH_NUMBER" ]; then
|
||||||
if [ "$HAS_GIT" = true ]; then
|
if [ "$HAS_GIT" = true ]; then
|
||||||
# Check existing branches on remotes
|
# Check existing branches on remotes
|
||||||
BRANCH_NUMBER=$(check_existing_branches "$BRANCH_SUFFIX" "$SPECS_DIR")
|
BRANCH_NUMBER=$(check_existing_branches "$SPECS_DIR")
|
||||||
else
|
else
|
||||||
# Fall back to local directory check
|
# Fall back to local directory check
|
||||||
HIGHEST=$(get_highest_from_specs "$SPECS_DIR")
|
HIGHEST=$(get_highest_from_specs "$SPECS_DIR")
|
||||||
@@ -255,7 +246,8 @@ if [ -z "$BRANCH_NUMBER" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
FEATURE_NUM=$(printf "%03d" "$BRANCH_NUMBER")
|
# Force base-10 interpretation to prevent octal conversion (e.g., 010 → 8 in octal, but should be 10 in decimal)
|
||||||
|
FEATURE_NUM=$(printf "%03d" "$((10#$BRANCH_NUMBER))")
|
||||||
BRANCH_NAME="${FEATURE_NUM}-${BRANCH_SUFFIX}"
|
BRANCH_NAME="${FEATURE_NUM}-${BRANCH_SUFFIX}"
|
||||||
|
|
||||||
# GitHub enforces a 244-byte limit on branch names
|
# GitHub enforces a 244-byte limit on branch names
|
||||||
|
|||||||
@@ -101,69 +101,25 @@ function Get-HighestNumberFromBranches {
|
|||||||
|
|
||||||
function Get-NextBranchNumber {
|
function Get-NextBranchNumber {
|
||||||
param(
|
param(
|
||||||
[string]$ShortName,
|
|
||||||
[string]$SpecsDir
|
[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)
|
||||||
try {
|
try {
|
||||||
git fetch --all --prune 2>$null | Out-Null
|
git fetch --all --prune 2>$null | Out-Null
|
||||||
} catch {
|
} catch {
|
||||||
# Ignore fetch errors
|
# Ignore fetch errors
|
||||||
}
|
}
|
||||||
|
|
||||||
# Find remote branches matching the pattern using git ls-remote
|
# Get highest number from ALL branches (not just matching short name)
|
||||||
$remoteBranches = @()
|
$highestBranch = Get-HighestNumberFromBranches
|
||||||
try {
|
|
||||||
$remoteRefs = git ls-remote --heads origin 2>$null
|
# Get highest number from ALL specs (not just matching short name)
|
||||||
if ($remoteRefs) {
|
$highestSpec = Get-HighestNumberFromSpecs -SpecsDir $SpecsDir
|
||||||
$remoteBranches = $remoteRefs | Where-Object { $_ -match "refs/heads/(\d+)-$([regex]::Escape($ShortName))$" } | ForEach-Object {
|
|
||||||
if ($_ -match "refs/heads/(\d+)-") {
|
# Take the maximum of both
|
||||||
[int]$matches[1]
|
$maxNum = [Math]::Max($highestBranch, $highestSpec)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
# Ignore errors
|
|
||||||
}
|
|
||||||
|
|
||||||
# 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
|
|
||||||
foreach ($num in ($remoteBranches + $localBranches + $specDirs)) {
|
|
||||||
if ($num -gt $maxNum) {
|
|
||||||
$maxNum = $num
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Return next number
|
# Return next number
|
||||||
return $maxNum + 1
|
return $maxNum + 1
|
||||||
}
|
}
|
||||||
@@ -254,7 +210,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 -SpecsDir $specsDir
|
$Number = Get-NextBranchNumber -SpecsDir $specsDir
|
||||||
} else {
|
} else {
|
||||||
# Fall back to local directory check
|
# Fall back to local directory check
|
||||||
$Number = (Get-HighestNumberFromSpecs -SpecsDir $specsDir) + 1
|
$Number = (Get-HighestNumberFromSpecs -SpecsDir $specsDir) + 1
|
||||||
|
|||||||
Reference in New Issue
Block a user