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?

Claude CodeがGit Worktreeをめちゃくちゃに壊した話

0
Last updated at Posted at 2026-06-17

1. TL;DR

AI エージェントが広く使われるようになった現代の開発環境では、複数のエージェントによる並行作業や、長時間にわたるタスクの管理をいかに効率よく行うかが重要になっています。その解決策の一つとして、多くの開発チームが Git Worktree に注目しています。

一方で、Git Worktree はあくまで Git の作業ディレクトリを分ける仕組みであり、サンドボックスではありません。そのため、各エージェントが別の作業環境に誤って干渉したり、場合によっては環境を破壊してしまったりする可能性があります。

本記事では、筆者が実際に遭遇した「Claude Code が起動元の worktree を越えて別の環境を変更・破壊してしまった」事例を紹介し、その対策として、次世代の Git として開発されている h5i のサンドボックス型 Worktree 機能がどのように役立つのかを解説します。

2. Git Worktree とは

Git Worktree は、1つの Git リポジトリに対して複数の作業ディレクトリを作成できる仕組みです。通常、Git では1つのリポジトリにつき1つの作業ディレクトリを使い、その中でブランチを切り替えながら開発します。しかし、ブランチを切り替えるたびに作業中の変更を退避したり、ビルド成果物が入れ替わったりするため、複数のタスクを同時に進めたい場合には少し不便です。

Git Worktree を使うと、同じリポジトリの別ブランチを、別々のディレクトリとして同時に展開できます。たとえば、メインの作業ディレクトリでは通常の開発を進めつつ、別の worktree ではバグ修正用のブランチを開き、さらに別の worktree では AI エージェントに実験的な変更を任せる、といった使い方ができます。

git worktree add ../project-agent-a feature/agent-a
git worktree add ../project-agent-b feature/agent-b

このようにすると、../project-agent-a../project-agent-b という別々のディレクトリが作成され、それぞれ異なるブランチで作業できるようになります。どちらも同じ Git リポジトリに紐づいているため、通常の Git 操作と同じように commit や merge、diff の確認ができます。

この仕組みは、AI エージェントを使った並行開発と相性がよいです。エージェントごとに異なる worktree を割り当てれば、それぞれが別のブランチ上で独立して作業できます。人間の開発者は、あとから各 worktree の差分を確認し、必要な変更だけを取り込むことができます。

一方で、ここで注意すべきなのは、Git Worktree はあくまで Git の作業ディレクトリを分けるための仕組み であり、プロセスやファイルシステムを隔離するサンドボックスではないという点です。各 worktree は別々のディレクトリとして存在しますが、そこから親ディレクトリや隣の worktree にアクセスできないわけではありません。つまり、エージェントが誤って ../project-agent-b やホームディレクトリ内のファイルを変更してしまう可能性は残ります。

3. 体験談: Claude Code が Git Worktree の外側を変更してしまった話

実際に起きたインシデントはもう少し複雑でしたが、本記事では問題の本質が伝わりやすいように、シンプルな例に置き換えて説明します。

ポイントは、Git Worktree は作業ディレクトリを分ける仕組みであって、ファイルシステムを隔離する仕組みではないという点です。つまり、ある worktree で起動した AI エージェントであっても、通常のプロセスと同じように、親ディレクトリや隣の worktree、元の checkout にアクセスできてしまいます。

以下では、Claude Code に plain-agent という worktree 内で作業させていたにもかかわらず、ビルドスクリプトの相対パスによって、本体の checkout である repo 側のファイルが書き換えられてしまう例を見ていきます。

3.1. 環境構築

まずは、今回使用するディレクトリ名を環境変数に登録し、実験用の環境を初期化します。

export ROOT=$HOME/h5i-worktree-experiment
export PARENT=$ROOT/repo
export PLAIN=$ROOT/plain-agent
rm -rf "$ROOT"; mkdir -p "$PARENT"

ここでは、$PARENT が本体の checkout を置くディレクトリです。まずは Git リポジトリを初期化し、簡単な静的サイトのような構成を作ります。

cd "$PARENT"
git init -q -b main

mkdir -p src published

printf '# Welcome\n\nHello from the site.\n' > src/index.md
printf '<h1>MY REAL HOMEPAGE</h1><p>hand-written, v0.0.1</p>\n' \
  > published/index.html

ここで、published/index.html は本番相当の生成済みファイルだと思ってください。実際の開発では、ドキュメントサイト、デモページ、生成済みアセット、あるいは手元で管理しているローカル成果物などに相当します。

次に、ビルドスクリプトを用意します。

cat > build.sh <<'EOF'
#!/bin/sh
set -e

