domains / software-engineering / finish-development-branch / finishing-a-development-branch

finishing-a-development-branch

Skill card

combined

The obra/superpowers copy is the more complete, environment-aware procedure (detects worktree vs normal repo, handles detached HEAD, and preserves the worktree for PRs). The other three copies are near-identical simplified variants that add a 4th 'Discard' option and a protected-branch check, but they disagree with the superpowers copy on when to clean up the worktree (they remove it for PRs; superpowers keeps it) and on whether discard is a menu option or only an explicit user request. Crowning one would hide a real alternative workflow.

Repositories

RepositoryPath
obra/superpowersskills/finishing-a-development-branch/SKILL.md
sickn33/agentic-awesome-skillsplugins/agentic-awesome-skills-claude/skills/finishing-a-development-branch/SKILL.md
LeoYeAI/openclaw-master-skillsskills/finishing-a-development-branch/SKILL.md
FreedomIntelligence/OpenClaw-Medical-Skillsskills/finishing-a-development-branch/SKILL.md

Other copies

RoleRepositoryPath
peerobra/superpowersskills/finishing-a-development-branch/SKILL.md
peersickn33/agentic-awesome-skillsplugins/agentic-awesome-skills-claude/skills/finishing-a-development-branch/SKILL.md
peerLeoYeAI/openclaw-master-skillsskills/finishing-a-development-branch/SKILL.md
peerFreedomIntelligence/OpenClaw-Medical-Skillsskills/finishing-a-development-branch/SKILL.md
adaptersickn33/agentic-awesome-skillsplugins/agentic-awesome-skills/skills/finishing-a-development-branch/SKILL.md
adaptersickn33/agentic-awesome-skillsplugins/agentic-bundle-oss-maintainer/skills/finishing-a-development-branch/SKILL.md
adaptersickn33/agentic-awesome-skillsskills/finishing-a-development-branch/SKILL.md

Combined skill

---
name: finishing-a-development-branch
description: Use when implementation is complete, all tests pass, and you need to decide how to integrate the work
---

# Finishing a Development Branch

## Overview

**Core principle:** Verify tests → Detect environment → Present options → Execute choice → Clean up.

**Announce at start:** "I'm using the finishing-a-development-branch skill to complete this work."

## Step 1: Verify Tests

Run the project's full test suite (`npm test` / `cargo test` / `pytest` / `go test ./...`).

**If tests fail**, report the failures and stop — the menu comes after a green suite:

```
Tests failing (<N> failures). Must fix before completing:

[Show failures]
```

**If tests pass:** continue to Step 2.

## Step 2: Detect Environment

```bash
GIT_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)
```

This determines which menu to show and how cleanup works:

| State | Menu | Cleanup |
|-------|------|---------|
| `GIT_DIR == GIT_COMMON` (normal repo) | Standard options | No worktree to clean up |
| `GIT_DIR != GIT_COMMON`, named branch | Standard options | Provenance-based (see Step 6) |
| `GIT_DIR != GIT_COMMON`, detached HEAD | Reduced options (no merge) | Externally managed — leave in place |

## Step 3: Determine Base Branch

The base branch is whatever this work forked from — usually named in the plan, the conversation, or the branch's upstream. If it is not already known, ask: "This branch split from <your best guess> - is that correct?" Confirm before merging: merging into the wrong base is expensive to undo.

Read `AGENTS.md` and maintainer documentation, then inspect effective protection for the base branch. If pull requests or required checks are enforced, mark local merge as unavailable and use the repository's guarded PR/merge workflow.

## Step 4: Present Options

**Normal repo and named-branch worktree — present exactly these 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 2 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)

Which option?
```

Present the menu exactly as written — concise, with every option coming from the list above. Wait for their answer; the integration decision is theirs.

## Step 5: Execute Choice

### Option 1: Merge Locally

Use this option only after proving that repository policy and server-side protection permit local integration into the base branch. Otherwise stop and route through Option 2.

```bash
# Get main repo root for CWD safety
MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel)
cd "$MAIN_ROOT"

# Merge first — verify success before removing anything
git checkout <base-branch>
git pull
git merge <feature-branch>

