Skip to main content
command

worktree-cleanup — Claude Code command for cleaning worktrees

Finds merged worktrees and related branches, displays their status, and removes selected ones. Use it to tidy up after finished tasks.

Install into Claude Code · claude-code-templates All methods and platforms ↓
npx claude-code-templates@latest --command git-workflow/worktree-cleanup
Open on GitHub

What worktree-cleanup does

The command checks that it is running from the main working tree, fetches branch updates with git fetch origin --prune, and identifies the main branch. It then looks for worktrees and local or remote branches prefixed with claude/, claude-daniel/, or review/, checking whether they have merged into the main branch. A diff check also helps identify squash-merged branches.

Before removing anything, it displays a table with merge status and whether each worktree has uncommitted changes. Use --dry-run to preview, --all to select merged branches, or --branch to target one branch. A dirty worktree is skipped rather than force-removed. The command requires a Git repository with origin configured and should run from the main working tree.

What it helps with

  • locate worktrees tied to merged branches
  • check local and remote branch status before removal
  • preview the worktrees selected for cleanup
  • remove finished worktrees and their branches
  • spot squash-merged branches by comparing diffs

Example prompts for the agent

  • Preview eligible worktrees without removing anything: /worktree-cleanup --dry-run.
  • Remove all merged worktrees and related branches: /worktree-cleanup --all.
  • Check and clean up the worktree for claude/my-task: /worktree-cleanup --branch claude/my-task.

How to install worktree-cleanup

1claude-code-templates

npx claude-code-templates@latest --command git-workflow/worktree-cleanup

2Manually: put the files in place

.claude/commands/worktree-cleanup.md

Call it with /worktree-cleanup. For all projects use ~/.claude/commands/

Questions about worktree-cleanup

How do I install worktree-cleanup in Claude Code?

Run npx claude-code-templates@latest --command git-workflow/worktree-cleanup. The command file is at .claude/commands/worktree-cleanup.md.

What does worktree-cleanup do?

It checks worktrees and branches prefixed with claude/, claude-daniel/, or review/, then helps remove merged ones. It displays their status first and skips dirty worktrees.

Can I preview what will be removed?

Yes. Run /worktree-cleanup --dry-run to display the cleanup table without making changes.

Source text

worktree-cleanup.md · MIT
---
allowed-tools: Bash(git:*), Bash(rm:*), Bash(ls:*), Bash(pwd:*), Bash(grep:*)
argument-hint: --all | --branch claude/name | --dry-run
description: Clean up merged worktrees and their branches
---

# Worktree Cleanup

Remove worktrees and branches that have been merged: $ARGUMENTS

## Instructions

You are in the **main repository** (not a worktree). Clean up finished worktrees.

### Branch Patterns

This project uses the following branch prefixes for worktrees:
- `claude/*` — Claude Code auto-created worktrees
- `claude-daniel/*` — User-created worktrees
- `review/*` — Component review worktrees

All three prefixes must be checked in every step below.

### Step 1: Validate Environment

1. Verify this is the main working tree (first entry in `git worktree list`)
2. If inside a worktree, warn: "Run `/worktree-cleanup` from the main repo, not from a worktree."
3. Fetch latest from origin: `git fetch origin --prune`
4. Get the main branch name (main or master)

### Step 2: Parse Arguments

Parse `$ARGUMENTS` for options:

- `--all` — clean up ALL merged worktrees and branches
- `--branch <prefix>/<name>` — clean up a specific worktree/branch
- `--dry-run` — show what would be cleaned up without doing anything
- `--force-all` — remove ALL worktrees regardless of merge status (asks confirmation per worktree)
- No arguments — list worktrees and ask which to clean up

### Step 3: Identify Worktrees

1. List all worktrees: `git worktree list`
2. List all matching branches:
   ```bash
   git branch --list 'claude/*' 'claude-daniel/*' 'review/*'
   ```
3. For each matching branch, check if it's been merged into main:
   ```bash
   git branch --merged origin/<main-branch> | grep -E '^\s+(claude/|claude-daniel/|review/)'
   ```
4. Also check remote branches:
   ```bash
   git branch -r --merged origin/<main-branch> | grep -E 'origin/(claude/|claude-daniel/|review/)'
   ```
5. For squash-merged branches (not detected by `--merged`), check if the branch diff is empty against main:
   ```bash
   # A branch is effectively merged if its changes already exist in main
   git diff origin/main...<branch> --stat
   ```
   If the diff is empty or very small (only whitespace), consider it merged.

### Step 4: Display Status

Show a table of all worktrees/branches:

```
| # | Worktree | Branch | Merged? | Dirty? | Action |
|---|---------|--------|---------|--------|--------|
| 1 | eager-mendeleev | claude/eager-mendeleev | Yes | Clean | Will remove |
| 2 | agent-a7e312d0 | review/code-reviewer-2026-04-01 | No | Clean | Skipped |
```

### Step 5: Confirm and Execute

If `--dry-run` was specified, show the table and stop.

Otherwise, use AskUserQuestion to confirm cleanup (unless `--all` was specified with only merged branches).

For each worktree/branch to clean up:

1. Remove the worktree:
   ```bash
   git worktree remove <path>
   ```
   If that fails (dirty worktree), warn and skip — **never force-remove**.

2. Delete the local branch:
   ```bash
   git branch -d <branch>
   ```
   Use `-d` (not `-D`) for merged branches. For `--force-all` unmerged branches, use `-D` only after explicit user confirmation.

3. Delete the remote branch (if it exists):
   ```bash
   git push origin --delete <branch>
   ```
   If the remote branch doesn't exist, ignore the error silently.

### Step 6: Prune

After all removals:

```bash
git worktree prune
```

### Step 7: Summary

Show what was cleaned up:

```
Cleanup Complete
──────────────────────────────────
Removed:  <N> worktree(s)
Deleted:  <N> local branch(es)
Deleted:  <N> remote branch(es)
Skipped:  <N> unmerged branch(es)
──────────────────────────────────
```

If any unmerged branches were skipped, list them and suggest:
- Merge the PR first, then run cleanup again
- Or use `git worktree remove <path>` and `git branch -D <branch>` manually if the work is truly abandoned

© davila7 · MIT · davila7/claude-code-templates

Similar slash commands

All slash commands for Git and GitHub →

From the same set804

The whole set →

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor