はじめに

開発中に「緊急のバグ修正が必要になったが、今の作業を中断したくない」「複数の機能を並行して開発しながら、それぞれの動作確認をしたい」という場面に遭遇したことはありませんか。従来はgit stashで作業を退避したり、リポジトリを別途クローンしたりする方法が一般的でしたが、これらには手間や管理の煩雑さという課題がありました。

git worktreeを使えば、1つのリポジトリから複数の作業ディレクトリを作成し、異なるブランチで同時に作業できます。本記事では、git worktreeの概念と利点から、worktree addworktree listworktree 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推奨

前提条件として、以下の知識があることを想定しています。

  • コマンドライン操作の基礎知識(cdls/dirmkdir等)
  • テキストエディタの基本操作
  • Gitの基本コマンド(git initgit addgit commitgit branchgit switch)の理解

Gitのバージョンは以下のコマンドで確認できます。

1
git --version

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. 同時作業が可能: 複数のブランチを別々のディレクトリで同時に開けるため、ブランチ切り替えの手間がなくなります
  2. ディスク効率が良い: オブジェクトデータベースを共有するため、追加のクローンと比較してディスク使用量が少なくなります
  3. 履歴の即時共有: 1つのworktreeでコミットした変更は、他のworktreeからも即座に参照できます
  4. ビルド成果物の分離: 各worktreeは独立した作業ディレクトリを持つため、ビルド成果物が混在しません
  5. 並行ビルド・テストが可能: 異なるブランチで同時にビルドやテストを実行できます

git worktree addで作業ディレクトリを作成する

基本的な使い方

git worktree addコマンドで、新しい作業ディレクトリを作成します。

1
2
# 基本構文
git worktree add <パス> [<ブランチ>]

既存のブランチをチェックアウトした新しいworktreeを作成する例です。

1
2
# featureブランチを../my-project-featureディレクトリにチェックアウト
git worktree add ../my-project-feature feature

実行結果:

Preparing worktree (checking out 'feature')
HEAD is now at abc1234 Add feature implementation

ブランチ名を省略すると、パスの最後の要素がブランチ名として使用されます。

1
2
# パス名からブランチ名を推測して作成
git worktree add ../hotfix

この場合、hotfixという名前のブランチがチェックアウトされます。ブランチが存在しない場合は、HEADから新しいブランチが作成されます。

新しいブランチを作成しながらworktreeを追加する

-bオプションを使用すると、新しいブランチを作成しながらworktreeを追加できます。

1
2
# 新しいブランチ「feature/login」を作成してworktreeを追加
git worktree add -b feature/login ../login-feature main

実行結果:

Preparing worktree (new branch 'feature/login')
HEAD is now at def5678 Initial commit

このコマンドは以下の処理を行います。

  1. mainブランチを起点としてfeature/loginブランチを作成
  2. ../login-featureディレクトリを作成
  3. 新しいworktreeでfeature/loginブランチをチェックアウト

-Bオプションを使用すると、既存のブランチを強制的にリセットして作成できます。

1
2
# 既存ブランチを強制リセットして作成
git worktree add -B feature/login ../login-feature main

detached HEAD状態でworktreeを作成する

特定のコミットやタグをチェックアウトしたい場合は、-d--detach)オプションを使用します。

1
2
# 特定のコミットをdetached HEADでチェックアウト
git worktree add -d ../v1.0-test v1.0.0

実行結果:

Preparing worktree (detached HEAD abc1234)
HEAD is now at abc1234 Release v1.0.0

detached HEAD状態のworktreeは、特定のバージョンのテストや調査に便利です。

リモートブランチを追跡するworktreeを作成する

リモートブランチを追跡する新しいブランチを作成してworktreeを追加する場合は、以下のようにします。

1
2
# リモートブランチを追跡するブランチを作成
git worktree add --track -b feature/api ../api-feature origin/feature/api

worktree.guessRemote設定を有効にすると、リモートブランチの自動追跡が可能になります。

1
2
3
4
5
# 設定を有効化
git config worktree.guessRemote true

# リモートに同名のブランチがあれば自動で追跡
git worktree add ../api-feature

git worktree listで既存のworktreeを確認する

worktree一覧の表示

git worktree listコマンドで、現在のリポジトリに関連付けられたすべてのworktreeを一覧表示できます。

1
git worktree list

実行結果:

/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オプションを使用すると、ロック状態や削除可能かどうかなどの詳細情報が表示されます。

1
git worktree list --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オプションを使用します。

1
git worktree list --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コマンドで削除します。

1
git worktree remove ../my-project-feature

実行結果:

(正常終了時は出力なし)

削除が成功したか確認するには、git worktree listを実行します。

削除時の注意点

git worktree removeは、以下の条件を満たすworktreeのみ削除できます。

  • 未コミットの変更がない(クリーンな状態)
  • 未追跡のファイルがない
  • ロックされていない

変更がある状態で削除しようとすると、エラーが発生します。

1
git worktree remove ../my-project-dirty

エラー出力:

fatal: '../my-project-dirty' contains modified or untracked files, use --force to delete it

強制削除

未コミットの変更や未追跡ファイルがあるworktreeを強制的に削除するには、--forceオプションを使用します。

1
git worktree remove --force ../my-project-dirty

ロックされたworktreeを強制削除する場合は、--forceを2回指定します。

1
git worktree remove --force --force ../my-project-locked

手動削除した場合のクリーンアップ

worktreeディレクトリをrmコマンドなどで手動削除した場合、Gitの管理情報が残ったままになります。この場合はgit worktree pruneで不要な情報をクリーンアップします。

1
git worktree prune

--dry-runオプションで、実際には削除せずに何が削除されるかを確認できます。

