0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

git worktreeでAIコーディングエージェントの衝突を防ぐ6ルール — 並列開発の実務テンプレ

0
Posted at

更新日: 2026-07-23

2つのAIコーディングエージェントに別々の修正を頼んだのに、同じ作業フォルダでファイルを書き換え、片方の変更をもう片方が消してしまう。

並列化したはずが、最後は差分の考古学。これ、めっちゃもったいないですよね。

結論から言うと、AIを並列にする前に、作業場を分ける のが先です。Gitの worktree を使うと、1つのリポジトリに複数の作業ディレクトリを関連付け、別々のブランチを同時にcheckoutできます。

ただし、worktreeを作るだけでは不十分です。コードの置き場は分かれても、同じDB、同じポート、同じファイルの担当、後片付けの判断は自動では分かれません。

そこでこの記事では、AI並列開発の事故を減らす6つのルールを紹介します。

  1. 1タスクを1ブランチ・1worktreeにする
  2. 変更してよいファイルを先に分ける
  3. DB・ポート・キャッシュも分ける
  4. 終了前にclean gateを通す
  5. 依存関係の順に統合する
  6. 正規の git worktree remove で片付ける

僕はこの全体を 「並列作業境界」 と呼びます。AIごとにコード、ブランチ、実行資源、終了条件を分ける運用境界です。

まずは10分で、2つの作業場が同時に存在するところまで進めましょう。

最初に3つの用語だけ

working tree は、いま実際にファイルを編集している作業ディレクトリです。

branch は、変更履歴の行き先につける名前です。

worktree は、同じGitリポジトリへ追加する別の作業ディレクトリです。たとえるなら、同じ設計図を参照しながら、机を2つ用意する感じです。

通常の git switch は一つの机で資料を入れ替えます。git worktree は机そのものを増やします。片方で未完成の変更を広げたまま、もう片方で別のブランチを作業できる。Git公式ドキュメントも、複数のworking treeで複数branchを同時にcheckoutできる仕組みとして説明しています。

人間とAIの役割を先に分ける

担当 任せること 任せないこと
人間 タスク分割、担当ファイル、統合順、削除承認 各worktree内の単純実装
AI 担当範囲内の実装、テスト、差分要約 担当外ファイルの変更、勝手な統合・削除
Git/CI branch隔離、dirty検知、テスト、履歴 業務上どちらを先に統合するか

AIはコードを書く速度を上げられます。でも「この2タスクは同じDB migrationを触るから直列にしよう」という判断は、リポジトリ全体の意図を持つ人間の仕事です。

AIに任せる範囲を増やすほど、人間の仕事は減るのではなく、境界を設計する仕事へ移る。なんかこれ、チーム開発そのものなんですよね。

10分の初回成功: 2つの作業場を作る

メインのリポジトリで、次を実行します。main は自分の基準branchへ置き換えてください。

git fetch origin

git worktree add -b agent/api-tests ../project-agent-api origin/main
git worktree add -b agent/docs-fix ../project-agent-docs origin/main

git worktree list

これで次のように分けられます。

project/             # 人間が統合を見るメイン作業場
project-agent-api/   # AI A: APIテスト
project-agent-docs/  # AI B: ドキュメント修正

それぞれで確認します。

git -C ../project-agent-api branch --show-current
git -C ../project-agent-docs branch --show-current

agent/api-testsagent/docs-fix が別々に表示されれば、最初の成功です。まだAIを2つ起動しなくて大丈夫です。先に「ぶつからない机」が作れた。今日はそこが大事です。

なおGitは、同じbranchを別worktreeでcheckoutしようとすると既定で拒否します。ここで安易に --force を付けないでください。せっかくある衝突防止を、自分で外すことになります。

ルール1: 1タスクを1ブランチ・1worktreeにする

悪い分け方は「AI Aはフロント、AI Bはバックエンド」のような大きすぎる担当です。期間が長くなり、両方が設定ファイルや型定義へ触れ始めます。

良い分け方は、完了条件まで含む小さなタスクです。

