---
name: step-start
description: Create new branch with worktree
next_step: null
---

# Step: START - Create Branch

## YOUR TASK:

Create a new feature/release/hotfix branch with optional worktree setup.

**ULTRA THINK about branch naming and base selection.**

---

## INPUT PARSING:

```
{branch_type} = feature | release | hotfix
{branch_name} = normalized name (kebab-case)
{no_worktree} = --no-worktree flag present
```

**From flags:**
- `-f {name}` → branch_type=feature, branch_name={name}
- `-r {name}` → branch_type=release, branch_name={name}
- `-h {name}` → branch_type=hotfix, branch_name={name}

---

## EXECUTION SEQUENCE:

### 1. Load Config and Analyze Context

```bash
# Load GitFlow config (sets GF_* variables)
# See _shared.md → READ_GITFLOW_CONFIG for all variables
read_gitflow_config || { echo "❌ Run /gitflow init first."; exit 1; }

CURRENT_BRANCH=$(git branch --show-current)
git fetch origin --quiet

# Version from config
VERSION="$GF_VERSION"
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "none")

# Develop ahead of main?
DEVELOP_AHEAD=$(git rev-list --count origin/$GF_MAIN_BRANCH..origin/$GF_DEVELOP_BRANCH 2>/dev/null || echo "0")

# Working directory status
DIRTY=$(git status --porcelain | wc -l)
```

**Display:**
```
Current: {CURRENT_BRANCH} | Version: {VERSION} | Tag: {LAST_TAG}
Develop → Main: {DEVELOP_AHEAD} commits {DEVELOP_AHEAD > 10 ? "(Release recommended)" : ""}
```

### 2. Interactive Questions (if no args)

**If branch_type missing:**
```yaml
AskUserQuestion:
  header: "Type"
  question: "What type of branch?"
  options:
    - label: "Feature"
      description: "New feature from develop"
    - label: "Release v{X.Y+1.0}"
      description: "Prepare release from develop"
    - label: "Hotfix"
      description: "Urgent fix from main"
```

**If branch_name missing:**
```yaml
AskUserQuestion:
  header: "Name"
  question: "Branch name? (will be normalized to kebab-case)"
  # Free text input
```

### 3. Normalize and Validate

```bash
# Normalize name
normalize_branch_name() {
  echo "$1" | tr '[:upper:]' '[:lower:]' | \
    sed 'y/àâäéèêëïîôùûüçœæ/aaaeeeeiioouucoa/' | \
    sed "s/[ _']/-/g" | sed 's/[^a-z0-9-]//g' | \
    sed 's/--*/-/g' | sed 's/^-//;s/-$//' | cut -c1-50
}

BRANCH_NAME=$(normalize_branch_name "$branch_name")
FULL_BRANCH="${branch_type}/${BRANCH_NAME}"

# Check if exists
LOCAL_EXISTS=$(git branch --list "$FULL_BRANCH")
REMOTE_EXISTS=$(git branch -r --list "origin/$FULL_BRANCH")

[ -n "$LOCAL_EXISTS" ] || [ -n "$REMOTE_EXISTS" ] && {
  echo "ERROR: Branch '$FULL_BRANCH' already exists"
  # Options: Different name | Checkout existing | Delete and recreate
}
```

### 4. Determine Base Branch

| Type | Base Branch | Target |
|------|-------------|--------|
| feature | develop | develop |
| release | develop | main + develop |
| hotfix | main | main + develop |

```bash
case "$branch_type" in
  feature) BASE_BRANCH="develop"; TARGET="develop" ;;
  release) BASE_BRANCH="develop"; TARGET="main" ;;
  hotfix)  BASE_BRANCH="main"; TARGET="main" ;;
esac
```

### 5. Handle Dirty Working Directory

```bash
[ "$DIRTY" -gt 0 ] && {
  echo "Working directory has uncommitted changes"
  # Options: Stash | Commit | Continue anyway | Cancel
}
```

### 5b. EF Core Migration Pre-flight (Release/Hotfix only)

**BLOCKING CHECK: Validate migration naming conventions BEFORE creating the release branch.**

See [references/start-efcore-preflight.md](../references/start-efcore-preflight.md) for the full validation script and user choice handling.

Expected format: `{context}_v{version}_{sequence}_{Description}` (e.g., `core_v2.0.0_001_InitialSchema`)

---

### 6. Create Branch and Worktree

**Read worktree mode from config (already loaded by read_gitflow_config):**
```bash
WORKTREE_MODE="$GF_WORKTREE_MODE"
```

**Mode: organized (uses absolute paths from config)**
```bash
case "$branch_type" in
  feature) WORKTREE_PATH="$GF_FEATURES_PATH/$BRANCH_NAME" ;;
  release) WORKTREE_PATH="$GF_RELEASES_PATH/v$VERSION" ;;
  hotfix)  WORKTREE_PATH="$GF_HOTFIXES_PATH/$BRANCH_NAME" ;;
esac

mkdir -p "$(dirname $WORKTREE_PATH)"
git worktree add -b "$FULL_BRANCH" "$WORKTREE_PATH" "origin/$BASE_BRANCH"

# Fix cross-platform paths in worktree metadata (if created from different platform)
repair_worktree_paths "$(git rev-parse --git-common-dir)"
```

