Git WorktreeをSkill化でIssueを同時処理<Claude Code>

こんにちは、makeshop事業本部開発部の森です。

AI エージェントに実装を任せる場面が増えるほど、1つのタスクを待っている間に別のタスクも前に進めたくなってきます。空いた時間にもう1つ Claude を走らせている、という方も多いのではないでしょうか。Claude Code を複数セッション並べて動かすのは、もはや特別な運用ではなくなりました。

私自身、手元では cmux で複数の Claude Code セッションを並べて回しています。その並列実行を支える土台が git の worktree です。Claude Code はこの worktree を ネイティブサポート するようになり、--worktree フラグだけでも worktree 上のセッションを手軽に立ち上げられます。

本記事では、この worktree を Skill 化して、より簡単に Issue 対応と紐づけた issue-start-worktree を、個人の開発環境で使えるようにするまでの記録としてまとめます。

なぜ作ったのか

worktree で作業空間を分ければ並列実行が成立する、ここまでは公式機能が用意してくれます。引っかかったのはその先で、worktree を切って実装に入るまでに、毎回これだけの段取りがついて回ります。

  • ベースブランチを最新化する
  • ブランチ名・ディレクトリ名を決める
  • 依存パッケージをインストールする
  • .env などの gitignore 対象ファイルをコピーする
  • Issue を読み込み、要件・実装方針を整理する

1回ぶんは大した手間ではなくても、並列セッションの数だけ手で繰り返すとなると話は別です。正直なところ、私も最初はセッションを増やすたびにこれを手でなぞっていて、だんだん「毎回これか」と感じるようになりました。そこで、この一連の手順をひとまとめにしたのが Custom Skill issue-start-worktree です。worktree という器は公式に任せ、その中で回す Issue 対応の段取りを Skill 側で固定しました。

issue-start-worktree が引き受ける範囲

issue-start-worktree は、これらの定型作業を /issue-start-worktree <issue番号> の1コマンドにまとめたものです。起動から実装着手まで10ステップで完結します。

前提として、内部で git worktreegh issue view を実行するため、git CLI と GitHub CLI(gh)がインストール・認証済み であることが必要です。

                /issue-start-worktree <issue番号>
                          │
                          ▼
┌────────────────────────────────────────────────────────────────────┐
│ 1. gh issue view <issue番号>                                       │
│ 2. ブランチ名・worktree ディレクトリ名を提案 + ユーザー確認        │
│ 3. ベースブランチを最新化 → worktree add                           │
│ 4. cd <worktree-path>     ← Bash cwd を切り替える                  │
│ 5. 依存セットアップ / 環境設定の用意                               │
│ 6. 要件・実装方針を整理 (Issue 内容 / 要件 / 方針)                 │
│ 7. 不明点をユーザーに確認                                          │
│ 8. 実装開始                                                        │
│ 9. 実装後のセルフレビュー                                          │
│ 10. コミット・push は **やらない** (ユーザー指示待ち)              │
└────────────────────────────────────────────────────────────────────┘

ここからは、各ステップが実際に何をしているのかを順に見ていきます。

Issue を取得し、命名案を出す(ステップ1〜2)

まず gh issue view で対象 Issue のタイトル・本文・ラベルを取得します(ステップ1)。そのうえで地味に効いてくるのが、ステップ2の ブランチ名・ディレクトリ名の提案 です。

並列で複数の worktree を運用すると、毎回ブランチ名を考えるのが地味な負担になります。命名規則を覚えていても、Issue タイトルを slug 化して、type を判断して、ディレクトリ名に整形して……という頭の運用が並列セッション分だけ増えます。issue-start-worktree では、命名案を Skill 側が自動で組み立てて提示してくれる ので、開発者は承認するか手直しを指示するだけで済みます。Skill が走らせる処理はこうです。

gh issue view <issue番号>   ← タイトル・本文・ラベルを取得
        │
        ▼
