KAKEHASHI Tech Blog

カケハシのEngineer Teamによるブログです。

git worktree × PR 一覧確認・一括掃除・Claude Code 自動起動を 1 コマンドにした CLI ccw を開発した

はじめに

こんにちは。 電子薬歴 Musubi の基盤開発チームで SRE を担当している大山です。

今回は、Claude Code で増えていく git worktree を PR 情報つきの一覧・選択・起動・後片付け までまとめて扱える個人 OSS の CLI ccw を紹介します。claude --worktreegit worktree を薄くラップしているだけのツールです。

普段の開発では Claude Code をメインに使っているのですが、単一のリポジトリで複数の作業を並行して進める となると、気づけば worktree が溜まって、どれが何の作業だったか迷子になったり、まとめて片付けたくなったりする場面が増えてきました。手元で一番やりたかったのは 「どの worktree か分からなくならない」「使い終わった worktree を一括で片付けたい」 という 2 点で、そこをそのまま CLI に落とし込んだのが ccw です。

ccw-cli header

対象となる読者

  • 作業を再開するときに「どの worktree が何の作業だったか」で迷いがちな方
  • git worktree を使っているが、気づくと worktree が増えて後片付けが面倒になっている方
  • Claude Code をメインに使っていて、同じリポジトリで複数の作業を並行して進める機会がある方

背景: 何に困っていたのか

普段は OS もターミナルも常時起動したままなので、作業の続きは「開いたままのタブに戻る」 で大抵は済みます。ただ、プロセスがクラッシュしたり、OS を再起動せざるを得なかったり、あるいは別の作業に切り替えている間に worktree のディレクトリから意図せず抜けてしまったり ー こうした ターミナルの文脈が切れるタイミング が、稀ではあるもののどうしてもあります。いざ作業を再開しようとしたとき ー 改めてゼロからターミナルを開き直したときや、別の作業から戻ってきたとき に、「どの worktree で何の作業をしていたんだっけ」 がパッと見でわからなくなる、というのが一番最初の困り事でした。

作業単位で git worktree を切る運用にしてからは並列作業自体はやりやすくなったのですが、その分 worktree の本数が増えて、作業を再開するたびに迷子になる回数も比例して増えてきました。

作業再開時に具体的にどう困っていたかを分解すると、次の 3 点になります。

困り事.1 再開時、worktree 名からは何の作業か判別できない

先ほど挙げた ターミナルの文脈が切れたあと.claude/worktrees/ を開くと、一番最初に突き当たるのがこの問題です。自分の運用では、作業の詳細を詰める前にとりあえず worktree を切って Claude と壁打ちすることが多く、worktree 名を手動で決めずに claude --worktree 任せのランダム命名にすることがほとんどです。結果として .claude/worktrees/ 配下は gleaming-scribbling-muffin のような形容詞 + 動名詞 + 名詞が並んだ状態になり、衝突しにくい反面 フォルダツリーを眺めても「どれが何の作業だったか」 が全くわからない 状態になります。

さらに、対応する PR が open なのか merged なのか、未コミットの変更が残っていないか ー ディレクトリ名だけでは何も判別できないので、再開のたびに結局一つずつ cd して git status やブランチ名から作業内容を思い出す羽目になっていました。

困り事.2 消し方の粒度を選びたい

場面によって消したい単位が違います。

  • ピンポイントで 1 つだけ消したい
  • 「push 済みでマージ済みの worktree」 だけまとめて片付けたい
  • 作業中のものも含めて 全部消して綺麗にしたい

TUI でチェックボックスを選ぶように削除できると一番楽ですが、CLI フラグで --clean-all --status=pushed のように非対話でも実行できると、スクリプト化したいときにも使えます。

💡 補足: claude --worktree で作業を開始して、完全に完了してから exit すると、Claude 側が 「この worktree を削除しますか?」 と聞いてくれるので、その場で yes と答えれば綺麗に作業を終えられます。本来はこれで片付くはずなのですが、途中で別作業に切り替えたり、ターミナルごと落ちたりしてこの削除確認のタイミングを逃してしまうことが実際には多く、そうして迷子になった worktree をあとから整理するためのツールが ccw です。

困り事.3 「何か打てば何とかなる状態」 にしたい

一番大きかったのはこれで、リポジトリに入って ccw とだけ打てば、既存 worktree を選ぶか新規を作るかの画面に行き着く という状態を作りたかったのです。

「えっと、続きの作業だから既存の worktree を探して cd して claude を叩く、あるいは新規なら claude --worktree で始める ...」といった分岐を毎回考える手順は、頭の中の context を消費します。ターミナルを開きっぱなしにしておけば省けるのですが、プロセスがクラッシュしたりリソース不足で落ちたりといった事象も稀に発生するので、結局「どこの worktree だっけ」 を思い出す作業が定期的に湧いてきます。そこは機械に任せて、自分は「どの作業を続けるか」だけ選びたい。

他の選択肢の検討