**Mode: --no-worktree**
```bash
git checkout "$BASE_BRANCH" && git pull origin "$BASE_BRANCH"
git checkout -b "$FULL_BRANCH"
```

### 6b. Push Branch to Remote (AUTOMATIC)

**ALWAYS push immediately after branch creation:**
```bash
git push -u origin "$FULL_BRANCH"

# CRITICAL: Verify push and update tracking refs
git fetch origin $FULL_BRANCH:refs/remotes/origin/$FULL_BRANCH --force --quiet
LOCAL_SHA=$(git rev-parse HEAD)
REMOTE_SHA=$(git rev-parse origin/$FULL_BRANCH)
if [ "$LOCAL_SHA" = "$REMOTE_SHA" ]; then
  echo "✅ Branch pushed and verified - origin/$FULL_BRANCH in sync"
else
  echo "⚠️ Push verification failed"
  echo "  Local:  $LOCAL_SHA"
  echo "  Remote: $REMOTE_SHA"
fi
```

### 7. Create Local Environment Config (Backend + Frontend)

See [references/start-local-config.md](../references/start-local-config.md) for the full configuration:
- **Port generation:** Unique ports per branch (API: 5200+, Web: 5300+) based on branch name hash
- **7a. Backend:** `appsettings.Local.json` (DB connection, SmartStack config, Kestrel port)
- **7b. Frontend:** `.env.standalone` + `npm run local` script (Vite mode=standalone, not "local" which conflicts with .env.local in Vite 7+)
- **7c. Backend:** `launchSettings.json` Local profile with unique port
- **7d. Summary:** Display configured DB name, API port, Web port

### 8. Store State

```bash
# Save to state for next steps
{
  "branch_type": "{branch_type}",
  "branch_name": "{FULL_BRANCH}",
  "base_branch": "{BASE_BRANCH}",
  "target_branch": "{TARGET}",
  "worktree_path": "{WORKTREE_PATH}",
  "version_current": "{VERSION}",
  "local_config": {
    "database": "{DB_NAME}",
    "api_port": "{API_PORT}",
    "web_port": "{WEB_PORT}",
    "api_dir": "{API_DIR}",
    "web_dir": "{WEB_DIR}"
  }
}
```

### 9. Summary

```
╔══════════════════════════════════════════════════════════════════╗
║                    {BRANCH_TYPE} CREATED                          ║
╠══════════════════════════════════════════════════════════════════╣
║  Branch:   {FULL_BRANCH}                                          ║
║  Base:     {BASE_BRANCH}                                          ║
║  Target:   {TARGET}                                               ║
║  Worktree: {WORKTREE_PATH}                                        ║
╠══════════════════════════════════════════════════════════════════╣
║  LOCAL ENVIRONMENT:                                               ║
║  Database: {DB_NAME}                                              ║
║  API:      http://localhost:{API_PORT}                            ║
║  Web:      http://localhost:{WEB_PORT}                            ║
╠══════════════════════════════════════════════════════════════════╣
║  NEXT STEPS:                                                      ║
║                                                                    ║
║  1. Go to worktree:                                               ║
║     cd {WORKTREE_PATH}                                            ║
║                                                                    ║
║  2. Start backend (auto-migrates Core + Extensions DB):           ║
║     dotnet run --project src/{Project}.Api --launch-profile Local ║
║                                                                    ║
║  3. Reset admin password:                                         ║
║     ss admin reset                                                ║
║                                                                    ║
║  4. Start frontend (other terminal):                              ║
║     cd web/{project}-web && npm run local                         ║
║                                                                    ║
║  5. Make changes and commit:                                      ║
║     /gitflow commit                                               ║
║                                                                    ║
║  6. Create pull request:                                          ║
║     /gitflow pr                                                   ║
║                                                                    ║
║  7. After PR merged, finalize:                                    ║
║     /gitflow finish                                               ║
╚══════════════════════════════════════════════════════════════════╝
```

---

## ERROR HANDLING:

| Error | Solution |
|-------|----------|
| Branch exists | Offer: rename, checkout, or delete |
| Dirty working directory | Offer: stash, commit, or continue |
| Worktree path exists | Remove orphan or use different path |
| Base branch behind remote | Pull before creating |

---

## SUCCESS CRITERIA:

- Branch created from correct base
- **Branch pushed to remote (AUTOMATIC)**
- Worktree set up (if enabled)
- Backend local config created: `appsettings.Local.json` (if .NET API detected)
- Backend launch profile created: `launchSettings.json` Local profile with unique port (if .NET API detected)
- Frontend local config created: `.env.standalone` + `npm run local` script (if web project detected)
- Ports synchronized between backend and frontend (unique per branch)
- State stored for subsequent steps

## NEXT STEP:

User works on code, then runs `/gitflow commit`.