┌─────────────────────────────────────┐
│ <type> を推定                       │
│   labels と issue 内容から          │
│   feat / fix / refactor / chore /   │
│   docs のいずれかを選ぶ             │
│                                     │
│ <slug> を生成                       │
│   タイトルを kebab-case 化          │
│   日本語タイトルは要約英訳          │
│                                     │
│ ディレクトリ名を整形                │
│   ブランチ名の `/` を `-` に置換    │
└─────────────────────────────────────┘
        │
        ▼
   提案:
     ブランチ名      feat/issue-<issue番号>-add-login-button
     ディレクトリ名  feat-issue-<issue番号>-add-login-button
        │
        ▼
   👤 ユーザー承認待ち

たとえば Issue タイトル Add Google login button にラベル feature が付いていれば、Claude は feat/issue-<issue番号>-add-login-button を提案してきます。開発者は「OK」と返すか、「slug を google-login にして」と指示するだけです。ディレクトリ名でブランチ名の /- に置換しているのは、/ をそのまま使うと <repo>-worktrees/feat/issue-... のようなネスト構造になり、フラットに一覧したい運用と相性が悪いからです。

SKILL.md には「ユーザーに確認するまで次の手順に進まない」と明記しています。命名は Claude が考えて、人間が承認する——この分担を最初の一拍で固定する設計です。並列セッションは数が増えるほど名前で見分けることになるので、ブランチ名は最初に自分の目で確認したい、という運用にしています。

worktree を作り、セッションごと移動する(ステップ3〜4)

承認された名前で、ベースブランチを最新化してから worktree を作成します(ステップ3)。このときメインリポジトリ本体には一切触らず、リポジトリの隣(<リポジトリ名>-worktrees/<dir-name>/)に新しい作業空間を切り出します。

ここで使うリポジトリのパスやベースブランチは、この skill が カレントの git リポジトリから自動で検出 します(git rev-parse --show-toplevelorigin/HEAD の検出)。特定のリポジトリにハードコードされていないので、どのプロジェクトでもそのまま使えます。なお末尾の SKILL.md 全文では、この検出を最初に行う「ステップ0」として独立させています(本記事の図では 1〜10 に集約しています)。

作成したら、コマンドを叩いたセッション自身がその worktree に移動します(ステップ4)。別ターミナルに新しい Claude を立ち上げる仕組みではなく、あくまで「いまのセッションを、新しく作った worktree に切り替える」だけです。並列で進めたいときは、cmux でもう1つセッションを開き、そこで別の Issue 番号に対して同じコマンドを叩きます。セッションごとに別々の worktree・別々の Issue が割り当たる、という形です。

依存と環境をそろえる(ステップ5)

worktree は新しいディレクトリなので、node_modules.env のような gitignore 対象は引き継がれません。ステップ5では、プロジェクトに応じた依存インストールと、環境設定ファイルの用意をまとめて行います。秘密情報を含むファイルは直接コピーせず、.env.example などのテンプレートやプロジェクト標準の初期化手順に従うのが安全です。

要件を整理し、不明点を先に潰す(ステップ6〜7)

Issue を読んで要件・完了条件・実装方針を整理し(ステップ6)、曖昧な点や設計判断が必要な点があれば、実装に入る前にユーザーへ質問して確定させます(ステップ7)。「分かったつもりで走り出して、後から手戻りする」を避けるためのガードレールで、確定するまで実装に進まないことを SKILL.md に明記しています。

実装後のレビューとコミット保留(ステップ8〜10)

実装(ステップ8)が一通り終わったら、抜け漏れや余計な変更がないかをセルフレビューします(ステップ9)。そして コミットとプッシュは、ユーザーが明示的に指示するまで行いません(ステップ10)。並列で複数セッションが走っているときに勝手にコミットが積まれると、差分の把握が一気に難しくなります。最後の手綱は人間が握る、という設計です。

おわりに

ポイントは、worktree という「器」は公式機能に任せ、その上で回る Issue 対応の段取りだけを Skill に閉じ込めた、という割り切りです。器づくりを公式へ預けたぶん、Skill は命名・要件整理・実装ガードレールといった「中身」に集中できます。

1人の人間が1つの Claude にかかりきりという形は、AI 駆動開発の入り口に過ぎません。「もう1セッション立ち上げる」という一歩のコストを、こうした小さな段取りの Skill が下げてくれます。

まずは公式の claude --worktree で並列セッションの感触を確かめてみてください。そのうえで Issue 対応まで型にしたくなったら、末尾の SKILL.md をコピーして自分のリポジトリに置いてみてください。リポジトリのパスやベースブランチは自動で検出されるので、書き換えずにそのまま使えます。同じように並列運用を組んでみたい方の参考になれば幸いです。

