worktreeとは、1つのリポジトリ内に、異なるブランチの作業場所(ワーキングツリー)を複数作成する仕組みです。
これにより、あるブランチで作業している状態を維持したまま、別のブランチの作業を同時に、かつ物理的に異なるディレクトリで進められるようになります。
- ブランチ (Branch)は、「履歴の枝分かれ(何の作業か)」を記録するもの
- Worktree (ワーキングツリー)は、「作業を行う場所(どのフォルダか)」を提供するもの
「ブランチ」と「worktree」の使い分け
「ブランチ」と「worktree」の使い分けは、「何をしたいか」によって明確に分かれます。基本的な考え方は、以下の通りです。
| 機能 | 目的 | いつ使うか |
|---|---|---|
| ブランチ | 開発の履歴を分ける(作業の論理的な区切り) | 新しい機能を作るとき、バグを修正するときなど、変更を隔離して残したいとき |
| Worktree | 作業環境を分ける(作業の物理的な場所) | 複数の作業を同時に進めたいときや、ブランチを切り替えずに別の作業をしたいとき |
ブランチを使うとき
ブランチは、Gitの中心的な機能であり、「この変更は一連の作業として記録しておこう」という、論理的な区切りを作るために使います。
1. 新しい機能の開発や修正を始めるとき
- 新しい機能(フィーチャー)開発を始める際 (
feature/A)。 - 本番環境のバグを修正する際 (
hotfix/B)。 - 既存のブランチから派生して、別のアイデアを試す際。
2. 作業を記録し、レビュー・統合するとき
- 作業を小さな単位でコミットとして履歴に記録するとき。
- 他のメンバーにレビューを依頼するとき(プルリクエスト/マージリクエスト)。
- 作業が完了し、
mainブランチなどの主軸の履歴に統合するとき。
→ **「変更履歴を管理・分離したい」**のがブランチの役割です。
worktree を使うとき
worktreeは、今やっている作業を中断したくないが、別のブランチでの作業をすぐに開始したいという、環境的なニーズがあるときに使います。
1. 緊急のバグ修正(ホットフィックス)
feature/Xブランチで作業中、緊急でmainのバグを直す必要が生じた。- → 今の作業をコミットしたりスタッシュしたりせずに、
worktree addで別のフォルダにhotfixブランチをチェックアウトし、すぐに修正に取り掛かる。
2. 複数の並行作業
- 機能A (
feature/A) の開発が一段落したが、レビュー待ち。その間に、機能B (feature/B) の開発に着手したい。 - → フォルダAで
feature/Aを開き、フォルダBでfeature/Bを開く。フォルダを切り替えるだけで、それぞれの作業を独立して進められる。
3. レビューやテストの実施
- 同僚からレビュー依頼が来たプルリクエストのブランチを、ローカルでビルドして動作確認したい。
- → 今の作業フォルダを汚さずに、レビュー専用の worktree を作り、そのブランチをチェックアウトして確認する。
→ **「作業環境を分離・並行化したい」**のがworktreeの役割です。
まとめ:使い分けの判断基準
| 質問 | 使う機能 |
|---|---|
| 「この変更を履歴として隔離したい?」 | ブランチ (git branch) |
| 「今の作業を中断せずに別のブランチで作業したい?」** | Worktree (git worktree) |
多くの日常的な開発作業では「ブランチ」が使われますが、並行作業や緊急対応の効率を上げるために「worktree」が非常に役立ちます。
worktree で作られるディレクトリは 「仮想」ではなく、実際に存在する物理フォルダ です。
そして、Gitの内部構造を壊さないために、プロジェクトの直下ではなく、外側(兄弟ディレクトリ)に作成するのが一般的です。
具体的にどうなるか
例えば、今 my-app という Git リポジトリがあるとします。
ここで次のコマンドを打つと:
すると、my-app と同じ階層に新しいフォルダが作られます。
つまり
hotfix-branch/フォルダは実際にディスク上に作られる- 実体はコピーではなく、
HEADやindexだけ個別に持っている .gitは本体を共有するのでリポジトリが増えるわけではない
なぜプロジェクト内に作らないのか?
理由は 「Git が内部的に誤認するのを防ぐため」 です。
.git配下に作ると Git が「不要なファイル」として掃除(prune)してしまうことがある- ツールや IDE が
.git内にあるコードを誤認識して予期せぬ動作をすることがある - Git 公式も 兄弟ディレクトリに作る方法を推奨しています
そのため、以下のような構成が推奨されます。
プロジェクト内に置く方法(非推奨)
技術的には、以下のようにプロジェクト内に作ることも可能です。
しかし、前述の通り、Gitが意図せず削除するリスクがあるため、この方法は推奨されません。
worktreeはファイルのコピーではない
| 質問 | 答え |
|---|---|
| worktree は仮想ディレクトリ? | いいえ、物理フォルダとして作られます |
| そのフォルダはプロジェクト内? | 作成は可能ですが、非推奨です |
| 一般的にはどこに作る? | プロジェクトの兄弟フォルダ(../feature-xxx)です |
worktree は「プロジェクト全体を丸ごとコピーしているわけではありません」。
見た目はコピーされたフォルダに見えますが、実際には Git の内部データを共有し、最低限の差分だけを持つ仕組みになっています。
実際にどうなっているのか?
例として、次のコマンドを実行するとします。
すると ../feature-x/ というフォルダができますが、これは
- ファイルは「その時点のブランチの内容」が展開される
- 履歴(コミットログなど)は
.git本体を共有 ../feature-x/.gitは本物ではなく「リンク情報」だけを持つ小さなファイル
コピーではない証拠
作られた worktree 内の .git ファイルの中身を確認すると、参照先が書かれていることがわかります。
つまり
- 通常の Git リポジトリではない
.git本体は 親プロジェクトと共有されている- 履歴が二重管理されるわけではない(ディスク容量をほぼ増やさない)
何が共有され、何が独立するのか?
worktree ごとに持つデータは「作業中の状態だけ」です。
| 状態 | 内容 |
|---|---|
| 共有される | Git 履歴(コミット、ブランチ、タグなど) |
| 共有される | オブジェクトデータ (.git/objects) |
| 独立する | チェックアウトされているファイルの状態 |
| 独立する | HEAD(どのブランチを見ているか) |
| 独立する | index(ステージング状態) |
わかりやすく例えると
- 通常のブランチ切り替え: 1つの作業机の上で、参照する設計図を次々に入れ替えるようなもの。
- worktree: 設計図(
.gitリポジトリ)は共有しつつ、作業机(ディレクトリ)を複数用意するようなもの。机ごとに異なる道具やメモ(作業ファイルやステージング状態)を広げられる。
巨大なプロジェクトでも軽量な理由
巨大なリポジトリ(例: 5GB)でも worktree フォルダを作るときに、5GB がまるごとコピーされるわけではありません。
共有の仕組みにより、実際に増えるディスク容量は数 MB〜数百 MB 程度です。
結論
| 質問 | 答え |
|---|---|
| プロジェクトを丸ごとコピーしている? | いいえ、していません |
| では何を共有している? | Git 履歴・オブジェクト・メタデータです |
| worktree ごとに独立しているものは? | 作業ファイル・HEAD・index です |
| ディスク容量はどうなる? | 最小限だけ増えます(実質差分のみ) |