From git
Runs a multi-phase cleanup pipeline across all worktrees and branches: removes stale worktrees, rebases branches, retests, and pushes. Gates destructive actions and avoids --force.
How this skill is triggered — by the user, by Claude, or both
Slash command
/git:wipThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Drive a repo full of leftover worktrees and half-finished branches toward a clean, landed state.
Drive a repo full of leftover worktrees and half-finished branches toward a clean, landed state. The pipeline has four phases that run in order, each gated:
j g / git-all), deleting
branches that have merged.These four phases are the bulk-cleanup core of a longer idea → merged-PR lifecycle (the later stages — open PR, CI, review, merge — are the user's call). If the repo or user documents a WIP state model, follow it for those later stages.
--force. Worktree removal uses git worktree remove --no-force (write the flag
explicitly); pushes use git push --force-with-lease. Git's refusal to act is the safety
net that protects uncommitted work and unexpected remote changes — don't defeat it.git worktree list --porcelain / git for-each-ref immediately before each
action — never trust a snapshot from a minute ago. Re-git fetch before testing and pushing.delete-merged (which deletes remote branches) are hard to undo. Surface them and get the
user's OK rather than charging ahead. Until the flow is proven smooth in a given repo, prefer
asking at each phase boundary.git worktree add), then tear it down.The main worktree is auto-detected — it is the first entry of git worktree list --porcelain
(equivalently, the one whose gitdir is git rev-parse --git-common-dir). Never remove it.
Protected worktrees (permanent ones to never remove) are listed per-repo in .llm/wip.json:
{"protectedWorktrees": ["/Users/you/projects/some-permanent-worktree"]}
Read this file at the start of Phase 1. If it's missing, treat the protected set as empty (only
the main worktree is kept) — but if there's any long-lived worktree you're unsure about, ask
rather than remove it. (Alternative native mechanism: git worktree lock makes git refuse to
remove a worktree without --force, which our never-force rule respects automatically.)
Goal: every non-main, non-protected worktree removed, so its branch is free to rebase.
.llm/wip.json for protectedWorktrees. Detect the main worktree (first porcelain entry).git worktree list --porcelain minus main minus protected. Use
plain git worktree list — never a user shell alias like git worktrees, which won't exist
elsewhere.git:clean-worktrees
skill (which runs git worktree remove --no-force <dir> and lets git refuse unsafe removals):
git -C <main> worktree remove --no-force <dir>.--force. A dirty worktree fails with
fatal: '<dir>' contains modified or untracked files, use --force to delete it (exit 128).
That's the safety net working. When it happens, look at what's there
(git -C <dir> status --short) and ask the user how to handle it: commit the WIP (single
line, via git:commit-handler), stash it, or leave the worktree in place.git -C <main> worktree prune --verbose.The one-shot is the git-all script — rebase-all → git worktree prune → delete-merged
(the user may alias it, e.g. j g). Prefer it over bare rebase-all so merged branches get
cleaned up. It needs the upstream configured (UPSTREAM_REMOTE, default upstream; many repos use
origin — check git remote -v and the project's .envrc). The origin/main written in the
examples below and in references/pipeline.md stands for whichever upstream you configured;
substitute $UPSTREAM_REMOTE/main when it isn't origin, or every rebase and "all clean" check
runs against a stale base and silently reports success.
dev, main4, experiment, and pr*-fix branches). Count them and
let the user confirm scope before a big batch.git-all halts on the first conflict, leaving an in-progress rebase. Hand genuine
conflicts to the git:conflict-resolver agent. git rerere auto-replays the user's prior
resolutions — verify them, don't blindly trust. (Beware false-positive conflict-marker greps in
files that legitimately contain =======, e.g. ASCII banners or markdown headings.)delete-merged is outward-facing — it also git push --delete origin <branch> for merged
remote branches (excluding main/HEAD/origin/pr/*). Gate it.See references/pipeline.md for the co-pointed-branch fallback (the most important edge case:
when several branch names point at the same commit, rebase-all skips them all and they never
rebase — you must rebase the leftovers directly), and the recommended worktree-per-branch parallel
rebase pattern.
After this phase, git for-each-ref refs/heads/ --no-contains origin/main should be empty.
Rebasing invalidates prior test results (the rebase ⋈ test diamond: a rebased branch must be
re-tested before it's trustworthy). Re-git fetch first — upstream may have moved.
Run build:test-all (per branch: git test run <FLAGS> origin/main..BRANCH) in a
dedicated worktree — git-test checks out each commit, which would disrupt the main checkout.
See references/pipeline.md for the worktree+env setup and the flaky-retest rule (force-retest
a single transient failure like Connection reset before reporting it as a real failure).
Record each branch's current remote sha (git rev-parse refs/remotes/origin/<branch>) before
re-git fetching, then push every branch ahead of upstream/main:
refs/remotes/origin/<branch> exists:
git push --force-with-lease=<branch>:<recorded-sha> origin <branch>:<branch> (updates the open
PR). Pin the sha explicitly — a bare --force-with-lease baselines on the remote-tracking ref,
which the re-fetch just advanced to match the remote, so it would clobber a teammate's new commit
instead of refusing. The pinned lease refuses if anyone pushed since you recorded the sha.git push origin <branch>:<branch> to create the remote branch.Do not open or merge PRs unless asked — landing is the user's call. git push is commonly in
the harness "ask" list, so expect per-push permission prompts.
Mechanical and safe to automate: detecting main, reading the protected list, computing sets live,
worktree remove --no-force, worktree prune, clean rebases, tests, --force-with-lease pushes
of branches the user has scoped.
Judgment calls — ask: what to do with a dirty worktree; whether to remove a brand-new one;
scope of a big rebase/push batch; how to resolve a genuine conflict; and any outward
step (delete-merged, force-push, merge).
npx claudepluginhub motlin/claude-code-plugins --plugin gitCreates isolated git worktrees for branch work, auto-installs dependencies, verifies baselines, and handles branch finishing with clean isolation.
Automates git workflow: creates isolated worktrees for features with .gitignore safety checks, enables atomic commits, completes branches via merge, PR, preserve, or discard.