Skip to content
cccskills
FreePublished on GitHub

git-worktree-clean

Clean up Git worktrees, separate working folders for branches, by identifying merged branches and reviewing unmerged ones. Preview deletions, preserve protected branches, and receive a report of removed folders and reclaimed disk space.

OriginalShow the original description

Clean up stale git worktrees with merged branch detection and disk usage report

See how to install

Good for

  • Clean up worktrees after merging branches
  • Preview deletions and potential disk savings
  • Review unmerged worktrees individually
  • Check reminders for database branch cleanup

Files included (1)

  • SKILL.md6.3 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Git worktree clean

Batch cleanup of stale git worktrees. Safely removes merged branches, reports disk usage, and handles unmerged branches interactively.

Core principle: Auto-clean merged worktrees, interactive review for unmerged, always report what was reclaimed.

Part of: Worktree Lifecycle Suite | /git-worktree | /git-worktree-status | /git-worktree-remove

Process

  1. List All Worktrees: git worktree list
  2. Classify Each: merged vs unmerged vs protected
  3. Calculate Disk Usage: Per-worktree size
  4. Auto Mode: Remove all merged worktrees (safe)
  5. Interactive Mode: Review unmerged worktrees one by one
  6. Database Cleanup Reminder: List DB branches to clean
  7. Report: Summary of actions taken and space reclaimed

Flags

FlagEffect
--dry-runPreview what would be cleaned, no changes
--allInclude unmerged worktrees (interactive confirmation each)
--forceRemove all worktrees without confirmation (dangerous)

Worktree discovery

# Get main branch name
MAIN_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')
MAIN_BRANCH=${MAIN_BRANCH:-main}

# Protected branches (never auto-clean)
PROTECTED="main master develop staging production"

# List all worktrees (skip main working tree)
git worktree list --porcelain | while read line; do
  # Parse worktree path and branch
  # Skip the main worktree (first entry)
done

Classification

for WORKTREE in $WORKTREES; do
  BRANCH=$(git -C "$WORKTREE" rev-parse --abbrev-ref HEAD)

  # Skip protected
  if echo "$PROTECTED" | grep -qw "$BRANCH"; then
    echo "PROTECTED: $BRANCH (skipped)"
    continue
  fi

  # Check merge status
  if git merge-base --is-ancestor "$BRANCH" "$MAIN_BRANCH" 2>/dev/null; then
    echo "MERGED: $BRANCH → safe to remove"
    MERGED_LIST="$MERGED_LIST $WORKTREE"
  else
    echo "UNMERGED: $BRANCH → requires review"
    UNMERGED_LIST="$UNMERGED_LIST $WORKTREE"
  fi
done

Disk usage calculation

for WORKTREE in $ALL_WORKTREES; do
  # Calculate size excluding symlinked node_modules
  SIZE=$(du -sh --exclude='node_modules' "$WORKTREE" 2>/dev/null | cut -f1)
  # Or on macOS:
  SIZE=$(du -sh -I 'node_modules' "$WORKTREE" 2>/dev/null | cut -f1)
  echo "  $WORKTREE: $SIZE"
done

Dry run mode

# --dry-run: show what would happen without making changes

echo "=== Dry Run ==="
echo ""
echo "Would remove (merged):"
for WT in $MERGED_LIST; do
  echo "  $WT ($BRANCH) - $SIZE"
done
echo ""
echo "Would ask about (unmerged):"
for WT in $UNMERGED_LIST; do
  echo "  $WT ($BRANCH) - $SIZE - last commit: $(git log -1 --format='%s' $BRANCH)"
done
echo ""
echo "Total space to reclaim: $TOTAL_SIZE"
echo ""
echo "Run without --dry-run to execute."

Auto mode (default)

Only removes merged worktrees. Safe by default.

echo "Cleaning merged worktrees..."

for WORKTREE in $MERGED_LIST; do
  BRANCH=$(git -C "$WORKTREE" rev-parse --abbrev-ref HEAD)

  # Remove worktree
  git worktree remove "$WORKTREE"

  # Delete local branch
  git branch -d "$BRANCH" 2>/dev/null

  # Delete remote branch
  git push origin --delete "$BRANCH" 2>/dev/null

  echo "  Removed: $WORKTREE ($BRANCH)"
done

# Report unmerged (not touched)
if [ -n "$UNMERGED_LIST" ]; then
  echo ""
  echo "Unmerged worktrees (kept):"
  for WT in $UNMERGED_LIST; do
    echo "  $WT - use /git-worktree-remove or --all to review"
  done
fi

Interactive Mode (--all)

Reviews unmerged worktrees one by one:

for WORKTREE in $UNMERGED_LIST; do
  BRANCH=$(git -C "$WORKTREE" rev-parse --abbrev-ref HEAD)
  LAST_COMMIT=$(git log -1 --format='%h %s (%cr)' "$BRANCH")
  AHEAD=$(git rev-list --count "$MAIN_BRANCH".."$BRANCH")

  echo ""
  echo "Unmerged: $WORKTREE"
  echo "  Branch: $BRANCH ($AHEAD commits ahead of $MAIN_BRANCH)"
  echo "  Last commit: $LAST_COMMIT"
  echo "  Size: $SIZE"
  echo ""
  echo "  [r]emove  [k]eep  [s]kip remaining"

  # Wait for user decision per worktree
