From git-workflow
Syncs local repository with remote, cleans up merged branches, and reports status
npx claudepluginhub zookanalytics/claude-devcontainer --plugin git-workflow# Claude Command: Git Cleanup Performs comprehensive git repository synchronization and cleanup while preserving local work. ## Usage ## Process This command performs a safe sync and cleanup of your git repository by: 1. **Pre-flight checks (parallel)** - Check uncommitted changes and stash simultaneously 2. **Fetching and pruning** - Syncs with remote and removes stale references 3. **Categorizing branches (parallel)** - Check each branch's merge status concurrently 4. **Cleaning up merged branches** - Removes local branches that were merged/deleted remotely 5. **Preserving new work...
/cleanupArchives accumulated phase directories from completed milestones into .planning/milestones/v{X.Y}-phases/, with dry-run summary and user confirmation.
/cleanupCleans up code and project structure by removing dead code, optimizing imports/files, with analysis, safe execution, validation, and summary report. Supports target path and --type, --safe, --interactive flags.
/cleanupDetects and safely removes dead code, unused imports/exports, unreachable branches, and dependencies in JS/TS, Python, Go, Rust. Outputs categorized findings with confidence; runs tests post-removal.
/cleanupCleans .a5c/runs and .a5c/processes: aggregates insights from old completed/failed runs into docs/run-history-insights.md and removes them plus orphans. Supports --dry-run and --keep-days N flags.
/cleanupRemoves temporary design lab files from .claude-design/ directory and Next.js/Vite preview routes after user confirmation. Reports deletions.
/cleanupDeletes all Lisa interview state files (.claude/lisa-*.md and lisa-draft.md) to reset plugin state. Lists files first, confirms deletion, skips completed specs.
Performs comprehensive git repository synchronization and cleanup while preserving local work.
/git:cleanup
This command performs a safe sync and cleanup of your git repository by:
Run these commands in parallel (no dependencies between them):
git status --porcelain # Check for uncommitted changes
git stash list # Check for stashed changes
After both complete:
git status --porcelain shows changes: STOP and notify user concisely
Sync with remote and remove stale remote-tracking branches:
git fetch --all --prune
What this does:
Find local branches whose remote counterparts are gone:
git branch -vv
Analysis:
[origin/...: gone]For each candidate branch with [origin/...: gone], determine if it's safe to delete.
Understanding merged PRs:
[origin/branch-name: gone]git branch --mergedgit merge-base --is-ancestor) don't work for squash mergesParallel categorization strategy:
# First, get shared context (run these in parallel):
git branch --show-current # Current branch (protected)
git branch --merged origin/main # All traditionally merged branches
# Then, for ALL candidate branches simultaneously, check GitHub PR status:
# Launch these in parallel - each is independent:
gh pr list --state merged --head BRANCH_1 --json number,title
gh pr list --state merged --head BRANCH_2 --json number,title
gh pr list --state merged --head BRANCH_3 --json number,title
# ... one call per candidate branch, ALL IN PARALLEL
# For branches with no merged PR, check unique commits (can also be parallel):
git rev-list origin/main..BRANCH_NAME --count
Why parallel: Each gh pr list call takes 1-2 seconds.
With 5 branches:
Categorization logic per branch:
gh pr list --state merged --head BRANCH returns a PR → safe to deletegit branch --merged origin/main → safe to deletegit rev-list origin/main..BRANCH --count:
0 = has unpushed work → preserve
Categories:
git branch --merged origin/main (traditional merge), ORDelete branches that are safe to remove:
# Use -d flag for safe deletion (will fail if truly unmerged)
git branch -d BRANCH_NAME
# If -d fails but we verified it's merged via PR:
# This WILL happen with squash/rebase merges
git branch -D BRANCH_NAME
Deletion strategy:
git branch -d first (may succeed for traditional merges)git branch -D (expected for squash/rebase merges)git branch --merged origin/main:
git branch -d (will succeed)git branch -d (will succeed, branch is empty)Rules:
[origin/...: gone] AND one of:
gh pr list), ORgit branch --merged origin/main, OR-D only when PR is confirmed merged but -d fails (squash/rebase case)Provide comprehensive status report:
If everything is clean:
✅ Repository is fully synced with remote
Summary:
- No uncommitted changes
- No stashed changes
- Deleted X merged branches: [list]
- All local branches are up to date
If local work exists:
⚠️ Repository synced with local work preserved
Summary:
- Uncommitted changes: [files list]
Action needed: Commit or stash these changes
- Stashed changes: X entries found
Reminder: You have stashed work that may need attention
Run 'git stash list' to review
- Deleted X merged branches: [list]
- Branches with unpushed work: [list]
These branches were kept because they have commits not yet pushed to remote
The Challenge: When you merge a PR on GitHub using "Squash and merge" or "Rebase and merge", GitHub:
[origin/branch-name: gone]git branch --merged won't show it as merged (different commit SHAs)git merge-base --is-ancestor returns false (branch not in main's history)The Solution: This command uses a three-tiered approach to safely identify merged branches:
GitHub PR Check (gh pr list --state merged --head BRANCH)
Traditional Merge Check (git branch --merged origin/main)
Unique Commit Count (git rev-list origin/main..BRANCH --count)
Why git ancestry checks don't work:
git merge-base --is-ancestor checks if commits are in the history treeResult: Branches from merged PRs are safely deleted even with GitHub's squash/rebase merge strategies by checking GitHub's PR state directly.
git merge-base --is-ancestor to confirm mergesConcise error reporting:
Checking for uncommitted changes...
✓ Working tree is clean
Checking stash...
✓ Found 2 stashed entries
Fetching from remote and pruning stale references...
✓ Synced with origin
✓ Pruned 5 stale remote-tracking branches
Analyzing local branches...
Found 4 branches with deleted remotes:
- feat/user-auth [gone] - checking merge status...
✓ Found merged PR #45 on GitHub (squash merged)
- fix/login-bug [gone] - checking merge status...
✓ Found in git merged branches (traditional merge)
- docs/update-readme [gone] - checking merge status...
✓ No unique commits (empty branch)
- feat/new-feature [gone] - checking merge status...
⚠️ No merged PR found, has 3 unique commits (preserving)
Cleaning up merged branches...
✓ Deleted feat/user-auth (merged PR #45)
✓ Deleted fix/login-bug (traditional merge)
✓ Deleted docs/update-readme (no unique commits)
✅ Repository cleanup complete
Summary:
- Deleted 3 merged branches
- Kept 1 branch with unpushed work: feat/new-feature (3 unique commits)
- Current branch 'main' is up to date with origin/main
- Stashed changes: 2 entries (run 'git stash list' to review)