```skill --- name: create-branch description: Git branch naming convention and creation workflow — handles working tree state, default branch detection, and interactive cleanup before branching. --- # Create Branch ## Just-In-Time Invocation Use this skill as the just-in-time mutation gate before the first code-writing step. Do not treat this skill as a mandatory startup blocker for read-only startup analysis or planning. Run this skill after the task graph is known and before the first task-executor launch. ## Branch Naming Convention Format: `{type}/{jira}_{slug}` - `{type}` — work type: `feature`, `fix`, `chore` - `{jira}` — JIRA ticket ID (e.g., `CACTUS-1234`) - `{slug}` — 3-word snake_case descriptor Examples: - `feature/CACTUS-1234_add_user_authentication` - `fix/PROJ-567_fix_login_button` - `chore/CACTUS-890_update_dependencies` ## Default Branch Detection Detect the default branch name: ```sh git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' ``` Fallback: check if `master` exists, else `main`. Store as `{default_branch}`. ## Git State Initialization Run these checks BEFORE creating a branch: ### 1. Get Current State ```sh CURRENT_BRANCH=$(git branch --show-current) IS_DIRTY=$(git status --porcelain) ``` Collect changed paths (staged, unstaged, untracked) and classify whether the dirty tree is documentation-only: ```sh CHANGED_FILES=$( { git diff --name-only git diff --cached --name-only git ls-files --others --exclude-standard } | sed '/^$/d' | sort -u ) NON_DOC_FILES=$(printf '%s\n' "$CHANGED_FILES" | grep -Ev '^(docs/|.*\.md$|docs/docs_cache_state\.yaml$)' || true) DOCS_ONLY_DIRTY=false if [ -n "$CHANGED_FILES" ] && [ -z "$NON_DOC_FILES" ]; then DOCS_ONLY_DIRTY=true fi ``` ### 2. Handle State Matrix | Current Branch | Working Tree | Action | |---------------|--------------|--------| | `{default_branch}` | Clean | `git pull` → create branch | | `{default_branch}` | Dirty (docs-only) | Auto-stash docs → `git pull` → create branch → `git stash pop` | | `{default_branch}` | Dirty (non-doc or mixed) | Ask user → handle → `git pull` → create branch | | Other branch | Clean | `git checkout {default_branch}` → `git pull` → create branch | | Other branch | Dirty (docs-only) | Auto-stash docs → `git checkout {default_branch}` → `git pull` → create branch → `git stash pop` | | Other branch | Dirty (non-doc or mixed) | Ask user → handle → `git checkout {default_branch}` → `git pull` → create branch | ### 3. Documentation-Only Dirty Tree (Automatic Path) If the working tree is dirty and `DOCS_ONLY_DIRTY=true`, do not prompt the user. 1. `git stash push -u -m "WIP: docs-only auto-stash before {jira}"` 2. Continue normal branch setup (`checkout {default_branch}` when needed, `git pull`, then create/switch target branch) 3. `git stash pop` If `git stash pop` reports conflicts, stop and ask the user how to resolve the conflict before continuing. ### 3. Dirty Working Tree Options When dirty and the changes are non-doc or mixed, present these options to the user (use `ask_questions` tool): - **Stash changes**: `git stash push -m "WIP: auto-stash before {jira}"` — saves changes for later - **Discard changes**: `git checkout -- . && git clean -fd` — permanently removes uncommitted changes - **Abort**: Stop the workflow — user handles git state manually After stashing or discarding, working tree is clean. Proceed with checkout/pull. ## Branch Creation After git state is clean and on `{default_branch}` with latest pulled: ```sh # Check if branch already exists locally git branch --list "{type}/{jira}_{slug}" # Check if branch exists on remote git ls-remote --heads origin "{type}/{jira}_{slug}" ``` - **Does not exist**: `git checkout -b {type}/{jira}_{slug}` - **Exists locally**: `git checkout {type}/{jira}_{slug}` - **Exists only on remote**: `git checkout -b {type}/{jira}_{slug} origin/{type}/{jira}_{slug}` ```