44
55JSON_MODE=false
66SHORT_NAME=" "
7+ BRANCH_NUMBER=" "
78ARGS=()
89i=1
910while [ $i -le $# ]; do
@@ -26,17 +27,31 @@ while [ $i -le $# ]; do
2627 fi
2728 SHORT_NAME=" $next_arg "
2829 ;;
30+ --number)
31+ if [ $(( i + 1 )) -gt $# ]; then
32+ echo ' Error: --number requires a value' >&2
33+ exit 1
34+ fi
35+ i=$(( i + 1 ))
36+ next_arg=" ${! i} "
37+ if [[ " $next_arg " == --* ]]; then
38+ echo ' Error: --number requires a value' >&2
39+ exit 1
40+ fi
41+ BRANCH_NUMBER=" $next_arg "
42+ ;;
2943 --help|-h)
30- echo " Usage: $0 [--json] [--short-name <name>] <feature_description>"
44+ echo " Usage: $0 [--json] [--short-name <name>] [--number N] <feature_description>"
3145 echo " "
3246 echo " Options:"
3347 echo " --json Output in JSON format"
3448 echo " --short-name <name> Provide a custom short name (2-4 words) for the branch"
49+ echo " --number N Specify branch number manually (overrides auto-detection)"
3550 echo " --help, -h Show this help message"
3651 echo " "
3752 echo " Examples:"
3853 echo " $0 'Add user authentication system' --short-name 'user-auth'"
39- echo " $0 'Implement OAuth2 integration for API'"
54+ echo " $0 'Implement OAuth2 integration for API' --number 5 "
4055 exit 0
4156 ;;
4257 * )
4863
4964FEATURE_DESCRIPTION=" ${ARGS[*]} "
5065if [ -z " $FEATURE_DESCRIPTION " ]; then
51- echo " Usage: $0 [--json] [--short-name <name>] <feature_description>" >&2
66+ echo " Usage: $0 [--json] [--short-name <name>] [--number N] <feature_description>" >&2
5267 exit 1
5368fi
5469
@@ -65,6 +80,37 @@ find_repo_root() {
6580 return 1
6681}
6782
83+ # Function to check existing branches (local and remote) and return next available number
84+ check_existing_branches () {
85+ local short_name=" $1 "
86+
87+ # Fetch all remotes to get latest branch info (suppress errors if no remotes)
88+ git fetch --all --prune 2> /dev/null || true
89+
90+ # Find all branches matching the pattern using git ls-remote (more reliable)
91+ 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)
92+
93+ # Also check local branches
94+ local local_branches=$( git branch 2> /dev/null | grep -E " ^[* ]*[0-9]+-${short_name} $" | sed ' s/^[* ]*//' | sed ' s/-.*//' | sort -n)
95+
96+ # Check specs directory as well
97+ local spec_dirs=" "
98+ if [ -d " $SPECS_DIR " ]; then
99+ 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)
100+ fi
101+
102+ # Combine all sources and get the highest number
103+ local max_num=0
104+ for num in $remote_branches $local_branches $spec_dirs ; do
105+ if [ " $num " -gt " $max_num " ]; then
106+ max_num=$num
107+ fi
108+ done
109+
110+ # Return next number
111+ echo $(( max_num + 1 ))
112+ }
113+
68114# Resolve repository root. Prefer git information when available, but fall back
69115# to searching for repository markers so the workflow still functions in repositories that
70116# were initialised with --no-git.
@@ -87,20 +133,6 @@ cd "$REPO_ROOT"
87133SPECS_DIR=" $REPO_ROOT /specs"
88134mkdir -p " $SPECS_DIR "
89135
90- HIGHEST=0
91- if [ -d " $SPECS_DIR " ]; then
92- for dir in " $SPECS_DIR " /* ; do
93- [ -d " $dir " ] || continue
94- dirname=$( basename " $dir " )
95- number=$( echo " $dirname " | grep -o ' ^[0-9]\+' || echo " 0" )
96- number=$(( 10 #$number ))
97- if [ " $number " -gt " $HIGHEST " ]; then HIGHEST=$number ; fi
98- done
99- fi
100-
101- NEXT=$(( HIGHEST + 1 ))
102- FEATURE_NUM=$( printf " %03d" " $NEXT " )
103-
104136# Function to generate branch name with stop word filtering and length filtering
105137generate_branch_name () {
106138 local description=" $1 "
@@ -157,6 +189,28 @@ else
157189 BRANCH_SUFFIX=$( generate_branch_name " $FEATURE_DESCRIPTION " )
158190fi
159191
192+ # Determine branch number
193+ if [ -z " $BRANCH_NUMBER " ]; then
194+ if [ " $HAS_GIT " = true ]; then
195+ # Check existing branches on remotes
196+ BRANCH_NUMBER=$( check_existing_branches " $BRANCH_SUFFIX " )
197+ else
198+ # Fall back to local directory check
199+ HIGHEST=0
200+ if [ -d " $SPECS_DIR " ]; then
201+ for dir in " $SPECS_DIR " /* ; do
202+ [ -d " $dir " ] || continue
203+ dirname=$( basename " $dir " )
204+ number=$( echo " $dirname " | grep -o ' ^[0-9]\+' || echo " 0" )
205+ number=$(( 10 #$number ))
206+ if [ " $number " -gt " $HIGHEST " ]; then HIGHEST=$number ; fi
207+ done
208+ fi
209+ BRANCH_NUMBER=$(( HIGHEST + 1 ))
210+ fi
211+ fi
212+
213+ FEATURE_NUM=$( printf " %03d" " $BRANCH_NUMBER " )
160214BRANCH_NAME=" ${FEATURE_NUM} -${BRANCH_SUFFIX} "
161215
162216# GitHub enforces a 244-byte limit on branch names
0 commit comments