git-worktree-clean
Clean up stale git worktrees with merged branch detection and disk usage report
What this skill does
# 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.md) | [`/git-worktree`](./git-worktree.md) | [`/git-worktree-status`](./git-worktree-status.md) | [`/git-worktree-remove`](./git-worktree-remove.md)
## 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
| Flag | Effect |
|------|--------|
| `--dry-run` | Preview what would be cleaned, no changes |
| `--all` | Include unmerged worktrees (interactive confirmation each) |
| `--force` | Remove all worktrees without confirmation (dangerous) |
## Worktree Discovery
```bash
# 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
```bash
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
```bash
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
```bash
# --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.**
```bash
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:**
```bash
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
| Situation | Action |
|-----------|--------|
| Default (no flags) | Remove merged worktrees only |
| `--dry-run` | Preview without changes |
| `--all` | Merged (auto) + unmerged (interactive) |
| `--force` | Remove everything except protected |
| Protected branch | Always kept |
| Merged branch | Auto-removed |
| Unmerged branch | Kept (default) or interactive (--all) |
| DB branches detected | Reminder 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: $ARGUMENTSRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.