はじめに
開発中に「緊急のバグ修正が必要になったが、今の作業を中断したくない」「複数の機能を並行して開発しながら、それぞれの動作確認をしたい」という場面に遭遇したことはありませんか。従来はgit stashで作業を退避したり、リポジトリを別途クローンしたりする方法が一般的でしたが、これらには手間や管理の煩雑さという課題がありました。
git worktreeを使えば、1つのリポジトリから複数の作業ディレクトリを作成し、異なるブランチで同時に作業できます。本記事では、git worktreeの概念と利点から、worktree add、worktree list、worktree removeの使い方、複数機能の並行開発や緊急対応時のworktree活用方法まで、実践的に解説します。
この記事を読み終えると、以下のことができるようになります。
- git worktreeの概念とメリットを理解できる
git worktree addで新しい作業ディレクトリを作成できるgit worktree listで既存のworktreeを確認できるgit worktree removeで不要なworktreeを削除できる- 複数ブランチでの同時作業を効率化できる
- 緊急対応時に既存の作業を中断せずに対応できる
実行環境と前提条件
本記事の内容は、以下の環境で動作確認を行っています。
| 項目 | 要件 |
|---|---|
| Git | 2.40以上 |
| OS | Windows 10/11、macOS 12以上、Ubuntu 22.04以上 |
| ターミナル | コマンドプロンプト、PowerShell、Terminal.app、bash等 |
| エディタ | VS Code推奨 |
前提条件として、以下の知識があることを想定しています。
- コマンドライン操作の基礎知識(
cd、ls/dir、mkdir等) - テキストエディタの基本操作
- Gitの基本コマンド(
git init、git add、git commit、git branch、git switch)の理解
Gitのバージョンは以下のコマンドで確認できます。
|
|
git worktreeとは
worktreeの概念
git worktreeは、1つのGitリポジトリに対して複数の作業ディレクトリ(working tree)を作成する機能です。通常、Gitリポジトリには1つの作業ディレクトリしかありませんが、worktreeを使うことで、同じリポジトリの異なるブランチを別々のディレクトリで同時にチェックアウトできます。
flowchart TB
subgraph main["my-project/ (メインworktree - mainブランチ)"]
M1[".git/"]
M2["src/"]
M3["..."]
end
subgraph feature["my-project-feature/ (リンクworktree - featureブランチ)"]
F1[".git (ファイル) - メインの.gitへの参照"]
F2["src/"]
F3["..."]
end
subgraph hotfix["my-project-hotfix/ (リンクworktree - hotfixブランチ)"]
H1[".git (ファイル) - メインの.gitへの参照"]
H2["src/"]
H3["..."]
end
main -.->|"履歴を共有"| feature
main -.->|"履歴を共有"| hotfix各worktreeは独立した作業ディレクトリを持ちますが、コミット履歴やブランチ情報は共有されます。リンクworktreeの.gitはディレクトリではなくファイルであり、メインworktreeの.gitディレクトリへの参照を保持しています。
git stashやリポジトリクローンとの違い
複数ブランチでの同時作業を実現する方法として、git stashやリポジトリの追加クローンもありますが、それぞれにメリット・デメリットがあります。
| 方法 | メリット | デメリット |
|---|---|---|
| git stash | 追加のディスク容量不要 | 作業の切り替えが必要、stashの管理が煩雑 |
| リポジトリクローン | 完全に独立した環境 | ディスク容量を大量に消費、同期が必要 |
| git worktree | 軽量、履歴を共有、同時作業可能 | 同じブランチを複数worktreeで開けない |
worktreeは、リポジトリのオブジェクトデータベース(.git/objects)を共有するため、クローンと比較してディスク容量の消費を大幅に抑えられます。また、git stashのように作業を退避する必要がないため、複数のブランチを同時に開いたまま作業を継続できます。
git worktreeを使うメリット
git worktreeには以下のようなメリットがあります。
- 同時作業が可能: 複数のブランチを別々のディレクトリで同時に開けるため、ブランチ切り替えの手間がなくなります
- ディスク効率が良い: オブジェクトデータベースを共有するため、追加のクローンと比較してディスク使用量が少なくなります
- 履歴の即時共有: 1つのworktreeでコミットした変更は、他のworktreeからも即座に参照できます
- ビルド成果物の分離: 各worktreeは独立した作業ディレクトリを持つため、ビルド成果物が混在しません
- 並行ビルド・テストが可能: 異なるブランチで同時にビルドやテストを実行できます
git worktree addで作業ディレクトリを作成する
基本的な使い方
git worktree addコマンドで、新しい作業ディレクトリを作成します。
|
|
既存のブランチをチェックアウトした新しいworktreeを作成する例です。
|
|
実行結果:
Preparing worktree (checking out 'feature')
HEAD is now at abc1234 Add feature implementation
ブランチ名を省略すると、パスの最後の要素がブランチ名として使用されます。
|
|
この場合、hotfixという名前のブランチがチェックアウトされます。ブランチが存在しない場合は、HEADから新しいブランチが作成されます。
新しいブランチを作成しながらworktreeを追加する
-bオプションを使用すると、新しいブランチを作成しながらworktreeを追加できます。
|
|
実行結果:
Preparing worktree (new branch 'feature/login')
HEAD is now at def5678 Initial commit
このコマンドは以下の処理を行います。
mainブランチを起点としてfeature/loginブランチを作成../login-featureディレクトリを作成- 新しいworktreeで
feature/loginブランチをチェックアウト
-Bオプションを使用すると、既存のブランチを強制的にリセットして作成できます。
|
|
detached HEAD状態でworktreeを作成する
特定のコミットやタグをチェックアウトしたい場合は、-d(--detach)オプションを使用します。
|
|
実行結果:
Preparing worktree (detached HEAD abc1234)
HEAD is now at abc1234 Release v1.0.0
detached HEAD状態のworktreeは、特定のバージョンのテストや調査に便利です。
リモートブランチを追跡するworktreeを作成する
リモートブランチを追跡する新しいブランチを作成してworktreeを追加する場合は、以下のようにします。
|
|
worktree.guessRemote設定を有効にすると、リモートブランチの自動追跡が可能になります。
|
|
git worktree listで既存のworktreeを確認する
worktree一覧の表示
git worktree listコマンドで、現在のリポジトリに関連付けられたすべてのworktreeを一覧表示できます。
|
|
実行結果:
/home/user/projects/my-project abc1234 [main]
/home/user/projects/my-project-feature def5678 [feature/login]
/home/user/projects/my-project-hotfix ghi9012 [hotfix/urgent-fix]
出力には以下の情報が含まれます。
- worktreeのパス
- 現在のHEADのコミットハッシュ(短縮形)
- チェックアウトされているブランチ名(detached HEADの場合は
(detached HEAD))
詳細情報の表示
--verboseオプションを使用すると、ロック状態や削除可能かどうかなどの詳細情報が表示されます。
|
|
実行結果:
/home/user/projects/my-project abc1234 [main]
/home/user/projects/my-project-feature def5678 [feature/login]
/home/user/projects/my-project-locked ghi9012 [hotfix]
locked: 作業中のため削除禁止
スクリプト向けのporcelain形式
スクリプトで処理しやすい形式で出力するには、--porcelainオプションを使用します。
|
|
実行結果:
worktree /home/user/projects/my-project
HEAD abc1234abc1234abc1234abc1234abc1234abc1234
branch refs/heads/main
worktree /home/user/projects/my-project-feature
HEAD def5678def5678def5678def5678def5678def5678
branch refs/heads/feature/login
git worktree removeで不要なworktreeを削除する
基本的な削除方法
作業が完了したworktreeは、git worktree removeコマンドで削除します。
|
|
実行結果:
(正常終了時は出力なし)
削除が成功したか確認するには、git worktree listを実行します。
削除時の注意点
git worktree removeは、以下の条件を満たすworktreeのみ削除できます。
- 未コミットの変更がない(クリーンな状態)
- 未追跡のファイルがない
- ロックされていない
変更がある状態で削除しようとすると、エラーが発生します。
|
|
エラー出力:
fatal: '../my-project-dirty' contains modified or untracked files, use --force to delete it
強制削除
未コミットの変更や未追跡ファイルがあるworktreeを強制的に削除するには、--forceオプションを使用します。
|
|
ロックされたworktreeを強制削除する場合は、--forceを2回指定します。
|
|
手動削除した場合のクリーンアップ
worktreeディレクトリをrmコマンドなどで手動削除した場合、Gitの管理情報が残ったままになります。この場合はgit worktree pruneで不要な情報をクリーンアップします。
|
|
--dry-runオプションで、実際には削除せずに何が削除されるかを確認できます。
|
|
実行結果:
Removing worktrees/my-project-feature: gitdir file points to non-existent location
git worktree lockでworktreeを保護する
worktreeのロック
外部ドライブやネットワーク共有上にworktreeを配置している場合など、一時的にアクセスできなくなる可能性がある場合は、git worktree lockでロックすることで誤削除を防止できます。
|
|
ロック状態はgit worktree list --verboseで確認できます。
|
|
実行結果:
/home/user/projects/my-project abc1234 [main]
/media/usb/my-project-usb def5678 [feature/mobile]
locked: USBドライブに保存中
worktreeのロック解除
作業が完了したらロックを解除します。
|
|
複数機能の並行開発でのworktree活用
実践例: 2つの機能を同時に開発する
複数の機能ブランチで同時に開発を進める典型的なワークフローを紹介します。
|
|
実行結果:
/home/user/projects/my-app abc1234 [main]
/home/user/projects/my-app-auth abc1234 [feature/user-auth]
/home/user/projects/my-app-dashboard abc1234 [feature/dashboard]
これで3つのディレクトリがそれぞれ独立した作業ディレクトリとして利用できます。
|
|
VS Codeでの活用
VS Codeでは、各worktreeを別々のウィンドウで開くことで、複数のブランチを同時に編集できます。
|
|
マルチルートワークスペース機能を使用すると、1つのウィンドウで複数のworktreeを管理することも可能です。
並行ビルドとテストの実行
各worktreeは独立したディレクトリを持つため、同時にビルドやテストを実行できます。
|
|
ビルド成果物(node_modules、distなど)が分離されるため、ブランチ間で干渉することがありません。
緊急対応時のworktree活用
実践例: 作業を中断せずにhotfixを適用する
git worktreeが最も威力を発揮するのは、緊急のバグ修正が必要になった場面です。従来の方法と比較してみましょう。
従来の方法(git stash使用):
|
|
worktreeを使った方法:
|
|
worktreeを使用することで、以下のメリットがあります。
- 現在の作業状態(ステージング、未保存の変更など)をそのまま維持できる
- stashの取り違えや適用忘れのリスクがない
- 複雑なリファクタリング中でも安全に緊急対応できる
本番環境のデバッグ
本番環境で発生した問題を調査する際にも、worktreeは便利です。
|
|
git worktreeの注意点とベストプラクティス
同じブランチを複数のworktreeで開けない
Gitの制約として、同じブランチを複数のworktreeで同時にチェックアウトすることはできません。
|
|
エラー出力:
fatal: 'main' is already checked out at '/home/user/projects/my-app'
これを回避するには、--forceオプションを使用しますが、意図しない競合が発生する可能性があるため推奨しません。
|
|
worktreeの管理場所
worktreeは任意の場所に作成できますが、以下のようなディレクトリ構成が推奨されます。
projects/
├── my-app/ <- メインworktree
├── my-app-feature-a/ <- リンクworktree
├── my-app-feature-b/ <- リンクworktree
└── my-app-hotfix/ <- リンクworktree
メインworktreeと同じ階層に配置することで、管理が容易になります。
定期的なクリーンアップ
使用しなくなったworktreeは速やかに削除することを推奨します。
|
|
サブモジュールとの併用
サブモジュールを含むリポジトリでworktreeを使用する場合は注意が必要です。現時点(Git 2.40以降)では、サブモジュールのサポートは不完全であり、予期しない動作が発生する可能性があります。サブモジュールを含むリポジトリでは、別途クローンを作成する方が安全な場合があります。
まとめ
git worktreeは、複数ブランチでの同時作業を効率化する強力な機能です。本記事で紹介した内容をまとめます。
| コマンド | 用途 |
|---|---|
git worktree add <パス> [<ブランチ>] |
新しいworktreeを作成 |
git worktree add -b <新ブランチ> <パス> [<起点>] |
新しいブランチを作成してworktreeを追加 |
git worktree list |
worktree一覧を表示 |
git worktree remove <worktree> |
worktreeを削除 |
git worktree prune |
手動削除されたworktreeの参照をクリーンアップ |
git worktree lock <worktree> |
worktreeをロックして保護 |
git worktree unlock <worktree> |
worktreeのロックを解除 |
git worktreeは以下のような場面で特に効果を発揮します。
- 複数の機能を並行して開発する場合
- 緊急のバグ修正が必要になった場合
- 異なるバージョンでのテストやデバッグが必要な場合
- レビュー中のブランチを確認しながら自分の作業を続けたい場合
git stashやリポジトリの追加クローンと比較して、worktreeはより効率的で安全な複数ブランチの同時作業を実現します。ぜひ日々の開発ワークフローに取り入れてみてください。