Skip to main content
AC
Delivery & Handoff5.1 KBMIT licensed

finishing-a-development-branch

Rewritten from patterns in obra/superpowers (MIT)

Close out a completed development branch: verify tests, then present merge, PR, keep, or discard options and execute the choice with safe worktree cleanup. Use when implementation is done and the work needs integrating. Not for executing the plan itself: use executing-plans. Not for commit and branching discipline during development: use git-workflow-and-versioning.

  • finishing
  • development
  • branch

SKILL.md

Finishing a Development Branch

Tests pass first, then the user picks from a fixed menu, then you execute exactly that choice. No open-ended "what next?", no cleanup that destroys work, no merge on red.

Workflow

  1. Verify tests. Run the project suite (npm test, pytest, cargo test, go test ./...). Failures: show them, state "cannot merge or PR until tests pass", and stop. Do not present options over a red suite.
  2. Detect the environment. Compare git rev-parse --git-dir with git rev-parse --git-common-dir (resolve both with pwd -P). Equal: normal repo. Different with a named branch: worktree you may need to clean up. Different with detached HEAD: externally managed workspace, reduced menu, never clean up.
  3. Determine the base branch. git merge-base HEAD main || git merge-base HEAD master, or ask: "This branch split from main, correct?"
  4. Present the fixed menu. Normal repo or named-branch worktree, exactly these four: 1) merge back to base locally, 2) push and create a PR, 3) keep the branch as-is, 4) discard this work. Detached HEAD, exactly three: push as new branch and PR, keep as-is, discard. No explanations attached, keep it terse.
  5. Execute the choice. Read references/option-playbooks.md before executing, it has the exact command sequence and cleanup rules per option. The invariants: merge before any cleanup, re-run tests on the merged result, worktree survives for options 2 and 3, discard requires the user to type discard.
  6. Clean up only what you own. Only options 1 and 4 clean up, and only worktrees under .worktrees/ or worktrees/. Anything else was created by the host environment: leave it alone. Always cd to the main repo root before git worktree remove, then git worktree prune.

Quick reference

OptionMergePushKeep worktreeDelete branch
1 Merge locallyyes--yes, after cleanup
2 Create PR-yesyes-
3 Keep as-is--yes-
4 Discard---yes, force, after typed confirm

Good vs bad

Bad: Tests are failing but the diff "looks fine", so you present the menu, the user picks merge, and main is now broken. Then you remove the worktree the user needed for the follow-up PR.

Good: Suite is green, you detect a named-branch worktree under .worktrees/, present the four options, user picks PR. You push with -u, report the branch name, and leave the worktree in place for review iteration.

Verification

After executing option 1, run git status on the base branch and the test suite. Expect: clean tree, merged commits present in git log, suite green, feature branch deleted, worktree removed and git worktree list no longer shows it. Anything else: stop, report the exact failing step, do not continue cleanup.

Completion checklist

  • [ ] Test suite run and green before the menu
  • [ ] Environment detected (repo vs worktree vs detached HEAD)
  • [ ] Exact fixed menu presented, right count of options
  • [ ] Chosen option executed per the playbook
  • [ ] Discard confirmed by the user typing discard, if chosen
  • [ ] Worktree cleanup only for options 1 and 4, only owned worktrees
  • [ ] Branch deletion after worktree removal, never before

Any box unchecked: not done. Fix or say so.

Red flags

Verbatim excuses that precede destroyed work or broken main:

  • "Tests are probably flaky, I'll merge anyway"
  • "I'll clean up the worktree now to be tidy" (on option 2 or 3)
  • "They said discard in spirit, close enough" (no typed confirmation)
  • "I'll force-push to fix the history"
  • "This worktree looks stale, I'll remove it" (not under .worktrees/)

Closure rule: destructive actions (discard, worktree removal, branch force-delete) require the exact preconditions in the playbook, met literally, or they do not happen.

Footguns

  • Deleting the branch before the worktree. git branch -d fails because the worktree still references it. Fix: merge, remove worktree, then delete branch, in that order.
  • Running `git worktree remove` from inside the worktree. Fails or half-completes. Fix: cd to the main repo root first (git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel).
  • Cleaning harness-owned workspaces. Removing a worktree the platform created leaves phantom state it cannot recover from. Fix: provenance check, only .worktrees/ and worktrees/ paths are yours.
  • Merging without re-testing the merged result. The branch was green, main moved, the merge is red. Fix: run the suite on the merge commit before deleting anything.

Reference files

More in Delivery & Handoff

All skills