0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Code × git worktreeで、メイン環境を汚さずIssueを並行処理する

0
Last updated at Posted at 2026-06-21

はじめに

VSCodeでClaude CodeにIssue対応を任せていると、以下のようなことをしたいなと思いました。

  • Claudeが1つのIssueを作業している間、ローカル環境で別のIssueも並行で進めたい
  • メインのVSCodeでは devサーバーを起動したまま別作業をしており、邪魔されたくない
  • Claudeの作業が終わったら、すぐローカルのブラウザで動作確認したい。OKならそのままPRを作ってほしい
  • クラウドで完結するAIもあるが、使い慣れているVSCodeを使って差分の閲覧と検証もしたい。

解決アプローチとして、gitのworktreeという機能とカスタムスラッシュコマンドを用いた。
git worktreeを使うと、1つのリポジトリから複数の独立した作業ディレクトリを作れる(ファイル編集が互いに衝突せず、git履歴は共有)。これをClaude Codeのカスタムスラッシュコマンドで自動化した。

動作イメージ

動作イメージは以下のようになります。

  1. /issue <GitHub Issue番号>で作業してほしいissueを指定(手動)
  2. git worktreeの自動作成(自動)
  3. VSCodeが別ウィンドウで立ち上がる(自動)
  4. 新規VSCodeのターミナルが自動で立ち上がり、/issue-workが実行され作業を開始する(自動)
    work.gif

導入方法

今回作成した、/issue/issue-workをカスタムスラッシュコマンドとしてClaude Codeが読み込める形にします。
~/.claude/commands/に置けば、全リポジトリ共通で使えます。

カスタムスラッシュコマンドの導入

以下のテキストをコピーして使用します。

`/issue`(VSCodeランチャー)
~/.claude/commands/issue.md
---
description: Issue番号からworktreeを作成し、新しいVSCodeウィンドウでClaude作業セッションを自動起動する(ランチャー)
argument-hint: <issue番号>
---

GitHub Issue #$ARGUMENTS の作業環境をセットアップしてください。
あなたの役割は**ランチャー**です。実装はこのセッションでは行いません(実装は新ウィンドウ側の `/issue-work` が担当)。

## 大前提(最重要)

- **現在のチェックアウトはユーザーが別作業中。絶対に触らない。**
  現在のディレクトリでのファイル編集・`git checkout` / `git switch` / `git stash` は禁止。
- このコマンドの実行自体が「worktree 用ブランチ作成の許可」とみなしてよい。

## 手順