done

Report format

After cleanup:

=== Worktree Cleanup Report ===

Removed (merged):
  .worktrees/feat/auth (feat/auth) - 2.3 MB
  .worktrees/fix/login-bug (fix/login-bug) - 1.1 MB
  .worktrees/chore/deps-update (chore/deps-update) - 0.8 MB

Kept (unmerged):
  .worktrees/feat/experimental (feat/experimental) - 4.2 MB
    Last commit: a1b2c3d "WIP: new auth flow" (3 days ago)

Kept (protected):
  .worktrees/develop (develop)

Space reclaimed: 4.2 MB
Worktrees remaining: 2
References pruned: yes

DB branches to clean:
  neonctl branches delete feat-auth
  neonctl branches delete fix-login-bug
  neonctl branches delete chore-deps-update

Dry run report:

=== Dry Run - No Changes Made ===

Would remove (3 merged):
  .worktrees/feat/auth - 2.3 MB
  .worktrees/fix/login-bug - 1.1 MB
  .worktrees/chore/deps-update - 0.8 MB

Would keep (1 unmerged):
  .worktrees/feat/experimental - 4.2 MB

Would keep (1 protected):
  .worktrees/develop

Potential space savings: 4.2 MB

Quick reference

SituationAction
Default (no flags)Remove merged worktrees only
--dry-runPreview without changes
--allMerged (auto) + unmerged (interactive)
--forceRemove everything except protected
Protected branchAlways kept
Merged branchAuto-removed
Unmerged branchKept (default) or interactive (--all)
DB branches detectedReminder with exact commands

Common mistakes

Running --force without --dry-run first

  • Always preview with --dry-run before force-cleaning

Forgetting DB branch cleanup

  • Worktree cleanup doesn't auto-delete DB branches. Follow the reminder commands.

Not running cleanup regularly

  • Stale worktrees accumulate disk space. Run /git-worktree-clean --dry-run weekly.

Usage

/git-worktree-clean
/git-worktree-clean --dry-run
/git-worktree-clean --all

Flags: $ARGUMENTS

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Evaluate Claude Code agents, skills, and commands with weighted quality criteria. Get scores, readiness grades, template comparisons, and practical improvement suggestions in Markdown or JSON reports to guide reviews before release.

  • Review skills before release
  • Compare agent definitions with reference templates
  • Quickly check critical quality criteria
FlorianBruniaux/claude-code-ultimate-guide6.2KUpdated Oct 18, 2026

audit-codebase

FreeSummary

Assess a codebase across seven areas, including exposed credentials, security, dependencies, structure, and tests. Receive category scores, findings tied to file locations, and a prioritized improvement plan with smaller tasks that can be completed quickly.

  • Assessing the overall health of an inherited project
  • Reviewing exposed credentials and security risks
  • Identifying dependency and test coverage gaps
FlorianBruniaux/claude-code-ultimate-guide6.2KUpdated Oct 18, 2026

autoresearch

FreeSummary

Measure code patterns such as casts to any or disabled lint rules, then run repeated, targeted edits. Keep changes that improve the chosen metric, revert unsuccessful changes, and track results for each improvement loop.

  • Finding code patterns to prioritize for cleanup
  • Preparing measurement files for an improvement loop
  • Repeating targeted edits to reduce casts to any
FlorianBruniaux/claude-code-ultimate-guide6.2KUpdated Oct 18, 2026

best-of-n

FreeSummary

Generate several separate solutions, compare them against criteria fixed in advance, and verify the selected result through executable checks or an independent reviewer. Keep a proof log documenting candidates, evidence, failures, and remaining limits.

  • Comparing implementation options before choosing one
  • Verifying a solution when a wrong choice would be costly
  • Keeping evaluation evidence for delivery or audit
FlorianBruniaux/claude-code-ultimate-guide6.2KUpdated Oct 18, 2026

canary

FreeSummary

Monitor a live application after deployment and compare it with a saved baseline, a record of its earlier state. Check page responses, loading times, and new errors, flag persistent changes, and produce a per-page health report.

  • Recording a healthy baseline before deployment
  • Monitoring production immediately after deployment
  • Checking key pages for slower responses or failures
FlorianBruniaux/claude-code-ultimate-guide6.2KUpdated Oct 18, 2026

catchup

FreeSummary

Rebuild project context after clearing a conversation or returning to work. Review recent Git history, uncommitted changes, and TODO markers to get a structured summary of project status and suggested next steps.

  • Restoring project context after /clear
  • Reviewing recent changes after a long break
  • Checking unfinished work before choosing the next task
FlorianBruniaux/claude-code-ultimate-guide6.2KUpdated Oct 18, 2026

See all skills by FlorianBruniaux

Report a problem with this skill