最初からこの形を作ったわけではなく、しばらくは fzf + git worktree list を組み合わせたシェルスクリプト で運用していました。簡易的な選択画面なら十分作れますし、立ち上げコストもゼロです。

ただ、PR のステータスやローカルの dirty / clean、upstream との ahead / behind まで表示したくなるたびに ~/.zshrc に関数や alias を足していった結果、~/.zshrc が見通しの悪い状態に膨らんでしまいました。Claude Code 2.1.49 (2026-02-19) で --worktree フラグが標準入りしたこともあり、シェル設定を痩せさせたい気持ちと合わせて「独立したバイナリに切り出す」選択に傾きました。

なぜ CLI という形にしたか

理由は大きく 2 つです。

  1. ~/.zshrc を整理したかった: 関数や alias が増えて見通しが悪くなっていた状態から、独立したバイナリに切り出せば元のサイズに戻せます。
  2. 他の人にも気軽に試してもらえる形にしておきたかった: brew install tqer39/tap/ccw で入れて、合わなかったら brew uninstall で綺麗に剥がせる ー そのくらいの距離感を目指しました。

自分の環境や好みを押し付けず、困っている部分だけにそっと刺さってくれるツールであれば嬉しいです。

ccw がやっていること

ざっくり書くと ccw は以下の 3 つを束ねた CLI です。

  1. git worktree の一覧を拾ってきて、ステータス付きで TUI (以降「選択画面」と呼びます) に表示する
  2. 選んだ worktree で claude を起動する (既存 worktree ならそのディレクトリで、なければ claude --worktree で新規作成)
  3. 使わなくなった worktree をまとめて消す (一括削除)

最低限の使い方は以下のとおりです。

# インストール
brew install tqer39/tap/ccw

# 任意の git リポジトリで
ccw

この 1 行で worktree 一覧 → 選択 → Claude Code 起動まで走ります。worktree が 1 つも無ければ新規作成の画面に進みます。

実際の選択画面の挙動は、README に貼ってある GIF が手っ取り早いです。

picker demo

選択画面の表示例

選択画面では worktree 状態PR 状態 の 2 種類のバッジを並べて表示しています。

worktree 状態バッジ (ローカルの git の状態から判定)

バッジ 意味
🟢 [PUSHED] clean・upstream 追従・ahead 0 の状態 (消してもほぼ安全)
🟡 [LOCAL] upstream が無い、または ahead commit あり (push 忘れの可能性)
🔴 [DIRTY] 未コミットの変更あり (消すと変更ごと失われる)

これに加えて、↑N ↓M ✎N の数字で ahead / behind / modified file の個数も出しています。

PR 状態バッジ (gh が入っているとき限定)

バッジ 意味
🟩 [OPEN] オープン中の PR (レビュー / マージ待ち)
[DRAFT] ドラフト PR
🟪 [MERGED] マージ済みの PR
🟥 [CLOSED] マージされずにクローズされた PR

PR 番号・状態・タイトルが選択画面の右側に並ぶので、「どの worktree がどの PR 用だったか」が一目でわかるようになりました。gh が未導入でも選択画面自体は普通に動き、PR バッジだけが出ない形になります。

実際に ccw-cli 開発中に ccw を起動した画面がこちらです。各 worktree のバッジ・ahead/behind/modified file の数・PR 情報が 1 画面に揃います。

ccw の選択画面 — worktree 一覧 (ccw-cli 自身の開発時の様子)

一括削除

選択画面には [clean pushed] / [delete all] / [custom select] というショートカット項目を用意していて、「push 済みをまとめて消す」 「全部消す」 「チェックボックスで選んだ分だけ消す」 がそれぞれ選べます。

CLI フラグ経由でも同じことができます。

ccw --clean-all --status=pushed --dry-run   # 消える対象をプレビュー
ccw --clean-all --force -y                  # 確認なしで一括削除

dirty な worktree を含む削除操作では、

  • y → force で消す
  • s → dirty だけ除外する
  • N → キャンセル

の 3 択を経由する作りにしているので、うっかり未コミットの作業を消してしまう事故は減らせているはずです。

[clean pushed] を選んだ直後の画面はこんな感じで、push 済みだった worktree が一覧から消えて、残っているのは dirty / local なものだけです。

ccw で `clean pushed` を実行した直後の画面 — 🟢 PUSHED の worktree がまとめて消えている

工夫したポイント

ここからは、作るときに意識した細かい設計の話です。

リポジトリ内ならどこから起動しても動く

必ずリポジトリのルートに cd してから叩く、というルールを持ちたくなかったので、git rev-parse --git-common-dir でメインリポジトリを解決し、サブディレクトリや別の worktree の中から ccw を叩いても同じように動く作りにしました。

一番のメリットは 「意図しない場所で claude を起動してしまう事故が減る」 ことです。以前、worktree 配下にいることに気づかず claude を起動してしまい、想定と違うブランチ・作業コンテキストで会話を始めてしまったことが何度かありました。ccw はどこから起動しても必ずメインリポジトリを解決してから選択画面を出してくれるので、「いまどの worktree にいるか」を気にせず安心して叩けるようになりました。

