git worktree の仕組みとブランチとの使い分け

要約
git worktreeはリポジトリをコピーせず複数ブランチを同時作業可能にする機能。作業ディレクトリを物理的に分け、緊急の修正や並行開発で役立ちます。
意見はこのエリアに表示されます

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) の開発に着手したい。
  • フォルダAfeature/A を開き、フォルダBfeature/B を開く。フォルダを切り替えるだけで、それぞれの作業を独立して進められる。

3. レビューやテストの実施

  • 同僚からレビュー依頼が来たプルリクエストのブランチを、ローカルでビルドして動作確認したい。
  • 今の作業フォルダを汚さずに、レビュー専用の worktree を作り、そのブランチをチェックアウトして確認する。

→ **「作業環境を分離・並行化したい」**のがworktreeの役割です。

まとめ:使い分けの判断基準

質問使う機能
「この変更を履歴として隔離したい?」ブランチ (git branch)
「今の作業を中断せずに別のブランチで作業したい?」**Worktree (git worktree)

多くの日常的な開発作業では「ブランチ」が使われますが、並行作業や緊急対応の効率を上げるために「worktree」が非常に役立ちます。

worktree で作られるディレクトリは 「仮想」ではなく、実際に存在する物理フォルダ です。
そして、Gitの内部構造を壊さないために、プロジェクトの直下ではなく、外側(兄弟ディレクトリ)に作成するのが一般的です。

具体的にどうなるか

例えば、今 my-app という Git リポジトリがあるとします。

ここで次のコマンドを打つと:

すると、my-app と同じ階層に新しいフォルダが作られます。

つまり

  • hotfix-branch/ フォルダは実際にディスク上に作られる
  • 実体はコピーではなく、HEADindex だけ個別に持っている
  • .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 です
ディスク容量はどうなる?最小限だけ増えます(実質差分のみ)
Explore More
関連記事はありません。