急ぎの修正依頼が来たとき、手元のブランチは編集の途中。定番の対処は、stash、中途半端なコミット、もう1つのcloneの三択です。
git worktreeとは、1つのGitリポジトリに複数の作業ディレクトリを紐づけ、ブランチごとに別のフォルダで同時に開いておける機能です。
ただし、追加した側のフォルダを覗くと、.gitがディレクトリではなくファイルになっています。
履歴を共有しているのに、なぜブランチごとに独立して動くのか。手元で動かした出力を見ながら、その仕組みを順にたどります。
git worktreeとは?1つのリポジトリで複数ブランチを開く機能
git worktreeは、Git 2.5(2015年7月)で追加された標準機能です。追加のインストールは要りません。
Gitでは、作業ファイルが並ぶフォルダをworktree(作業ツリー)と呼びます。リポジトリを作ると最初の1つが自動でできていて、これをmain worktreeと呼びます。
git worktreeは、このフォルダをあとから何個でも増やす仕組みです。
通常のGitは作業ディレクトリが1つだけ
git initやgit cloneで作られるフォルダは1つです。ブランチを切り替えるたびに、そのフォルダの中身がまるごと入れ替わります。
作業途中のファイルがあると、checkoutは変更の衝突で止まるか、変更を抱えたまま切り替わります。
だから割り込みの修正が入ると、stash、仮コミット、もう1つのcloneのどれかを選ぶことになります。
通常のGit:フォルダは1つ
📁 app/
main → feature-a → hotfix
切り替えるたびに、同じフォルダの中身が入れ替わる。
git worktree:ブランチごとにフォルダ
📁 app/
main
📁 app-feature-a/
feature-a
📁 app-hotfix/
hotfix
切り替えず、フォルダを移動するだけ。
worktreeで解決できる3つの場面
worktreeのメリットは、今の作業を止めずに済むことです。効くのは、次の3つの場面です。
- 緊急の修正:作業中のブランチはそのまま置いて、別フォルダでhotfixを書く
- レビュー:相手のブランチを別フォルダで開き、動かしながら確認する
- 長い処理の待ち時間:ビルドやテストを回している間に、別のブランチで作業を進める
1行目で、隣のフォルダapp-hotfixに新しいブランチhotfixを作って開きます。2行目で、いま存在するworktreeの一覧を確認できます。
git worktreeの仕組み|.gitファイルと共有の境界
worktreeが別フォルダで別ブランチを動かせる原理は、リポジトリの中身を「全員で共有する部分」と「フォルダごとに持つ部分」に分けている点にあります。
共有するのはオブジェクトとブランチ、独立して持つのはHEADとindex。この境界は、.gitの中を見るとはっきりわかります。
main worktreeとlinked worktreeの違い
最初からある作業ディレクトリがmain worktree、git worktree addで追加したものがlinked worktreeです。
リポジトリの本体である.gitディレクトリを持つのは、main worktreeだけです。
.gitがファイルになり.git/worktrees/を指す
linked worktreeの.gitを開くと、ディレクトリではなく1行だけのテキストファイルです。Git 2.50.1(Apple Git)で実際に作って確認しました。
指す先の.git/worktrees/app-feature-a/には、このworktree専用の情報が入っています。
ここにobjectsはありません。commondirの../..が、共有側の本体である.git/へ戻る道です。
linked worktreeの中でgit rev-parseを実行すると、この2つの場所が別々に返ります。
前者がworktree専用の置き場、後者が全員で共有する置き場です。これが「履歴は共有、状態は独立」の正体です。
共有されるものと独立するもの
公式ドキュメントの分類を、手元の挙動と突き合わせて、図と表にします。
main worktree(app/)
独立:作業ファイル
独立:HEAD → main
独立:index
linked worktree(app-feature-a/)
独立:作業ファイル
独立:HEAD → feature-a
独立:index
▼ どちらも同じ .git/ を参照する ▼
共有:.git/
オブジェクトDB(コミットとファイルの中身)
refs/heads/*、refs/tags/*(ブランチとタグ)
config(リモートなどの設定)
ブランチ名の一覧は共有です。別のworktreeで開いているブランチには、git branchの一覧で+が付きます。
コミットは共有、HEADとindexは独立
$ (コマンド待ち)
app/(main)
HEADmain
indexC1のまま
app-feature-a/
HEADfeature-a
indexC1のまま
▼ どちらも同じ .git/ を参照 ▼
共有:.git/
objectsC1C2
refs/heads/mainC1
refs/heads/feature-aC2
※コミット名C1・C2は説明用の例です。
同じブランチを2か所で開けない理由
すでに開いているブランチを別のworktreeで開こうとすると、Gitは拒否します。
理由は、ブランチの先端が共有なのに、HEADとindexがworktreeごとに独立しているからです。
片方でコミットするとブランチが進み、もう片方のindexと作業ファイルは古いままになります。その状態でコミットすると、直前の変更を巻き戻してしまいます。
① 同じブランチを開く
worktree AとBが、どちらも main(コミットC1)を指す。
② Aでコミットする
共有の main がC2へ進む。Bの HEAD も、ブランチ経由でC2を指す。
③ Bだけ古いまま
Bのindexと作業ファイルはC1のまま。そのままコミットすると、C2の変更を巻き戻す。
--forceで回避できますが、この状態を意図して作る場面は通常ありません。
ブランチを占有せずに同じコミットを開きたいときは、git worktree add --detach ../app-tmp mainのようにdetached HEADで開きます。この形なら、mainが別のworktreeで使用中でも拒否されません。
cloneやstash、checkoutとの違い
worktreeは、clone、stash、checkoutの間を埋める道具です。何が同じで何が違うのかを、表にまとめます。
選ぶ基準は2つあります。未コミットの変更を手放せるか、履歴を重複させたくないか、です。
cloneより軽い理由
cloneは.gitを丸ごと複製するため、履歴が大きいほどディスクも時間も使います。worktreeは作業ファイルだけを増やし、履歴は1つを共有します。
git clone:履歴が2つ
📁 app/
.git/(履歴すべて)
📁 app-copy/
.git/(履歴すべて)
fetchも、フォルダごとに行う。
git worktree:履歴は1つ
📁 app/
.git/(履歴すべて)
📁 app-feature-a/
.git は1行のファイルで、上の .git/ を指す
fetchは1か所で、全フォルダに反映される。
cloneは別のリポジトリ扱いなので、fetchやブランチの更新も個別に行う必要があります。worktreeなら、1か所でfetchすれば全員に反映されます。
stashやcheckoutでは足りない場面
- stashの戻し忘れで、退避した作業が行方不明になる
- 切り替えのたびにビルド成果物や依存関係が入れ替わり、再ビルドが走る
- 2つのブランチの動作を、並べて比べられない
数分で終わる割り込みならstashで足ります。フォルダを分ける価値が出るのは、切り替えの回数が増えたときです。
Claude Codeの並列実行とworktree
AIエージェントに複数のタスクを同時に任せると、同じフォルダを2つのセッションが書き換えて衝突します。worktreeは、この衝突をフォルダを分けることで避ける手段です。
Claude Codeには、並列実行の土台としてworktreeが組み込まれています。
AIエージェントと相性がよい理由
セッションごとに作業フォルダとブランチが独立するため、ファイル編集が互いに触れ合いません。履歴は共有なので、作業が終わったあとにマージして統合できます。
公式ドキュメントによると、このコマンドは.claude/worktrees/feature-auth/にworktreeを作り、ブランチ名はworktree-feature-authになります。
サブエージェントも、isolation: worktreeを指定すれば専用のworktreeで動きます。
サブエージェントそのものの使い方は、Claude Codeサブエージェントの使い方にまとめています。
複数セッションを並べる方法はtmuxで並列実行する方法、役割を分けたエージェントを走らせる方法はAgent Teamで専門家チームを作る実践ガイドで扱っています。
worktree内のセッションを再開する手順は、セッション再開ガイドが参考になります。
Claude Codeの導入から基本操作までは、【2026年版】Claude Code使い方|導入から実践活用までが入口になります。
未コミットの変更は持ち越されない(私の失敗談)
worktreeは、コミット済みの内容から新しくチェックアウトされます。作業フォルダにある未コミットの変更は、コピーされません。この仕様で、ヒヤリとする経験をしました。
2026年9月7日、ブログ記事のリライトをClaude Codeのサブエージェントに任せたときの話です。
事前にWordPressから最新の本文を取得し、ローカルのHTMLを最新の状態に更新していました。ただし、このHTMLはgit管理下にあり、更新はコミット前でした。
サブエージェントをisolation: worktreeで起動したところ、作業の土台になったのは8月24日にコミットした古い本文です。
編集の途中で、サブエージェント自身が「本文の書き方が、取得済みの内容と食い違っている」と報告してきて、発覚しました。
実害は出ませんでした。WordPressへのアップロードが、環境の都合でたまたま失敗していたからです。アップロードが通っていたら、本番の記事が約2週間前の状態に巻き戻っていたことになります。
公式ドキュメントでは、新しいworktreeの土台は既定でリモートのデフォルトブランチ(通常はmain)とされています。設定worktree.baseRefを"head"にすると、手元のHEADに変わります。
どちらを選んでも、未コミットの変更は含まれません。
対策は単純で、worktreeを作る前に、必要な変更をコミットしておくことです。生成物や取得結果をgit管理下に置いている場合は、特に効きます。
git worktreeを使うときの注意点
新しく作ったworktreeは、コミット済みのファイルだけが並んだ、ほぼ新品のフォルダです。そう考えると、つまずきにくくなります。よくある落とし穴を2つ挙げます。
公式ドキュメントには、複数チェックアウトはまだ実験的な機能で、サブモジュール(submodule)を含むスーパープロジェクトでの利用は推奨されない、とも書かれています。
node_modulesや.envは引き継がれない
Gitで管理されていないファイルは、新しいworktreeに存在しません。node_modules、.env、ビルド成果物が該当します。依存関係のインストールは、worktreeごとにやり直します。
Claude Codeなら、プロジェクト直下の.worktreeincludeに.gitignore形式で書いたファイルを、新しいworktreeへコピーしてくれます。対象は、gitignore済みのファイルだけです。
フォルダを直接消すとpruneが必要になる
worktreeのフォルダをFinderやmvで動かしたり消したりすると、Git側の登録だけが残ります。実際に隣のフォルダへ移動してみると、一覧にprunableと出ました。
正規の手順はgit worktree removeです。未コミットの変更があると拒否され、--forceを付けたときだけ消せます。git worktree pruneは、登録だけ残った残骸を掃除するコマンドです。
フォルダを動かしたいときはgit worktree moveを使います。mvで動かしてしまった場合は、git worktree repairでGit側の登録を直せます。
手元では、mvの直後に一覧へprunableと出ましたが、repairを実行すると新しい場所で正常に表示されました。動かしたフォルダを残したいなら、pruneより先にrepairです。
git worktreeのよくある質問
git worktreeについて、検索でよく見かける疑問を、Q&A形式で7つにまとめました。
回答は、本文で実機確認した挙動と、GitおよびClaude Codeの公式ドキュメントの記述をもとにしています。仕組みの要点を確認したいときにも使えます。
git worktreeとは何ですか?
1つのGitリポジトリに複数の作業ディレクトリを紐づけ、ブランチごとに別のフォルダで同時に開ける機能です。履歴とブランチは共有し、HEADとindexはフォルダごとに独立します。
git worktreeとgit cloneの違いは何ですか?
cloneは.gitを丸ごと複製して別のリポジトリを作ります。worktreeは履歴を1つ共有したまま、作業フォルダだけを増やします。履歴の重複がなく、fetchも1か所で済みます。
同じブランチを複数のworktreeで開けますか?
通常は開けません。すでに別のworktreeで使われているブランチを指定すると、fatalエラーで拒否されます。--forceで回避できますが、HEADとindexが食い違うため、推奨されません。
worktreeを削除するにはどうしますか?
git worktree removeを使います。未コミットの変更があると拒否され、--forceを付けると削除できます。フォルダを直接消した場合は、git worktree pruneで登録の残骸を掃除します。
未コミットの変更は新しいworktreeに引き継がれますか?
引き継がれません。新しいworktreeはコミット済みの内容からチェックアウトされます。必要な変更は、worktreeを作る前にコミットしてください。
.envやnode_modulesはコピーされますか?
Gitの標準動作ではコピーされません。依存関係はworktreeごとにインストールし直します。Claude Codeでは、.worktreeincludeに書いたgitignore済みファイルを新しいworktreeへコピーできます。
git worktreeはGitのどのバージョンから使えますか?
Git 2.5(2015年7月)から使えます。現在の一般的なGitであれば、追加の設定なしで利用できます。
git worktreeの理解を整理する
急ぎの修正が来たときの三択に、4つ目の選択肢が加わります。仕組みの要点は次のとおりです。
- worktreeとは、1つのリポジトリに複数の作業ディレクトリを紐づける機能(Git 2.5以降)
- linked worktreeの
.gitはファイルで、.git/worktrees/名前/を指す - オブジェクト、ブランチ、設定は共有。HEADとindexはworktreeごとに独立
- 同じブランチは2か所で開けない
- 新しいworktreeは未コミットの変更を持たない。作る前にコミットし、依存関係や.envは別途用意する
次に割り込みの修正が飛んできたら、stashの前に、隣のフォルダを1つ増やしてみてください。