透過的な passthrough (--)

ccw -- --model opus のように -- 以降を書くと、そのまま claude コマンドに渡します。普段使いのオプションを ccw 側の語彙に取り込まずに済むので、Claude Code 本体のオプションが増えても ccw の実装を追従させる必要がありません。

-s で superpowers のワークフローを注入 (オプショナル)

ここから先は worktree ランチャーとしての本筋からは少し外れる、オプショナルな機能 の話です。「最初に設計から詰めたいタイプの作業」が多い方向けの位置付けです。

ccw -s で新しい worktree を作ると、Claude Code 起動時に superpowers プラグインの「brainstorming → writing-plans → executing-plans」ワークフローを最初のプロンプトとして注入します。

superpowers は Jesse Vincent 氏らが公開している「コーディングエージェントにいきなり書かせずに段取りを踏ませる」ためのスキル集で、-s で注入しているのはその中心となる 3 つのスキルです (README より要約)。

  • brainstorming: コードを書く前に起動。ラフなアイデアを質問で精緻化し、代替案を並べ、セクション単位で検証可能な形にした上で、最終的に設計ドキュメント (docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md) として保存する。
  • writing-plans: 設計が承認されたら起動。作業を 1 タスク 2〜5 分で完了できるタスクに分割し、各タスクに「正確なファイルパス」「完全なコード」「検証手順」を書き込んだ実行計画を docs/superpowers/plans/YYYY-MM-DD-<feature-name>.md に保存する。
  • executing-plans: 計画ができたら起動。計画をバッチ単位で実行しながら、バッチ境界でユーザーにチェックポイントを取る。サブエージェントにタスクを配る派生スキル (subagent-driven-development) もあり、そちらは「仕様準拠 → コード品質」の 2 段レビューが自動で走る。

メリット: 発散 → 計画化 → 実行の 3 段が設計ドキュメント・計画ドキュメントとして残るので、新機能のような「前提から揃えたい作業」 で道筋をトレースしやすくなります。

デメリット: 3 段を丁寧に回す分、通常より トークン消費と実行時間が増えます。軽い修正やバグ 1 件の対応なら素の ccw の方が適していて、-s は「新機能の初動」 「設計の認識合わせから始めたいとき」 に限定するのが現実的です。

なお -s は私の好みに寄せたショートカットです。superpowers を独自のワークフローで使いたい方は、-s を付けずに ccw (または ccw -n) で起動し、Claude に任意のタイミングでスキルを呼び出してもらう方が柔軟です。superpowers プラグイン未導入の場合は -s を付けなければ通常起動になります。

.claude/worktrees/docs/superpowers/ を git 管理対象外にしておく

ccw と superpowers を併用すると、以下 2 種類の ローカル作業用で、リポジトリにコミットする必要のない 生成物が増えていきます。

  • ccw (実体は claude --worktree) が作る worktree: .claude/worktrees/<name>/ — ローカル作業用の git worktree 実体なので、コミット対象にするとサブリポジトリが混入する形になります
  • superpowers の設計 / 計画ドキュメント: docs/superpowers/specs/docs/superpowers/plans/ — 手元の思考プロセスの記録で、レビューや運用の一次情報にはしたくないケースが多いはず

両方まとめて .gitignore に入れておくと、意図していないファイルのコミットを防げます。

# .gitignore
.claude/worktrees/
docs/superpowers/

「設計ドキュメントはチームで共有したい」 場合は docs/superpowers/ を除外せず、.claude/worktrees/ だけ ignore する形にしてください。

使ってみた効果

自分の運用では以下の 3 つが明確に良くなりました。

  • 「この worktree 何だっけ」 が消えた: PR 情報とバッジが出るので、思い出すための往復が不要になりました。
  • 後片付けが手軽になった: 「そろそろ整理しておくか」 と思ったら ccw を起動して [delete all][clean pushed] を選ぶだけで、不要な worktree がまとめて消えます。
  • 新しい作業を始めるときの心理的コストが下がった: リポジトリに入って ccw -n と打てば、空の worktree で Claude Code が立ち上がるだけなので、作業単位を分けるハードルが下がりました。

おわりに

「作業ごとに worktree を切る」 という運用自体は昔からあった考え方ですが、Claude Code と組み合わせたことで、単に便利というよりも 「セッションの混線を防ぐ前提」 として欠かせない 存在に感じるようになりました。同じような悩みを抱えている方の引き出しの 1 つとして、ccw が選択肢に入れば嬉しいです。

ccw は GitHub で公開している個人 OSS なので、気になった方は覗いてみてください。合う・合わないはあると思いますが、感想や「こういう使い方しているよ」 という報告をいただけると作者として励みになります。

株式会社カケハシでは、一緒に働く仲間を募集しています。 フロントエンドやバックエンドはもちろん SRE にも楽しいお仕事が沢山あるので、興味のある方は採用ページをご覧いただけますと幸いです。