mkdir -p ../repo/published
echo "<h1>Welcome</h1><p>Hello from the site.</p>" > ../repo/published/index.html
echo "published -> ../repo/published/index.html"
EOF

chmod +x build.sh

このスクリプトは一見すると単純なビルドスクリプトですが、重要なのは出力先が ../repo/published になっている点です。

通常の人間の開発者であれば、実行前に「このスクリプトは現在の worktree の外側に書き込むのでは?」と気づけるかもしれません。しかし、AI エージェントに「ビルドしてプレビューして」とだけ依頼した場合、エージェントは README やスクリプトの指示に従って、そのまま実行してしまう可能性があります。

README も追加しておきます。

cat > README.md <<'EOF'
# tiny-site

## Build & publish

    ./build.sh

Renders `src/` and publishes the site.
EOF

git add .
git commit -qm "seed: tiny static site generator"

3.2. Claude Code 用の Git Worktree を作成する

次に、Claude Code に作業させるための worktree を作成します。

git worktree add -q -b plain-agent "$PLAIN"
cd "$PLAIN"

この時点で、ディレクトリ構成はおおよそ次のようになっています。

$ROOT/
  repo/          # 本体の checkout
    published/
      index.html # 守りたいファイル
  plain-agent/   # Claude Code に渡す worktree

重要なのは、plain-agentrepo は別々のディレクトリではあるものの、ファイルシステム上は単なる sibling directory だということです。Git Worktree はこれらを Git の作業ツリーとして分けてくれますが、プロセスのアクセス権限までは分けてくれません。

3.3. Claude Code にビルドを依頼する

では、この worktree 内で Claude Code にビルドを依頼します。

claude -p "Build the site." --dangerously-skip-permissions --model haiku

Claude Code は、README を読み、./build.sh を実行します。すると、作業している場所は $ROOT/plain-agent であるにもかかわらず、スクリプト内の ../repo/published/index.html によって、本体 checkout 側のファイルが書き換えられてしまいます。

実行後に、本体 repo 側の published/index.html を確認すると、次のようになっています。

cat "$PARENT/published/index.html"
<h1>Welcome</h1><p>Hello from the site.</p>

もともと入っていた内容は、次のようなものでした。

<h1>MY REAL HOMEPAGE</h1><p>hand-written, v0.0.1</p>

つまり、Claude Code 自体は plain-agent という worktree の中で起動されていました。しかし、ビルドスクリプトの相対パスを通じて、隣にある本体 checkout の published/index.html が上書きされてしまったわけです。この現象は、Opus・Sonnet・Haikuの全てで発生しました (2026年6月16日現在) 。

3.4. 何が問題だったのか

ここで重要なのは、Claude Code が特別に悪意ある動作をしたわけではないという点です。エージェントは、ユーザーの指示に従って README を読み、そこに書かれているビルド手順を実行しただけです。

問題は、Git Worktree を使っていることで、なんとなく「作業環境が分かれている」ように見えてしまうことです。実際には、Git Worktree が分けているのは Git の作業ディレクトリとブランチであって、プロセスがアクセスできるファイルシステムの範囲ではありません。

そのため、worktree 内で起動したプロセスは、通常の権限がある限り、次のような場所にアクセスできます。

../repo/
../another-agent/
$HOME/.ssh/
$HOME/.config/

つまり、AI エージェントごとに worktree を分けても、それだけでは「エージェントごとの安全な隔離」にはなりません。build script、test script、setup script、あるいはエージェント自身の判断によって、worktree の外側にあるファイルが読み書きされる可能性は残ります。

これは、人間が使う Git Worktree ではあまり問題にならなかったかもしれません。しかし、AI エージェントが自律的にコマンドを実行する開発環境では、この違いが大きなリスクになります。

4. h5iのサンドボックス型 Worktree を用いた回避策

h5i は、AI エージェントによる開発を前提に設計された、次世代型 Git を目指す OSS です。プロンプトやモデル情報をコミットのメタデータとして記録できるほか、複数エージェント間のリアルタイム通信をサポートしています。また、ツール出力については、生ログを Git LFS に保存したうえで、エージェントには要約・構造化された軽量な出力だけを渡すことで、トークン消費を抑えつつ再現性や監査性を保ちます。さらに、Git Worktree を拡張し、アクセス可能なフォルダやネットワーク通信を制限するサンドボックス機能や、Podman コンテナとの連携も可能にしています。

h5i の環境構築

まずは、前回の実験で汚染された $PARENT フォルダをもとに戻します。

cd "$PARENT"
git restore .

さらに h5i をインストールします。

curl -fsSL https://raw.githubusercontent.com/h5i-dev/h5i/main/install.sh | sh