1
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でロックすることで誤削除を防止できます。

1
git worktree lock ../my-project-usb --reason "USBドライブに保存中"

ロック状態はgit worktree list --verboseで確認できます。

1
git worktree list --verbose

実行結果:

/home/user/projects/my-project              abc1234 [main]
/media/usb/my-project-usb                   def5678 [feature/mobile]
	locked: USBドライブに保存中

worktreeのロック解除

作業が完了したらロックを解除します。

1
git worktree unlock ../my-project-usb

複数機能の並行開発でのworktree活用

実践例: 2つの機能を同時に開発する

複数の機能ブランチで同時に開発を進める典型的なワークフローを紹介します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# メインworktreeでmainブランチをチェックアウト中と仮定
cd ~/projects/my-app

# 機能A用のworktreeを作成
git worktree add -b feature/user-auth ../my-app-auth main
# 機能B用のworktreeを作成  
git worktree add -b feature/dashboard ../my-app-dashboard main

# worktree一覧を確認
git worktree list

実行結果:

/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つのディレクトリがそれぞれ独立した作業ディレクトリとして利用できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 機能Aの開発
cd ~/projects/my-app-auth
# 認証機能の実装...
git add .
git commit -m "feat: ユーザー認証機能を実装"

# 機能Bの開発(別のターミナルで)
cd ~/projects/my-app-dashboard
# ダッシュボード機能の実装...
git add .
git commit -m "feat: ダッシュボード画面を実装"

VS Codeでの活用

VS Codeでは、各worktreeを別々のウィンドウで開くことで、複数のブランチを同時に編集できます。

1
2
3
# 別々のVS Codeウィンドウで開く
code ~/projects/my-app-auth
code ~/projects/my-app-dashboard

マルチルートワークスペース機能を使用すると、1つのウィンドウで複数のworktreeを管理することも可能です。

並行ビルドとテストの実行

各worktreeは独立したディレクトリを持つため、同時にビルドやテストを実行できます。

1
2
3
4
5
6
7
# ターミナル1: 機能Aのテスト
cd ~/projects/my-app-auth
npm test

# ターミナル2: 機能Bのテスト(同時実行)
cd ~/projects/my-app-dashboard
npm test

ビルド成果物(node_modulesdistなど)が分離されるため、ブランチ間で干渉することがありません。

緊急対応時のworktree活用

実践例: 作業を中断せずにhotfixを適用する

git worktreeが最も威力を発揮するのは、緊急のバグ修正が必要になった場面です。従来の方法と比較してみましょう。

従来の方法(git stash使用):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 現在の作業を退避
git stash push -m "feature作業中"
# mainに切り替え
git switch main
# hotfixブランチを作成して修正
git switch -c hotfix/critical-bug
# ... 修正作業 ...
git commit -a -m "fix: 重大なバグを修正"
# mainにマージ
git switch main
git merge hotfix/critical-bug
git push
# 元の作業に戻る
git switch feature/my-feature
git stash pop

worktreeを使った方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 現在の作業を中断せずにhotfix用worktreeを作成
git worktree add -b hotfix/critical-bug ../my-app-hotfix main

# 別のターミナルでhotfixを適用
cd ../my-app-hotfix
# ... 修正作業 ...
git commit -a -m "fix: 重大なバグを修正"
git switch main
git merge hotfix/critical-bug
git push

# worktreeを削除
cd ../my-app
git worktree remove ../my-app-hotfix

# 元のworktreeでは作業が継続できている

worktreeを使用することで、以下のメリットがあります。

  • 現在の作業状態(ステージング、未保存の変更など)をそのまま維持できる
  • stashの取り違えや適用忘れのリスクがない
  • 複雑なリファクタリング中でも安全に緊急対応できる

本番環境のデバッグ

本番環境で発生した問題を調査する際にも、worktreeは便利です。

1
2
3
4
5
6
7
8
9
# 本番環境にデプロイされているタグをチェックアウト
git worktree add -d ../my-app-prod-debug v2.3.1

cd ../my-app-prod-debug
# 本番と同じ状態でデバッグ...

# 調査完了後に削除
cd ../my-app
git worktree remove ../my-app-prod-debug

git worktreeの注意点とベストプラクティス

同じブランチを複数のworktreeで開けない

Gitの制約として、同じブランチを複数のworktreeで同時にチェックアウトすることはできません。

1
git worktree add ../my-app-main2 main

エラー出力:

fatal: 'main' is already checked out at '/home/user/projects/my-app'

これを回避するには、--forceオプションを使用しますが、意図しない競合が発生する可能性があるため推奨しません。

1
2
# 非推奨: 同じブランチを強制的にチェックアウト
git worktree add --force ../my-app-main2 main

worktreeの管理場所

worktreeは任意の場所に作成できますが、以下のようなディレクトリ構成が推奨されます。

projects/
├── my-app/              <- メインworktree
├── my-app-feature-a/    <- リンクworktree
├── my-app-feature-b/    <- リンクworktree
└── my-app-hotfix/       <- リンクworktree

メインworktreeと同じ階層に配置することで、管理が容易になります。

定期的なクリーンアップ

使用しなくなったworktreeは速やかに削除することを推奨します。

1
2
3
4
5
6
7
8
# 現在のworktree一覧を確認
git worktree list

# 不要なworktreeを削除
git worktree remove ../my-app-old-feature

# 手動削除された参照をクリーンアップ
git worktree prune

サブモジュールとの併用

サブモジュールを含むリポジトリで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はより効率的で安全な複数ブランチの同時作業を実現します。ぜひ日々の開発ワークフローに取り入れてみてください。

参考リンク