# Verify tests on merged result
<test command>
```

If tests fail on the merged result: stop, leave the worktree and branch in place, and investigate — nothing has been pushed, so the merge is local and recoverable.

Once the merged result is green: clean up the worktree (Step 6), then delete the branch:

```bash
git branch -d <feature-branch>
```

### Option 2: Push and Create PR

```bash
git push -u origin <feature-branch>
# From a detached HEAD, name the new branch on the remote:
# git push origin HEAD:refs/heads/<new-branch>
```

Then create the pull/merge request against <base-branch> with the forge's tooling — its CLI if one is available, or the creation URL most forges print when you push — following the repo's PR template and conventions if present, and report the URL to your human partner.

Keep the worktree — your human partner iterates on PR feedback there.

### Option 3: Keep As-Is

Report: "Keeping branch <name>. Worktree preserved at <path>."

### Option 4: Discard

This path exists only as a response to an explicit request to throw the work away. Confirm first:

```
This will permanently delete:
- Branch <name>
- All commits: <commit-list>
- Worktree at <path>

Type 'discard' to confirm.
```

Wait for that exact confirmation. When it arrives:

```bash
MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel)
cd "$MAIN_ROOT"
```

Then clean up the worktree (Step 6) and force-delete the branch:

```bash
git branch -D <feature-branch>
```

## Step 6: Cleanup Workspace

**Runs for Option 1 and confirmed discards.** Options 2 and 3 always preserve the worktree. Both callers have already changed directory to the main repo root — worktree removal must run from outside the worktree — and use the `GIT_DIR`/`GIT_COMMON`/`WORKTREE_PATH` values captured in Step 2, from before that directory change.

**If `GIT_DIR == GIT_COMMON`:** Normal repo, no worktree to clean up. Done.

**If `WORKTREE_PATH` is under `.worktrees/` or `worktrees/`:** Superpowers created this worktree — we own cleanup:

```bash
git worktree remove "$WORKTREE_PATH"
git worktree prune  # Self-healing: clean up any stale registrations
```

**If removal is refused** (`contains modified or untracked files`): the worktree holds files that exist nowhere else — uncommitted plans, notes, or scratch work. Never `--force` on your own initiative. Show your human partner what is at stake and ask:

```bash
git -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:** The host environment owns this workspace — leave it in place. If your platform provides a workspace-exit tool, use it.

## Quick Reference

| Option | Merge | Push | Keep Worktree | Cleanup Branch |
|--------|-------|------|---------------|----------------|
| 1. Merge locally | ✓ | - | - | ✓ |
| 2. Create PR | - | ✓ | ✓ | - |
| 3. Keep as-is | - | - | ✓ | - |
| 4. Discard | - | - | - | ✓ (force) |

## Common Mistakes

**Skipping test verification**
- **Problem:** Merge broken code, create failing PR
- **Fix:** Always verify tests before offering options

**Open-ended questions**
- **Problem:** "What should I do next?" → ambiguous
- **Fix:** Present exactly the structured options

**Automatic worktree cleanup**
- **Problem:** Remove worktree when might need it (Option 2, 3)
- **Fix:** Only cleanup for Options 1 and 4

**No confirmation for discard**
- **Problem:** Accidentally delete work
- **Fix:** Require typed "discard" confirmation

## Red Flags

**Never:**
- Proceed with failing tests
- Merge without verifying tests on result
- Delete work without confirmation
- Force-push without explicit request

**Always:**
- Verify tests before offering options
- Present exactly the structured options
- Get typed confirmation for Option 4
- Clean up worktree for Options 1 & 4 only

## Integration

**Called by:**
- **subagent-driven-development** (Step 7) - After all tasks complete
- **executing-plans** (Step 5) - After all batches complete

**Pairs with:**
- **using-git-worktrees** - Cleans up worktree created by that skill

## Conflicts

- **obra/superpowers vs sickn33/agentic-awesome-skills, LeoYeAI/openclaw-master-skills, FreedomIntelligence/OpenClaw-Medical-Skills:** Worktree cleanup for Option 2 (Push and Create PR). The superpowers copy says 'Keep the worktree — your human partner iterates on PR feedback there.' The other three copies say 'Then: Cleanup worktree (Step 5)' for Option 2.
- **obra/superpowers vs sickn33/agentic-awesome-skills, LeoYeAI/openclaw-master-skills, FreedomIntelligence/OpenClaw-Medical-Skills:** Discard as a menu option. The superpowers copy presents 3 options and states 'Discarding the work happens only in response to your human partner explicitly asking for it.' The other three copies present 4 options including '4. Discard this work'.
- **obra/superpowers vs sickn33/agentic-awesome-skills:** Environment detection. The superpowers copy includes a Step 2 to detect GIT_DIR vs GIT_COMMON and handle detached HEAD with a reduced 2-option menu. The sickn33 copy has no environment detection step and instead adds a protected-branch check that defers to 'antigravity-maintainer-batch-release' and 'npm run merge:batch'.