Skip to content
Agentmart
Submit a tool

worktree-merge-cleanup

On-demand home for the pre-merge worktree precondition and the unified post-merge cleanup sequence — how to run `gh pr merge --squash --delete-branch` from…

Skill by devseunggwan

IndexedMIT★ 1
Write a review

Chalk Labs

Need help deploying worktree-merge-cleanup?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/devseunggwan-worktree-merge-cleanup

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

On-demand home for the pre-merge worktree precondition and the unified post-merge cleanup sequence — how to run `gh pr merge --squash --delete-branch` from the base-branch worktree, the submodule `--force` caveat, the squash-ancestry stale-HEAD guard, and the no-`&&`-chain rule.

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/worktree-merge-cleanup

What's inside

Skill name
worktree-merge-cleanup
Description
On-demand home for the pre-merge worktree precondition and the unified post-merge cleanup sequence — how to run `gh pr merge --squash --delete-branch` from the base-branch worktree, the submodule `--force` caveat, the squash-ancestry stale-HEAD guard, and the no-`&&`-chain rule.
License
MIT
Instructions
356 lines in SKILL.md · view on GitHub

Agent Skills spec issues

  • body: contains an absolute path from the author's machine

Files (1)

  • SKILL.md

SKILL.md (first lines)

# worktree-merge-cleanup

## Overview

`gh pr merge --squash --delete-branch` does a local checkout of the base branch
(main / dev / prod) in the post-squash stage, and it deletes the local head
branch by reachability against the local base HEAD. Both facts make the command
sensitive to *which worktree* it runs from and *whether the base is synced* —
get either wrong and the merge fails at the git layer or silently skips the
local-branch delete, forcing manual recovery.