参考リンク

SKILL.md 全文

全文を下に畳んでおきます。この skill は リポジトリ非依存 で、.claude/skills/issue-start-worktree/SKILL.md として配置すれば、リポジトリのパスやベースブランチはカレントの git リポジトリから自動検出されます(手元のパスを書き換える必要はありません)。依存セットアップのコマンドだけ、プロジェクトのパッケージマネージャに合わせて調整してください。

issue-start-worktree / SKILL.md 全文を開く

---
name: issue-start-worktree
description: >-
  GitHub Issue を新規 worktree + 新規ブランチ で対応開始するための skill。
  メインの作業を中断せずに別 issue に着手したいとき
  ("issue を別 worktree で始めたい", "新しい worktree 作って issue 対応", "並行で issue やる")
  に使う。worktree 作成 → issue 内容取得・要件整理 → 実装着手まで
  をワンストップで行う。リポジトリ非依存(カレントの git リポジトリを自動検出)。
user_invocable: true
arguments:
  - name: issue_number
    description: GitHub Issue number
    required: true
---

# issue-start-worktree

GitHub Issue #$ARGUMENTS を、新規ブランチを切った新規 worktree 上で対応する。
メインリポジトリは触らず、リポジトリ外の worktree ディレクトリを作業ディレクトリとし、
**現在の Claude Code セッションのまま** worktree に `cd` して継続作業する。

この skill は特定リポジトリに依存しない。リポジトリのパス・派生ブランチ・worktree 配置はすべて
カレントの git リポジトリから自動検出するか、ユーザーに確認して決める。

## 用語(手順中で使うプレースホルダ)

| プレースホルダ | 意味 | 求め方 |
|---|---|---|
| `<repo-root>` | メインリポジトリの絶対パス | `git rev-parse --show-toplevel` |
| `<repo-name>` | リポジトリのディレクトリ名 | `basename <repo-root>` |
| `<base-branch>` | 派生元ブランチ | 既定ブランチを自動検出(後述)。プロジェクト規約があれば優先 |
| `<worktree-root>` | worktree を並べる親ディレクトリ | 既定 `<repo-root>/../<repo-name>-worktrees`(リポジトリ外) |
| `<branch-name>` | 新規ブランチ名 | 手順2で決定 |
| `<dir-name>` | worktree ディレクトリ名 | `<branch-name>``/``-` に置換 |
| `<worktree-path>` | 作業ディレクトリの絶対パス | `<worktree-root>/<dir-name>` |

## 前提

- worktree 作成コマンドは `git -C <repo-root> ...` でメインリポジトリを明示する。
- 作成直後に `cd <worktree-path>` で Bash の cwd を切り替え、以降の `git` / ビルド・タスク系コマンドは相対で動かす。
- **Read / Write / Edit / Grep などのファイル操作ツールは cwd を見ないので、引き続き worktree の絶対パス (`<worktree-path>/...`) を使う。**

## 手順

### 0. リポジトリ情報を確定

カレントディレクトリの git リポジトリから基礎情報を取得する。

```bash
git rev-parse --show-toplevel        # → <repo-root>
```

派生元ブランチ `<base-branch>` を決める。プロジェクトに `develop` 運用などの規約があればそれに従い、
なければ既定ブランチ(`origin/HEAD` が指す先)を検出する。`develop` / `main` / `master` などプロジェクトに
よって異なるため、検出結果をユーザーに提示して確認する。

### 1. Issue 内容を取得

```bash
gh issue view $ARGUMENTS
```

タイトル・本文・ラベルを把握する。`gh` コマンドはどのディレクトリからでも実行可。

### 2. ブランチ名・worktree ディレクトリ名を決定

issue タイトルから `<type>/issue-<number>-<slug>` 形式のテンプレを生成し、ユーザーに提示して確認・編集してもらう。

- `<type>` 候補: `feat` / `fix` / `refactor` / `chore` / `docs` 等。issue ラベルや内容から推定する
- `<slug>`: タイトルを kebab-case 化した英数ハイフン(日本語タイトルの場合は要約英訳)
- `<dir-name>` はブランチ名の `/``-` に置換した形を推奨(例 `feat/issue-12345-foo``feat-issue-12345-foo`)

