Finishing a Development Branch
Overview
Present clear options. Handle chosen workflow.
Core principle: Verify tests → detect environment → present options → execute choice → clean up.
Announce at start: "I'm using the superpowers-finishing-a-development-branch skill to complete this work."
The Process
Step 1: Verify Tests
Verify tests pass before options (use superpowers-verification-before-completion):
bashnpm test / cargo test / pytest / go test ./...
Tests fail: report failures. Cannot merge/PR until they pass. Stop. Tests pass: continue.
Step 2: Detect Environment
Capture all three up front, before any later step changes directory — WORKTREE_PATH must reflect where you are now, not after Step 5 has cd'd to the main repo root:
bashGIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P) GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P) WORKTREE_PATH=$(git rev-parse --show-toplevel)
| State | Menu | Cleanup |
|---|---|---|
GIT_DIR == GIT_COMMON (normal repo) | Standard 4 options | No worktree to clean up |
GIT_DIR != GIT_COMMON, named branch | Standard 4 options | Provenance-based (Step 6) |
GIT_DIR != GIT_COMMON, detached HEAD | Reduced 3 options (no merge) | No cleanup (externally managed) |
Step 3: Determine Base Branch
bashgit merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null
Or ask: "Branch split from main — correct?"
Step 4: Present Options
Normal repo or named-branch worktree — present exactly these 4 options:
Implementation complete. What would you like to do? 1. Merge back to <base-branch> locally 2. Push and create a Pull Request 3. Keep the branch as-is (I'll handle it later) 4. Discard this work Which option?
Detached HEAD — present exactly these 3 options:
Implementation complete. You're on a detached HEAD (externally managed workspace). 1. Push as new branch and create a Pull Request 2. Keep as-is (I'll handle it later) 3. Discard this work Which option?
Don't add explanation. Keep options concise.
Step 5: Execute Choice
Option 1: Merge Locally
bashMAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel) cd "$MAIN_ROOT" git checkout <base-branch> git pull git merge <feature-branch> <test command> # Verify tests on merged result
After merge succeeds: cleanup worktree (Step 6), then git branch -d <feature-branch>.
Option 2: Push and Create PR
bashgit push -u origin <feature-branch> gh pr create --title "<title>" --body "$(cat <<'EOF' ## Summary <2-3 bullets of what changed> ## Test Plan - [ ] <verification steps> EOF )"
Do NOT clean up the worktree — needed alive for PR feedback.
Option 3: Keep As-Is
Report: "Keeping branch . Worktree preserved at ." No cleanup.
Option 4: Discard
Confirm first — require typed discard:
This will permanently delete: - Branch <name> - All commits: <commit-list> - Worktree at <path> Type 'discard' to confirm.
Confirmed: cd to main repo root, cleanup worktree (Step 6), then git branch -D <feature-branch>.
Step 6: Cleanup Workspace
Runs for Options 1 and 4 only. Options 2 and 3 preserve worktree.
Reuse the GIT_DIR, GIT_COMMON, and WORKTREE_PATH captured in Step 2 — do NOT recompute them here. Step 5 (Options 1 and 4) has already cd'd to the main repo root, so a fresh git rev-parse --show-toplevel would return the main repo, not the worktree, and remove the wrong path. Removal must run from outside the worktree.
If GIT_DIR == GIT_COMMON: normal repo, nothing to clean up.
If WORKTREE_PATH under .worktrees/, worktrees/, or ~/.config/reasonix/worktrees/: we created it — we own cleanup:
bashgit worktree remove "$WORKTREE_PATH" git worktree prune
If removal is refused (contains modified or untracked files): worktree holds files that exist nowhere else — uncommitted plans, notes, scratch work. Never --force on your own initiative. Show the user what's at stake and ask:
bashgit -C "$WORKTREE_PATH" status --porcelain -uall
Worktree removal refused — these files were never committed: <file list> 1. Commit them to <branch> before cleanup 2. Move them into <main repo root> 3. Delete them (unrecoverable) Which?
Carry out the choice, then remove the worktree.
Otherwise: harness owns workspace. Do NOT remove it. Workspace-exit tool available? Use it. Else leave in place.
Quick Reference
| Option | Merge | Push | Keep Worktree | Cleanup Branch |
|---|---|---|---|---|
| 1. Merge locally | yes | - | - | yes |
| 2. Create PR | - | yes | yes | - |
| 3. Keep as-is | - | - | yes | - |
| 4. Discard | - | - | - | yes (force) |
Red Flags
Never: proceed on failing tests; merge without verifying tests on result; delete work without typed confirmation; force-push without explicit request; remove worktree before merge confirmed; clean up worktrees you didn't create; git worktree remove from inside the worktree; treat a removal-refused error as "just add --force" — it means files exist only there, so show the user and ask.
Always: verify tests before options; detect environment before menu; present exactly 4 options (3 detached HEAD); typed confirmation for Option 4; clean up worktree for Options 1 & 4 only; cd to main repo root before removal; git worktree prune after.