agent/api-tests
- 変更対象: tests/api/**, src/api/validator.py
- 完了条件: 対象テストが通る
- 触らない: migrations/**, package lock

agent/docs-fix
- 変更対象: docs/**, README.md
- 完了条件: link checkerが通る
- 触らない: src/**, migrations/**

branch名、ディレクトリ、AIへの依頼を同じタスク名で揃えると、ログを見たとき迷いにくくなります。

ルール2: ファイルの所有範囲を先に分ける

worktreeはファイルを別ディレクトリへ置きますが、最後にmergeすれば同じ履歴へ戻ります。2つのAIが同じ行を変えれば、統合時の競合は残ります。

だから開始前に、allowed_pathsforbidden_paths を宣言します。

task: api-tests
allowed_paths:
  - tests/api/
  - src/api/validator.py
forbidden_paths:
  - migrations/
  - package-lock.json
  - .github/workflows/

AIには「必要なら担当外も直して」ではなく、「担当外の変更が必要なら止まり、理由だけ報告して」と渡します。止まることは失敗ではありません。境界が働いた証拠です。

プロンプト1: 作業範囲を固定する

あなたは agent/api-tests worktreeだけを担当します。
変更可能: tests/api/**, src/api/validator.py
変更禁止: migrations/**, package-lock.json, .github/workflows/**

禁止範囲の変更が必要だと判断したら、編集せず、
1. 必要な理由
2. 影響するファイル
3. 代替案
を報告して停止してください。
完了時は変更ファイル、実行テスト、未解決事項を要約してください。

ルール3: DB・ポート・キャッシュも分ける

ここがworktree記事で省略されがちなところです。

ディレクトリを分けても、両方が localhost:3000 を使えば片方は起動できません。同じテストDBへmigrationを流せば、ファイルは無傷でもデータが壊れます。

# agent/api-tests
export APP_PORT=3101
export TEST_DB_NAME=app_agent_api
export CACHE_NAMESPACE=agent_api

# agent/docs-fix
export APP_PORT=3102
export TEST_DB_NAME=app_agent_docs
export CACHE_NAMESPACE=agent_docs

分ける候補は次のとおりです。

  • HTTPポート
  • テストDB名またはschema
  • Redis key prefix
  • 一時ディレクトリ
  • Docker Compose project名
  • ブラウザのテストプロファイル

秘密情報をworktreeごとにコピーするのは避けます。.env をGitへ追加せず、既存の安全なsecret管理から必要最小限を注入してください。

ルール4: 終了前にclean gateを通す

一番怖いのは、AIの作業が終わったと思ってworktreeを消したら、未commitの修正が残っていたケースです。

Gitの status --porcelain はスクリプトで扱うための安定形式です。出力が空ならclean、1文字でもあれば未保存の変更があります。

#!/usr/bin/env bash
set -euo pipefail

target="${1:?usage: check-worktree.sh PATH}"

if [ -n "$(git -C "$target" status --porcelain)" ]; then
  echo "STOP: uncommitted changes exist in $target" >&2
  git -C "$target" status --short
  exit 1
fi

echo "OK: worktree is clean"

このコードは一時Gitリポジトリで、clean時は終了コード0、未追跡ファイル追加後は1になることを確認します。

プロンプト2: 終了レポートを作る

このworktreeの終了レポートを作ってください。
- git status --short
- git diff --stat
- 実行したテストと結果
- 変更した公開インターフェース
- 残る懸念

commit、merge、push、worktree削除は実行せず、
人間が判断できる事実だけを簡潔に出してください。

ルール5: 依存関係の順に統合する

2つのbranchがcleanでも、merge順で意味が変わることがあります。

たとえばAI AがAPIの型を追加し、AI Bがその型を使う画面を作るなら、Aが先です。逆に独立したテスト追加と文章修正なら、順番の影響は小さい。

統合前に次の3点だけ並べます。

  1. どのbranchが公開インターフェースを変えるか
  2. どのbranchがそれへ依存するか
  3. 各merge後に何のテストを回すか
1. agent/api-contract をmerge
2. API contract testを実行
3. agent/ui-client を最新mainへrebase
4. UI integration testを実行
5. 人間が公開差分を確認

プロンプト3: 統合順をレビューする

2つのbranchの差分要約から、統合順の候補を出してください。
観点:
- 公開API、schema、型、migrationの依存
- 同一ファイルの変更
- merge後に必要なテスト
- rollbackしやすさ

出力は「推奨順」「根拠」「競合候補」「人間が決める点」。
merge自体は実行しないでください。

AIは順番の候補を整理できます。でも、どちらの仕様を正とするか、migrationを本番へ出すかは人間が決めます。

ルール6: 正規のremoveで片付ける

作業ディレクトリをFinderや rm -rf で直接消すと、Git側の管理情報が残ることがあります。Git公式は、完了したlinked worktreeを git worktree remove で削除する流れを案内しています。

git worktree list
git -C ../project-agent-api status --porcelain
git worktree remove ../project-agent-api
git branch -d agent/api-tests

remove はdirtyなworktreeを既定で拒否します。ここでも、すぐ --force を付けるのではなく、何が残っているか確認してください。

もしディレクトリを手動で消して管理情報だけ残ったら、まずdry-runです。

git worktree prune --dry-run --verbose
git worktree prune --verbose

場所を手動で移動して接続が壊れた場合は git worktree repair が用意されています。推測で .git/worktrees を直接編集するより、正規コマンドから試す方が安全です。

チームで使う最小テンプレ

最初から巨大な自動化はいりません。次の順で十分です。

# 1. 作る
git worktree add -b "agent/$TASK_NAME" "../project-$TASK_NAME" origin/main

# 2. AIへ allowed / forbidden paths と完了条件を渡す

# 3. 人間が終了レポートを確認
git -C "../project-$TASK_NAME" status --short
git -C "../project-$TASK_NAME" diff --stat origin/main...HEAD

# 4. テスト・レビュー・merge後、cleanを確認して消す
git worktree remove "../project-$TASK_NAME"
git branch -d "agent/$TASK_NAME"

TASK_NAME へ外部入力をそのまま入れるスクリプトは避け、チームで許可した短い名前だけを使ってください。パスを自動生成する処理ほど、入力検証が必要です。

この方法が効かない条件

反証も置いておきます。

2つのタスクが同じファイル、同じDB migration、同じ公開APIを同時に変えるなら、worktreeを分けても本質的な競合は消えません。競合が「作業中」から「merge時」へ移るだけです。

見分け方は簡単です。両タスクの allowed_paths を並べ、重要ファイルが重なるか確認します。

  • 重ならない: 並列化しやすい
  • テストやdocsだけ重なる: 所有者を決めれば並列化できる
  • schema、migration、公開型が重なる: 直列化か、先にインターフェースを固定する

小さな1ファイル修正を2つ並列化するのも、準備と統合の方が高くつく場合があります。無料で十分な人、というより 普通の1branchで十分なタスク は確実にあります。

並列化は目的ではありません。待ち時間を減らしながら、失敗したときの影響を小さくする手段です。

よくあるトラブル

「branch is already checked out」と出る

同じbranchが別worktreeで使用中です。git worktree list で場所を確認し、別branchを作ってください。安易にforceで迂回しません。

ディレクトリを消したのにlistへ残る

git worktree prune --dry-run --verbose で対象を確認してからpruneします。

worktreeを移動したら壊れた

可能なら git worktree move を使います。手動移動後は git worktree repair を検討します。

AI同士の変更がmergeで競合する

worktreeの不具合ではなく、タスク境界が重なっています。どちらを正とするか人間が決め、次回はallowed pathsか統合順を先に固定します。

今日10分でやること

独立した小タスクを2つ選び、次のコマンドで作業場だけ作ってください。

git worktree add -b agent/task-a ../project-task-a origin/main
git worktree add -b agent/task-b ../project-task-b origin/main
git worktree list

そのあと、各タスクへ変更可能なパスを3行で書く。AIを起動するのはそこからです。

速く走らせる前に、ぶつからない場所を作る。未来の自分が差分の考古学をしなくて済むなら、明日の自分から「あざっす」が返ってくる気がします。

参考リンク(一次情報・2026-07-23確認)

生成AI活用エンジニア&3児のパパ。AI×開発の実践知を毎日発信しています → X

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?