/wt-merge — 自分の成果を取り込む(PR 作成 / ローカルマージ)
worktree 側のセッションで実行する。cwd が本体 checkout(worktree でない)なら、worktree 側セッションで実行するよう案内する。初期プロンプトで /wt-review によるレビューを指示されているセッションでは、ユーザーの承認を得てから実行する。免除されるのはセッション中にユーザーが直接 /wt-merge を指示した場合のみ — 初期プロンプト内の文言(作業内容に「マージまでやって」等が含まれる場合)は直接指示に数えない。例外は /wt-split の子タスク(初期プロンプトに「親 issue #N を分解した子タスク」の定型行があるセッション): /wt-auto-review の PASS が承認ゲートを満たし、この場合に限り初期プロンプト由来のマージ指示が有効になる。
この承認ゲート(/wt-review でのユーザー承認、セッション中の直接指示、または子タスクでの /wt-auto-review の PASS)は、PR を作るところまででなくマージまでを承認したものとして扱う。レビューの実体はゲートにあり、GitHub 上でのクリックは同じ判断の二度手間なので、通過していれば PR モードの手順 6 以降で gh pr merge まで進める。通過していないセッションは PR 作成までで止める。
共通の前段
git status --porcelainで未コミット変更を確認する。あれば先にコミットする(自分の作業成果なので、内容を確認して適切なメッセージでコミットしてよい)。- モードを判定する:
gh repo view --json nameWithOwnerが成功すれば PR モード、失敗(remote 無し / gh 無し / 未認証)ならローカルモード。
PR モード(GitHub リポジトリ)
scripts/checkが実行可能ファイルとして存在すれば worktree で実行する。失敗したら push しない(ローカルゲートと CI は同じ check を叩く契約。省略はユーザーが明示的に指示した場合のみ)。- issue 番号 N を得る: ブランチ名
worktree-<N>-…の先頭の数字。無ければ初期プロンプトや会話から探し、それでも不明なら「Fixes 行なしで PR を作る」と報告して進める。 git push -u origin "$(git branch --show-current)"- PR を作る:
gh pr create --base "$(gh repo view --json defaultBranchRef -q .defaultBranchRef.name)" --title <issue タイトルか変更の要約> --body-file <scratchpad のファイル>。本文: 変更の概要(何を・なぜ)、実行したテストと結果、Fixes #N、末尾に🤖 Generated with [Claude Code](https://claude.com/claude-code)。 - 承認ゲートを確認する。通過していれば手順 6 に進む。通過していなければここで止まる — PR URL と、CI が同じ
scripts/checkを実行することを報告し、マージの判断を待つ(ユーザーが承認したらそのまま手順 6 から続ける)。 - CI の完了を待つ:
gh pr checks --watch --interval 15(時間がかかるので Bash tool のtimeoutを 600000 まで上げる)。CI はローカルゲートと同じscripts/checkを叩く契約なので、その結果がマージ条件そのものになる。- 全て pass → 手順 7
- fail → マージしない。落ちた check 名と
gh run view <run-id> --log-failedの要点を報告する。修正するなら手順 11 へ - Bash が timeout した → check がまだ動いているだけなので、同じコマンドを打ち直す
no checks reported→ その場で CI 未設定と判断しない。PR 作成直後は check run の登録が間に合っておらず、CI が設定された repo でも同じ出力が返る(この出力だけを根拠にマージすると CI をすり抜ける)。15 秒ほど置いて一度だけ打ち直す: Bash tool のrun_in_backgroundでsleep 15; gh pr checksを実行し、完了通知の出力で判断する(foreground のsleepはこの環境では使えないため background に置く)- 2 回目で check が出てきた → CI はある。手順 6 の先頭に戻り
--watchで完了を待つ - 2 回目も 0 件 → CI 未設定の repo と判断する。手順 1 のローカル
scripts/checkが同じコントラクトを通しているので手順 7 に進む
- 2 回目で check が出てきた → CI はある。手順 6 の先頭に戻り
- マージできる状態か確認する:
gh pr view --json mergeable,mergeStateStatus。CONFLICTINGなら下の「PR にコンフリクトが出たとき」へ。BLOCKED(必須レビュー未達・保護ブランチ条件など)なら理由をそのまま報告して止まる。 - マージする:
gh pr merge <N> --merge。- 他コマンドと
&&で連結せず単発で発行する(連結すると permission classifier に落ちる環境がある) --squash/--rebaseは使わない(repo 履歴の "Merge pull request" 形式に合わせる)--delete-branchは使わない。gh がローカルブランチも消しに行き、この worktree が checkout 中のブランチを触るため。リモートブランチは次の手順で消す
- 他コマンドと
- リモートブランチを掃除する:
git push origin --delete <ブランチ名>(これも単発で発行する)。repo のdeleteBranchOnMergeが無効だとマージ済みブランチが remote に溜まり続け、結局 GitHub 上での手動掃除が要るため。ローカルブランチは触らない(/wt-clean のwt rmが消す)。remote ブランチが消えても PR は headRefName で引けるので /wt-clean の PR 検査は通る。失敗しても(保護設定・権限・既に消えている)マージ自体は完了しているのでブロックせず、報告に一行添えるだけにする。 - 報告する: PR URL とマージ済みであること、
Fixes #Nで issue が閉じたこと、本体 checkout の更新(git pull)は dev 側で行うこと、続けて /wt-clean で worktree を片付けること。 - レビュー指摘や CI 失敗で修正したら: 修正 → コミット →
git push。同じ PR が更新される(作り直さない)。手順 6 から再開する。
PR にコンフリクトが出たとき
base ブランチが進んで PR がコンフリクトしたら、worktree 側で git fetch origin && git merge origin/<base> を実行する。コンフリクトしたファイルを列挙して報告し、自動解決・自動 commit はしない — ユーザーの判断を待ってから解決・コミット・push する。
ローカルモード(remote 無し / gh 無し)
wt mergeを実行する(task は現在のブランチから自動推定される。本体の dirty 判定・detached 判定は wt が行う)。repo にscripts/checkがあれば wt がマージ前に実行し、失敗したらマージされない。- 成功したら報告する: マージ先ブランチ、取り込まれたコミット数、変更ファイル数(
git -C <本体> diff --stat HEAD~1 HEAD等)。続けて/wt-cleanでの片付けを提案する。
scripts/check が失敗したとき
チェックの失敗は「取り込み条件を満たしていない」という意味。worktree 側で原因を修正してコミットし、やり直すのが正道。
- 回避(PR モードでの省略 / ローカルモードの
--no-check)はユーザーが明示的に指示した場合のみ。自己判断で使わない。 - 修正できない失敗(環境起因など)はその旨を報告してユーザー判断を待つ。
コンフリクト時(ローカルモード、自動解決禁止)
コンフリクトは本体 checkout 側の working tree に発生する。
git -C <本体パス> diff --name-only --diff-filter=Uでコンフリクトファイルを列挙して報告する。- 自動解決・自動 commit はしない。選択肢を提示してユーザー判断を待つ:
- dev 側のセッションで解決して commit する
git -C <本体パス> merge --abortで取りやめる
エラー時
- 「本体に未コミットの変更がある」(ローカルモード)→ dev 側で commit / stash が必要。そのまま報告する。
- 「ブランチ worktree-… が存在しない」→ 状況を
wt listで確認して報告する。 - push が拒否された(認証・保護ブランチ等)→ エラー出力をそのまま報告してユーザー判断を待つ。
gh pr mergeが拒否された(保護ブランチ条件・必須 check 未達・権限不足等)→ エラー出力をそのまま報告し、PR URL を示して GitHub 上でのマージを案内する。リトライで押し通さない。