1. `gh issue view $ARGUMENTS --json title -q .title` で issue タイトルを取得し、**スラッグ**を作る:
   - 英数の kebab-case に変換する(例: "Fix login form validation" → `fix-login-form-validation`   - 日本語タイトルは内容を表す短い英語に意訳する(例: "ログイン画面のバリデーション修正" → `fix-login-validation`   - 3〜5語・30文字程度まで。記号は除去する
   - 以降、worktree 名は `issue-$ARGUMENTS-<スラッグ>`、ブランチ名は `issue/$ARGUMENTS-<スラッグ>` とする
2. `git fetch origin` を実行し、worktree を作成する:
   `git worktree add .claude/worktrees/issue-$ARGUMENTS-<スラッグ> -b issue/$ARGUMENTS-<スラッグ> origin/HEAD`
   (同名ブランチが既に存在する場合は `-b` を外して既存ブランチで作る)
3. `.env` など gitignore されていて実行に必要なファイルを、メインのチェックアウトから worktree にコピーする。
4. worktree 内に `.vscode/tasks.json` を作成する。これは新ウィンドウで Claude を自動起動するための**使い捨てファイル**`/issue-work` 側が起動後すぐ削除する):

   ```json
   {
     "version": "2.0.0",
     "tasks": [
       {
         "label": "claude-issue-worker",
         "type": "shell",
         "command": "claude \"/issue-work $ARGUMENTS\"",
         "runOptions": { "runOn": "folderOpen" },
         "presentation": { "focus": true, "panel": "dedicated" },
         "problemMatcher": []
       }
     ]
   }
   ```

5. `code <worktreeの絶対パス>` で新しい VSCode ウィンドウを開く。
6. 以下を報告して終了する:
   - worktree のパスと、新ウィンドウで `/issue-work $ARGUMENTS` が自動起動すること
   - もし自動起動しない場合(自動タスクが未許可など)は、新ウィンドウのターミナルで
     `claude "/issue-work $ARGUMENTS"` を手動実行すればよいこと

このセッションは引き続き別の `/issue <番号>` を受け付けられる(ディスパッチャーとして使い回せる)。
`/issue-work`(作業役)
~/.claude/commands/issue-work.md
---
description: worktree内でIssueの実装〜動作確認待ち〜PR作成まで進める(/issueから自動起動される作業役)
argument-hint: <issue番号>
---

GitHub Issue #$ARGUMENTS に対応してください。
あなたは worktree 内で起動された**作業セッション**です。カレントディレクトリがその worktree です。

## 大前提

- 作業はすべてこの worktree 内で完結させる。worktree の外(メインのチェックアウト)には触らない。
- **push と PR 作成はユーザーの「OK」が出るまで禁止**## 手順

1. まず `.vscode/tasks.json` を削除する(自動起動用の使い捨てファイル。PR に混入させない)。
2. `gh issue view $ARGUMENTS` で issue の内容・受け入れ条件を確認する。
3. 依存関係をインストールする(例: `npm install`。worktree は新規チェックアウトなので `node_modules` が存在しない)。
4. 実装する。既存のテスト・lint があれば実行して通す。
5. コミットする(push はしない)。
6. 動作確認の準備として、dev サーバーを**バックグラウンド起動**する。
   メインのチェックアウトのサーバーと衝突しないよう、空いているポートを使うこと
   (例: `npm run dev -- --port 3001`。3001 が埋まっていれば 3002, 3003…と探す)。
7. 完了したら以下を報告し、**ユーザーの確認待ちで止まる**:
   - 確認用 URL(例: http://localhost:3001)と、確認すべき画面・API・操作手順
   - 変更内容の要約(何をどう変えたか)
8. ユーザーが「OK」と言ったら:
   - dev サーバーを停止する。
   - push し、`gh pr create` で PR を作成する(本文に変更概要・動作確認内容・`closes #$ARGUMENTS` を含める)。
9. 修正指摘があった場合は、修正→再コミット→手順7に戻る
   (サーバーがホットリロード対応なら起動したままでよい)。
10. PR 作成後、後片付けの案内をして終了する:
    - このウィンドウは閉じてよいこと
    - worktree の削除はメインのチェックアウト側で
      `git worktree remove <この worktree の絶対パス>` を実行すればよいこと
      (実際のパスを `pwd` で確認して案内する。ランチャー側の Claude に
      「issue #$ARGUMENTS の worktree を消して」と頼んでもよい)

実際の動作

実際の動作原理です。読み飛ばしても問題ありません。

/issue(ランチャー): 環境構築だけ。メインのチェックアウトには一切触らないことを厳命。同じセッションで次々と Issue をディスパッチできる

/issue-work(作業役): 新ウィンドウ側で自動起動され、実装〜確認待ちまでを担当

メインのターミナル(ディスパッチャー)         
─────────────────────────────
1. claudeを起動して /issue 17 コマンドを受理
2. ghでIssueタイトル・内容取得
3. worktree 作成(worktree名はIssueの内容から自動命名)
4. .env をメインからコピー
5. 使い捨て tasks.json を仕込む
6. code <worktreeパス> で新ウィンドウ起動 


新しいVSCodeウィンドウ(自動で開く)
─────────────────────────────
新しいVSCodeウィンドウでClaudeを自動起動する部分は、VSCodeの自動タスク機能(tasks.json の "runOn": "folderOpen")を利用。

1. フォルダを開いた瞬間、自動タスクでtasks.json を即削除(PR混入防止)
2. npm install(worktreeは新規チェックアウト)
3. 実装 → テスト → コミット
4. 必要があれば、空きポートで dev サーバー起動

今後の展望

  • 作業が終わったらpushとPR作成を自動で行ってworktreeも削除して完了するまでを自動化しても良いかもしれないです。AIにpushして欲しくなかったので、今回は含めていません。
  • 余談ですが、Claudeが作業完了したときに音を鳴らすようにすると、捗ります。

参考文献

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?