113 lines
4.0 KiB
Markdown
113 lines
4.0 KiB
Markdown
```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}`
|
|
```
|