**ブランチ名は git で有効な形に正規化してから使う。** issue タイトル由来の slug をそのまま
`git worktree add -b` に渡すと、空白・記号・日本語残りで失敗する。英小文字・数字・`-` のみに変換し、
連続する `-` を畳み、先頭・末尾の `-` を除去したうえで検証する:

```bash
git check-ref-format --branch "<branch-name>" && echo OK
```

正規化したテンプレをユーザーに提示し、確認・編集してもらうまで次の手順に進まない。

### 3. base-branch を最新化して worktree を作成

```bash
git -C <repo-root> fetch origin <base-branch>
git -C <repo-root> worktree add -b <branch-name> \
  <worktree-path> origin/<base-branch>
```

エラーパターン:

| 症状 | 対処 |
|------|------|
| `fatal: '<path>' already exists` | 既に存在するパス。別名にするか、既存 worktree を確認 (`git -C <repo-root> worktree list`) |
| `fatal: '<branch>' is already checked out at '<other-path>'` | 同名ブランチが別 worktree で開かれている。別名を使う |

### 4. その worktree に cwd を切り替える

worktree が出来たら、**すぐに同じセッションのまま `cd` で移動する**。Bash の cwd は永続化されるので、一度切り替えれば以降のコマンドはこの worktree 上で動く:

```bash
cd <worktree-path>
```

- `git status` / ビルド・タスク系コマンドは相対で OK
- ファイル系ツール (Read/Write/Edit/Grep) は cwd を参照しないので、worktree 配下は絶対パス (`<worktree-path>/...`) を使う
- メインリポジトリ側を参照したいときは `<repo-root>/...` の絶対パスで明示する

### 5. 依存セットアップ(必要時)

issue が触る領域に応じて worktree 側で実行する。プロジェクトのパッケージマネージャ/ビルドツールに合わせる:

| 領域 | 例 |
|------|---------|
| Node 系 | `npm ci` / `yarn install` / `pnpm install` |
| Go | 通常不要。古ければ `go mod download` |
| その他言語 | プロジェクト規約のセットアップコマンド |

worktree は新規チェックアウトなので、gitignore 対象のローカル設定(環境変数ファイル等)は
引き継がれない。**秘密情報を含むファイルを直接コピーする運用は避け**、リポジトリ標準の初期化方法に従う
(`.env.example` 等のテンプレートから生成する、環境変数やシークレットマネージャで渡す、など)。

dev サーバを worktree 側で立てる場合は **ポート競合** に注意(メイン側を停止 or 別ポート指定)。

### 6. 要件・実装方針を整理する

issue の内容から要件・完了条件 (DoD) と実装方針を読み取って整理し、実装の見通しを立てる。曖昧な点は次のステップで確定させる。

### 7. 不明点の確認

issue 内容が曖昧な箇所、設計判断が必要な箇所はこの段階でユーザーに質問して確定させる。確定前に実装に入らない。

### 8. 実装を開始

worktree 配下で実装する:

- **ファイル編集 (Read/Write/Edit/Grep)**: cwd を参照しないので `<worktree-path>/...` の絶対パスで操作
- **git 操作**: cwd が worktree なので `git status` / `git diff` / `git add` 等を相対で実行可
- **ビルド・タスク系コマンド**: プロジェクト規約に従って実行

既存コードのスタイル・規約に合わせる。

### 9. 実装後のセルフレビュー

実装が一通り終わったら全体を見直し、抜け漏れ・余計な変更がないかを確認する。

### 10. コミット・プッシュ

ユーザーから明示的に指示があるまで、コミットもプッシュもしない。

## 注意

- issue を完全に・過不足なく実装する。理解が曖昧なまま進めない
- 同じブランチを複数 worktree でチェックアウトすることは git の制約上不可
- worktree の一覧・削除:
  - 一覧: `git -C <repo-root> worktree list`
  - 削除: `git -C <repo-root> worktree remove <worktree-path>`(未コミット変更があると拒否される。確認の上 `--force`  - ブランチも消す場合: `git -C <repo-root> branch -D <branch-name>`