This skill is the on-demand home for that procedure. The always-loaded rule set
keeps only a pointer here; the deterministic `--delete-branch` failure mode is
additionally enforced structurally by the `gh-merge-worktree-precondition`
PreToolUse hook (see [Relationship to enforcement](#relationship-to-enforcement)).

**Core principle:** run the post-merge cleanup steps as *separate* Bash calls,
never collapsed into one `&&`-chain — a git hard error mid-sequence
short-circuits the chain and its trailing output is easily misread as success.

## When to Use

- About to merge a PR with `gh pr merge --squash --delete-branch` from an
  issue-branch worktree.
- The merge just failed with `fatal: '<base>' is already used by worktree at ...`
  or `cannot delete branch 'X' used by worktree at ...`.
- After a squash-merge the local feature branch was not deleted
  (`warning: deleting branch 'X' ... not yet merged to HEAD`).
- Cleaning up a worktree that contains a submodule.
- Removing the worktree and head branch of a PR the user closed without
  merging. The removal mechanics are the same as below (clean-check, submodule
  `--force` without `deinit`, explicit workdir afterwards, remote tip equals
  the PR's `headRefOid` before `push origin --delete`), but a post-merge
  standing approval does not cover it: list the worktree and branches and ask
  once. Load this skill before the first removal command even for a one-off
  closed PR — skipping it is how the shared-config `deinit` damage repeats.
- Cleaning up many stale worktrees across repos at once → follow
  `references/bulk-stale-worktree-cleanup.md` (inventory, classification order,
  squash-safe content oracle, regenerable-artifact list, checkpointed background run,
  and the stash/keep-branch pass for removing holds when the user asks for all).

## Pre-call checklist

`gh pr merge --squash --delete-branch` must be **called from the worktree that
owns the base branch**. Calling from an issue-branch worktree triggers the git
exclusive-ref guard:

```text
fatal: 'main' is already used by worktree at /Users/.../<main-worktree>
```

1. Confirm the worktree occupying the base branch with `git worktree list`.
2. **If `--delete-branch` is included**: remove the PR head branch's worktree
   first (`git worktree remove <issue-worktree-path>`). If the shell's working
   directory is that worktree, every later shell call fails at its implicit
   `cd` once the directory is gone — run the remove from (or with `-C`) the base
   worktree, and give every following call an explicit working directory
   (`workdir`, `git -C`, `--repo`) instead of retrying. On Hermes the
   terminal tool's persistent cwd is applied before your command runs, so a
   `cd <base> && …` inside the command still fails with `cd: <removed path>:
   No such file or directory` — set the tool's `workdir` parameter.
   Likewise, step 5's scratch deletion removes only files you created for
   this PR: list them with mtimes and leave older files other sessions wrote. The post-merge local
   branch delete fails if the branch is still occupied — `cannot delete branch
   'X' used by worktree at ...` — even when invoked from the base (main)
   worktree, because the failing branch is the *head*, not the base. After
   removal, re-run `git worktree list` to confirm.
   - ⚠️ **The worktree is the agent session's own working folder** (Hermes desktop freezes a chat's cwd at creation; check the runtime `Current working directory` / the turn's workdir): removing it kills the session — every later message fails with "working folder no longer exists" before any model call. Still remove it if the cleanup is approved, but say in the same report that this chat must be moved (desktop **Move to project**) to a live folder before the next message, and name the folder (base worktree or the next issue's worktree).
   - ⚠️ **Something live may still run from the worktree**: before removing it, check that no symlink points into it (an agent's plugin or skills directory linked to the worktree loads from it: `ls -la <load dir>`) and that no process has its cwd there (`lsof -d cwd 2>/dev/null | grep -F "<worktree path>"`, which also catches a subdirectory without the recursive walk of `+D`; `pgrep -fl <worktree path>` matches command lines only and misses a process that merely `cd`'d there). Stop or repoint those first and name them in the report.
   - ⚠️ **The `codex-review-wrap` companion leaves its app-server broker running with the reviewed worktree as cwd.** Find it (`lsof -a -p <pid> -d cwd` on the `app-server-broker.mjs serve --cwd <worktree>` process) and stop only that pid before removing the worktree — never a broad `pkill`.
   - ⚠️ **Submodule-containing worktree**: plain `git worktree remove` is
     rejected with `fatal: working trees containing submodules cannot be moved
     or removed`. Use `git worktree remove --force <path>` **only after
     confirming the worktree is clean** (`git -C <path> status --porcelain`
     empty, and no `!!` line from `--porcelain --ignored` other than a
     regenerable dependency or build cache — `remove` deletes ignored files too). `--force` destroys uncommitted changes in a dirty worktree, so
     never make it the default. Never run `git submodule deinit` in a linked worktree as a
     cleanup step: it does not lift the rejection (the check looks at the
     registered submodule, not its checkout), and it deletes
     `submodule.<name>.url` from the repository config that every worktree
     shares, so sibling worktrees lose their submodule registration. Go
     straight to the clean-check + `--force`. If a deinit already ran, restore
     the entry from the main checkout with `git submodule init <path>` and
     confirm with `git config --get submodule.<name>.url`.
3. `cd <base-worktree-path>` or chain `cd <path> && gh pr merge ...` in the same
   Bash call (avoid cwd-reset trap between Bash calls).
   - **Fork clones: pass `--repo <fork-owner>/<repo>` on every `gh pr` call,
     the merge included.** In a clone whose GitHub repo is a fork, gh
     resolves a bare `gh pr merge <N>` (and `view` / `comment` / `edit`)
     against the parent repo: it fails with `Could not resolve to a
     PullRequest` at best and acts on the upstream PR of the same number at
     worst.
4. Even if the call fails on a worktree conflict, the PR may already be merged
   on remote (gh order: remote merge → local sync). Manual cleanup — run each as
   a **separate** Bash call, never chained (a failure in one step must not
   short-circuit the rest): `git worktree remove <path>`, then
   `git branch -D <branch>`, then `git worktree prune` (snapshot and dry-run
   it first — see [prune is repository-wide](#prune-is-repository-wide--snapshot-before-running-it)),
   then `git pull origin <base>`.
5. **Squash-ancestry stale HEAD guard (post-merge sync mandatory)**: immediately
   after `gh pr merge --squash --delete-branch`, run `git pull origin
   <base-branch>` as a **separate step**. gh merges remote then deletes local
   branch by reachability against local HEAD — but does not fetch the local
   base, so if local base is still at pre-merge SHA the delete silently skips
   (`warning: deleting branch 'X' that has been merged to 'refs/remotes/origin/X',
   but not yet merged to HEAD`). Distinct from item 4's worktree case — only
   `git pull` fixes it, not `git worktree remove`.

## When the user merged out-of-band

A repository bot can also merge the PR once approval and checks are green, so your own `gh pr merge` prints `already merged` (exit 0). Treat that as an out-of-band merge: read `gh pr view <N> --json state,mergedAt,mergedBy,mergeCommit` and report who merged it. The user's approval to merge still covers the cleanup below.

When the user reports "merged" after merging themselves (a `/merge` PR-comment
slash command, the web UI), the cleanup below deletes things: the head
worktree, the local branch, scratch files, the remote head branch, and it may
post an issue close-out. A merge report is not an instruction to delete. Run
the whole sequence without asking only when the user's own instructions
(CLAUDE.md, AGENTS.md, or agent memory) record a standing approval for
post-merge cleanup. Without one, run the read-only checks (steps 1–2), then

From devseunggwan/praxis, MIT.

More from devseunggwan/praxis

Signals

Stars
1
Forks
0
Open issues
0
Last commit (this folder)
Oct 14, 2026 (16 days ago)
Last release
Oct 24, 2026 (6 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from devseunggwan

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get worktree-merge-cleanup running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying worktree-merge-cleanup?

CallGet help
Cite this page

worktree-merge-cleanup skill. Agent Mart. https://agentmart.dev/skills/devseunggwan-worktree-merge-cleanup (last updated 2026-10-24)