技術ブログ一覧へ

Git Worktree × Claude Code × Conductor で並列開発する実践メモ

細執筆細岡 希夢ExecutiveDirectorプロフィールを見る

はじめに

Claude Code で開発するとき、「Claude にタスクを振る → 出力を待つ → レビューする」を直列でやってると、待ち時間がとにかくダルい。

そこで git worktree と Conductor を 組み合わせて、複数の Claude Code エージェントを同時並行で走らせる ワークフローを運用している。開発から検証まで並列で回せるようになって、 1人で複数タスクを進めている感覚がかなり変わった。

この記事は、その運用で得た知見の実践メモ。git-flow を前提にしている。

想定読者: Claude Code を日常的に使っていて、もう一段スループットを 上げたい人


なぜ並列開発か

worktree を活用すると、こうなる。

  • 1人で独立性の高い feature/* ブランチを同時に複数走らせられる (例: feature/login-form と feature/refactor-api を並行)
  • develop での作業を中断せず、hotfix/* や差し込みレビューに 対応できる
  • 「Claude が考えている時間」が、別 worktree での自分の作業時間に 化ける

前提: ブランチ運用は git-flow

この記事は git-flow 前提。主要ブランチはこう。

ブランチ役割派生元マージ先
main本番リリース版--
develop開発統合mainmain(release 経由)
feature/*機能開発developdevelop
release/*リリース準備developmain と develop
hotfix/*本番緊急修正mainmain と develop

並列開発では、ほとんどの worktree が feature/*(develop から派生) になる。hotfix/* は別系統で、develop の通常作業を止めずに main から派生させて並行で進める使い方が特に効く。


git worktree とは(基礎)

git worktree は、1つのリポジトリから複数の作業ディレクトリを 派生させられる Git の標準機能。

通常 git switch feature-a でブランチを切り替えると、作業ディレクトリの 中身がそのブランチの状態にまるごと差し替わる。同時に2つのブランチの 内容を触ることはできない。

worktree を使うと、feature-a と feature-b をそれぞれ別ディレクトリに チェックアウトできて、両方を同時に開いて編集・ビルド・実行できる。 .git 自体は共有されているので、リモートからの fetch やコミット履歴は 一本にまとまる。

なぜ並列開発と相性がいいか

ファイル編集の混線が起きない。Claude エージェントを2体走らせるとき、 同じディレクトリで作業させると同じファイルを同時に書き換えてしまう。 worktree なら物理的にディレクトリが別なので、両方が安心して書き込める。

ビルド成果物が壊れない。git switch で行き来すると node_modules やビルドキャッシュが片方のブランチに合わせて更新されてしまう。 worktree なら各ディレクトリが独立した成果物を持てる。

「ちょっと別ブランチ見たい」のコストが激減する。stash する必要も、 コミットしてから戻る必要もない。隣のディレクトリに移動するだけ。

単純な使い方

# 通常はこう書くが、Conductor を使えば直接叩くことはほぼない
# feature ブランチは develop から派生
git worktree add -b feature/login-form ../repo-feature-login-form develop
# hotfix ブランチは main から派生
git worktree add -b hotfix/critical-bug ../repo-hotfix-critical-bug main
git worktree list
git worktree remove ../repo-feature-login-form

全体像

┌────────────────────────────────────────────────────┐
│  Conductor が worktree を自動作成                  │
│                                                    │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐          │
│  │ feature/ │  │ feature/ │  │ hotfix/  │          │
│  │   A      │  │   B      │  │   X      │          │
│  │ Claude   │  │ Claude   │  │ Claude   │          │
│  │ :3001    │  │ :3002    │  │ :3003    │          │
│  │ db-a     │  │ db-b     │  │ db-c     │          │
│  └──────────┘  └──────────┘  └──────────┘          │
│       │             │             │                │
│       └── develop ──┘             └── main へ ──   │
└────────────────────────────────────────────────────┘

ポイントは「worktree ごとに、開発サーバーのポートと Docker コンテナ (DB 等)を分ける」こと。これで同じリポジトリの別ブランチを、 見た目上は別アプリのように同時起動できて、ブラウザでも DB クライアントでも 両方同時に検証できる。


ツールスタック

役割ツール
worktree 管理・ライフサイクル自動化Conductor(Scripts / Actions)
エージェントClaude Code
環境分離Docker / docker compose(DB・ミドルウェア)
ポート・コンテナ名の分離.env(worktree ごとに手動設定)
定型コマンド束Makefile(make up / make down 等)

Conductor が worktree のライフサイクル(作成・実行・後始末)を一手に 引き受けてくれるので、git worktree add を直接叩くことはほぼない。


セットアップ

.env で環境を分離する

worktree ごとに .env を切って、こんな感じで上書きする。

  • 開発サーバーのポート(例: PORT=3001)
  • docker compose のプロジェクト名(例: COMPOSE_PROJECT_NAME=app-wt-a)
  • Docker でホストに publish するポート(例: DB_PORT=5433)
  • アプリ側が参照する DB の接続先 (例: DATABASE_URL=postgresql://...:5433/...)

COMPOSE_PROJECT_NAME を変えると、コンテナ名・ネットワーク名・ ボリューム名がすべてそのプレフィックスで切られるので、別 worktree の DB と 取り違える事故が起きにくくなる。

採番はゆるく予約しておくと楽。

  • アプリ: 3001, 3002, 3003, ...
  • DB: 5433, 5434, 5435, ...

Makefile に作業を集約しておく

セットアップ・起動・後始末は Makefile にまとめておくと、Conductor の Scripts から呼ぶときも、手動で叩くときも同じインターフェースになって 楽。

setup:        ## 依存インストール + コンテナ作成
	npm ci
	docker compose build
up:           ## DB + 開発サーバー起動
	docker compose up -d
	npm run dev
down:         ## 開発サーバー停止 + コンテナ削除
	docker compose down -v

Conductor Scripts でライフサイクルを自動化

Scripts は worktree のライフサイクルイベントに紐づくフック。 Makefile のターゲットを呼ぶだけで、worktree の準備と片付けが全部 自動化される。

タイミングやること中身(例)
worktree 作成時コンテナ作成・依存インストール・開発サーバー起動make setup && make up
アーカイブ時コンテナ削除・開発サーバー停止make down

これで .env だけ自分で書けば、あとは Conductor 側で勝手にコンテナが 立ち上がる/消える状態にできる。「アーカイブ時のコンテナ削除を忘れて 孤児ボリュームが溜まる」事故もなくなる。

Conductor Actions でカスタム操作を仕込む

Actions は worktree に対してワンクリックで走らせる手動アクション。 チーム特有の運用ルールを Claude に毎回口頭で説明しなくて済むようにできる。

実際に仕込んでいる例:

  • Review: コードレビュー時に、独自のレビュー観点(命名規則、 セキュリティチェック項目、UX 上の確認ポイントなど)を Claude に 追加で意識させるためのプロンプト
  • PR 作成: PR 作成時に、リポジトリの PR テンプレート(背景・ 変更点・確認手順・スクショ欄など)に従わせるためのプロンプト

これらを Actions として登録しておくと、誰がやっても同じ観点で レビューと PR が出てくるので、品質が揃う。


日常オペレーション

ここが本記事の中心。

並列開発の心得(最初に読む)

タスクへの向き合い方は、直列のときと何も変わらない。

worktree が並んでて Claude が複数走ってても、ある1つのタスクに対して 「要件を理解し、Claude に的確に指示し、出力をレビューする」プロセスは 1本ずつ真剣にやる必要がある。並列だからといって雑になってよい部分は ない。

並列にすると 自分の脳の切り替えコスト は確実に上がる。タスク A の 文脈を頭から退避させて、タスク B の文脈をロードし直す、を何度も 繰り返すので、直列のときよりも疲れる。

最初は2タスク同時から始めるのを推奨。 慣れる前にいきなり3本4本走らせると、どの worktree で何を頼んだかを 見失ったり、雑なレビューで通してしまったりする。2本で違和感なく 回せるようになってから、徐々に増やすのが安全。

並列にするほどレビューの責任は重くなる。Claude が出してくる差分の量は 直列のときの N 倍になるので、自分が責任を持って見られる本数を超えない こと。

新しいタスクを始めるとき

  1. Conductor で新しい worktree を作る
    • 通常開発なら develop から feature/xxx を派生
    • 本番緊急修正なら main から hotfix/xxx を派生
    • リリース準備なら develop から release/x.y.z を派生
  2. Setup Script が走り、依存と Docker が自動で立ち上がる
  3. .env を編集してポート/コンテナ名を採番
  4. 必要に応じて再起動
  5. その worktree で Claude Code を起動し、タスクを投げる
  6. Claude が作業している間に、別 worktree で自分は別のことをやる or 別 Claude を走らせる

並列で Claude に振るときのコツ

タスクの粒度は「ファイルが被らない」単位で切る。worktree が物理的に 分かれていても、最終的にマージするのは同じ develop(hotfix の場合は main と develop の両方)なので、コンフリクトする量が少ない切り方を 選ぶ。

並列に向くタスク

  • 独立した新規画面の追加(既存ファイルへの影響が局所的)
  • ドキュメント・README の更新
  • 単発のリファクタ(範囲が明確で、ロジック変更を伴わないもの)
  • ライブラリのバージョン上げ(依存の影響範囲が読めるもの)
  • テストの追加

直列にした方が安全なタスク

  • DB スキーマ変更を伴う機能追加(マイグレーションが衝突しやすい)
  • 共通基盤(認可・ロギング等)の作り変え(全 worktree がその上に 乗っているので、後追いで全部やり直しになる)
  • アーキテクチャ判断が絡む大きめの設計変更(並列にする前に方針を 決めるべき)

検証まで並列でやる

ポートと DB を分けているので、ブラウザのタブで localhost:3001 と localhost:3002 を同時に開いて、両方の worktree の成果を同時に触れる。

レビュー前のセルフチェックでは、

  • 開発サーバーで動作確認
  • DB の状態を確認(コンテナ名が分かれているので取り違えなし)
  • 必要なら別 worktree と挙動を見比べる

を、ブランチ切り替えなしでやれる。

レビューと PR

Conductor の Actions に登録した Review / PR 作成プロンプトを呼んで、 独自観点でのセルフレビュー → テンプレに沿った PR 作成までを Claude に 任せる。

マージ・片付け

  1. 完了した worktree の PR を作成
    • feature/* → develop への PR
    • hotfix/* → main への PR(マージ後、develop にも反映する PR を別途)
    • release/* → main への PR(マージ後、develop にも反映)
  2. PR をマージ
  3. 取り込み先のブランチ(develop または main)を pull
  4. 残っている worktree で取り込み先のブランチを反映する (rebase or merge)
  5. Conductor で worktree をアーカイブ(Archive Script が走り、 コンテナとボリュームが自動で削除される)

hotfix/* をマージしたあとは、他の feature/* の worktree も develop を取り込み直す のを忘れずに。hotfix の修正が develop 側にも 反映された状態を基準にしないと、せっかく直したバグを feature 側で 復活させてしまうことがある。


ハマりどころと対策

ポート/コンテナ名の衝突

  • 症状: docker compose up が「ポートが使われている」で失敗、または 別 worktree の DB に接続してしまってデータが混ざる
  • 原因: .env のポート採番がかぶっている/COMPOSE_PROJECT_NAME を 変え忘れた
  • 対策: worktree を作った最初の一手として .env を上書きするのを 習慣化。採番表を README に置く

node_modules など重い依存

  • worktree ごとに npm install すると時間とディスクが厳しい
  • 対策: パッケージマネージャの shared cache を使う(pnpm の store、 yarn の global cache 等)

DB スキーマがブランチで分岐したとき

  • worktree A と worktree B が別々のマイグレーションを足してしまうと、 develop にマージしたあとで他の worktree が壊れる
  • 対策: マイグレーションを伴うタスクは、できれば直列で進める。 並列にする場合は、後追いの worktree が develop を取り込んだ時点で 必ずローカル DB を作り直す

release/hotfix のダブルマージを忘れる

  • hotfix/* と release/* は main と develop の両方にマージする 必要があるが、片方を忘れがち
  • 対策: PR テンプレに「もう一方への反映 PR」のチェック欄を入れる。 Conductor の Action で「ダブルマージ忘れがないか確認するレビュー観点」 を入れておくのも有効

Claude のコンテキスト境界

  • worktree ごとに別の Claude が走るので、片方の Claude が知っている 設計判断をもう片方は知らない
  • 対策: 設計判断は CLAUDE.md か docs/ に書いておき、全 worktree が 同じベースから派生していれば自然に共有される。worktree 限定の指示は その worktree の Claude にだけ伝える

「どの worktree で何を頼んだか分からなくなる」

  • 並列を増やしすぎたときの典型的な症状
  • 対策: 2タスクから始める。Conductor の worktree 名に「何のためか」を 含めておく(feature-login-form のように)

並列開発を進める上での心構え

  • レビューするとき、複数 PR が同時に飛んでくるので「ベースの develop(hotfix なら main)がいつ時点か」を意識する。後発の PR は最新の取り込み先を反映してから見る方が事故が少ない
  • 並列にしすぎると自分のレビュー帯域がパンクする。同時に走らせる本数は、 自分が責任を持って見られる範囲に収める
  • 走らせっぱなしの Claude セッションはコストとして積み上がるので、 終わったら止める/削除する
  • Conductor の Scripts / Actions はチームで共有できる資産。良い Action ができたら他のメンバーにも展開する

チートシート

# Conductor で worktree 作成 → Setup Script が自動実行
#   make setup && make up(コンテナ作成、依存インストール、開発サーバー起動)
# .env を編集してポートとプロジェクト名を採番(必要なら再起動)
# 作業終了時
# Conductor で worktree アーカイブ → Archive Script が自動実行
#   make down(コンテナ削除、開発サーバー停止)

Makefile の最低限の例

setup:
	npm ci
	docker compose build
up:
	docker compose up -d
	npm run dev
down:
	docker compose down -v

次に試したいこと(調査中)

Claude を Loop 処理で回す

並列 worktree でいったん「複数タスクを同時に進められる」状態には なった。次は 各 worktree の Claude を Loop 処理で回す ことを 試したい。

イメージはこんな感じ。

  • Claude にタスクを投げて、出力を待つだけでなく、計画 → 実装 → セルフテスト → 修正 のループを Claude 自身に回させる
  • worktree N 本 × ループ N 周 の組み合わせで、人間が介入する密度を さらに下げる
  • 人間は「ループの開始指示」と「ループ終了時のレビュー」だけに集中

検討中の論点:

  • 暴走を止める仕組み
    • 最大反復回数(例: 5周回ってもテストが通らなければ強制終了)
    • コスト上限(1タスクあたりのトークン消費の天井)
    • 明示的な停止条件(テスト全通過、lint クリーン等)
  • ループ中に Claude が壊した状態を検知する方法(テスト、lint、 型チェックをループの停止判定に組み込む)

PR レビューの分担を見直す

並列で PR が量産されるようになると、人間のレビュー帯域がボトルネックに なる。なのでレビューの分担自体を見直したい。

  • ロジック部分は AI に任せる: 型・テスト・lint・命名・実装の 妥当性チェックなど、機械的に検証できる領域
  • 人間はドメイン部分だけを見る: 仕様との整合、UX 判断、ビジネス ロジックの正しさ、エッジケースの拾い漏れなど、AI では判断しきれない 領域

これが回り始めると、worktree × Claude の並列度を上げてもレビューが 追いつく状態にできるはず。Conductor の Actions に「AI レビュー観点」を 仕込んで PR コメントとして自動投下する、みたいな運用が候補。


おわりに

worktree × Claude Code × Conductor の組み合わせで、1人で複数タスクを 同時に進められる感覚はかなり変わった。一方で「タスク1本ずつにかける 真剣さは変えない」「最初は2タスクから」という原則は守らないと、雑な レビューや迷子の worktree で逆に効率が落ちる。

同じような構成で運用している人がいたら、ハマりどころや工夫を 教えてもらえると嬉しい。


参考リンク

Conductor

Claude Code

git worktree

git-flow