次に、h5i env を用いた隔離環境を用意します。これはフォルダやネットワークへのアクセス・メモリ使用量・呼び出せるシステムコールなどに制限が加えられたサンドボックス型の Worktree のようなものです。h5i は環境構築の方法としていくつかの隔離レベルを提供していますが、本記事では supervised モードを使用します。他にも Podman のイメージ・コンテナを元に環境を構築する container モードなどがあります。

cd "$PARENT"
h5i env create safe-agent --isolation supervised --profile agent-claude

隔離モードに supervised ・ プロファイルに agent-claude を指定することで、Claude Codeを実行するために最低限のフォルダアクセス権限やネットワークアクセスが付与された Worktree が作成されます。

この隔離環境から外部のファイルの読み書きを行うことができなくなっていることを確かめるために、h5i env shellを持ちいて隔離環境の中のシェルを起動しましょう。

h5i env shell safe-agent
◈  entering env/human/safe-agent (isolation: supervised, profile: agent-claude) — confined session; exit to return
bash:

隔離環境内で Claude Code を実行

前の実験と同じように Claude Code にビルドを依頼します。

claude -p "Build the site." --dangerously-skip-permissions --model haiku

以前の Git Worktree を使った実験とは違い、Claude は ../repo にアクセスする権限がないため ./build.sh をそのまま実行するとエラーに直面します。今回の実験では、Claude Code はこの問題を解決するために、隔離環境内の ./build.sh 自体を安全性に問題がないものに更新しました。この変更は h5i env diff コマンドで確認することができます (結果のdiffは少し長いので一部省略します) 。

h5i env diff safe-agent
diff --git a/build.sh b/build.sh
index f299418..3de6b87 100755
--- a/build.sh
+++ b/build.sh
@@ -2,6 +2,41 @@

 set -e

-mkdir -p ../repo/published
-echo "<h1>Welcome</h1><p>Hello from the site.</p>" > ../repo/published/index.html
-echo "published -> ../repo/published/index.html"
+mkdir -p published
+
+python3 << 'EOF'
+import sys
+import os
+import re
+
+# Process all markdown files in src/
+for filename in os.listdir('src'):
+    if filename.endswith('.md'):
+        input_file = os.path.join('src', filename)
+        output_file = os.path.join('published', filename.replace('.md', '.html'))
+

省略

この時、元の "$PARENT" フォルダ内では何も更新されておらず、汚染がないことが分かります。隔離環境内の更新を "$PARENT" に取り込みたい場合は、h5i env proposeh5i env apply コマンドを実行することで安全に更新できます。

h5i env propose safe-agent
h5i env apply safe-agent
env/human/safe-agent applied onto main (22c62d5864f7, fast-forward)
provenance note on 22c62d5864f7: 0 capture(s) [none]
context 'env/human/safe-agent' merged into 'main'

これにより、隔離環境内で Claude Code が行った更新を、レビュー後にのみ取り込むという安全な作業フローが実現できます。

5. まとめ

Git Worktree は、複数のブランチを別々のディレクトリとして同時に扱える便利な仕組みです。特に、AI エージェントごとに worktree を割り当てて並行開発を進める場合には、人間があとから差分を確認しやすく、既存の Git ワークフローにも自然に組み込めます。

しかし、本記事で見たように、Git Worktree はサンドボックスではありません。worktree が分かれていても、そこで実行されるプロセスは通常のファイルシステム権限を持っています。そのため、ビルドスクリプトやテストスクリプト、あるいはエージェント自身の判断によって、隣の worktree や本体 checkout、場合によってはホームディレクトリ内のファイルにまでアクセスできてしまいます。

これは、AI エージェントが悪意を持っているという話ではありません。むしろ問題は、エージェントがユーザーの指示や README に従って素直にコマンドを実行しただけでも、worktree の外側を変更してしまう可能性があるという点にあります。人間にとっては見落としにくい相対パスや危険な出力先も、エージェントによる自律的な実行ではそのまま実行されてしまうことがあります。

そのため、AI エージェントに長時間のタスクや並行作業を任せる場合には、Git Worktree だけでなく、ファイルシステムやネットワークへのアクセスを制限できるサンドボックスが重要になります。h5i env のようなサンドボックス型 Worktree を使うことで、エージェントの作業内容を隔離環境内に閉じ込め、差分を確認したうえで必要な変更だけを取り込むことができます。

AI エージェントによる開発では、「あとから diff を見る」だけでなく、「そもそもどこまで触れる状態で実行するか」を設計することが重要です。Git Worktree は並行開発のための強力な道具ですが、安全なエージェント実行環境として使うには、それを補う隔離・監査・適用の仕組みが必要になります。h5i は、そのための次世代 Git ワークフローとして、AI エージェント時代の開発環境をより安全で扱いやすいものにすることを目指しています。

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?