はじめに
Gitで機能を開発している最中に、「本番環境の致命的なバグに対するホットフィックス(緊急修正)の依頼が入った」という場面はよくあります。
このような時、多くの開発者は以下のいずれかの対応をとります。
- 現在の変更を
git stashで一時退避し、ブランチを切り替えて修正し、作業完了後にgit stash popで戻す。 - ディレクトリ内に同じリポジトリをもう一つ
git cloneして別フォルダで作業する。
しかし、stash は退避した内容を忘れてしまったり、復元時にコンフリクトを起こすリスクがあります。また、別個の git clone はディスク容量を2倍消費する上に、ローカルコミットの同期が面倒です。
これらの課題をスマートに解決するのが、Gitの標準機能である git worktree コマンドです。本記事では、複数タスクの並行作業を劇的に効率化する git worktree の使い方を解説します。
1. git worktree とは?
git worktree は、1つの .git ディレクトリ(リポジトリの実体)を共有したまま、ディスク上の別のフォルダに「別のブランチをチェックアウトした作業ディレクトリ」を複数展開できる機能です。
主なメリット
- stashが不要に: 開発中の手を止めることなく、フォルダを移動するだけで別ブランチの作業に入れます。
- ディスク容量の節約: リポジトリの履歴データ(
.git)は1つだけなので、新しくgit cloneするのに比べてディスク消費量が極めて少なく済みます。 - ビルドキャッシュの維持: フォルダが分かれているため、ブランチ切り替えによるビルドツール(WebpackやViteなど)のキャッシュクリアが発生せず、ビルドの待ち時間を削減できます。
2. 基本的な操作手順
実際にワークツリーを作成して並行作業を行う流れを見ていきましょう。
構成イメージ
プロジェクトのフォルダが以下のように展開されます。
/my-project/ (元のフォルダ:featureブランチで作業中)
/my-project-hotfix/ (新しく作成するフォルダ:hotfixブランチをチェックアウト)
ステップ1: ワークツリーを追加する(別ブランチを開く)
開発中のリポジトリ(/my-project/)で、以下のコマンドを実行します。
# git worktree add <追加先パス> <対象ブランチ名>
# ※ブランチがまだ存在しない場合は -b をつけて新規作成します
git worktree add ../my-project-hotfix -b hotfix/critical-bug
このコマンドを実行すると、1つ上の階層に my-project-hotfix というフォルダが自動生成され、その中で hotfix/critical-bug ブランチがチェックアウトされた状態になります。
ステップ2: フォルダを移動して作業する
あとは、生成されたフォルダに移動して修正を行い、コミット・プッシュするだけです。
cd ../my-project-hotfix
# ファイルを修正
git add .
git commit -m "fix: critical bug in production"
git push origin hotfix/critical-bug
この間、元の my-project フォルダのファイルや編集中の変更は一切汚されることなく、元の状態のまま維持されています。
ステップ3: ワークツリーを削除する
緊急対応が終わり、不要になったワークツリーは以下のコマンドで安全に削除できます。
元のリポジトリフォルダに戻り、削除コマンドを実行します。
cd ../my-project
# ワークツリーの一覧を確認
git worktree list
# ワークツリーを削除する (指定フォルダも自動的に消去されます)
git worktree remove ../my-project-hotfix
これだけでクリーンアップが完了します。
3. 運用の注意点
git worktree を利用する際のルールがあります。
重要同一リポジトリ内で、複数のワークツリーに「全く同じブランチ」を同時にチェックアウトすることはできません。
例えば、すでに my-project で main ブランチを開いている場合、別のワークツリーでさらに main ブランチを git worktree add しようとするとエラーになります。これはコミット履歴の不整合を防ぐためのGitの安全機能です。
まとめ
git worktree は、並行して複数の機能追加やバグ修正をこなすモダンな開発者にとって必須のコマンドです。
- 急な作業割り込みが入ったら
git worktree addで別フォルダを作る - 作業が終わったらコミットし、
git worktree removeでフォルダごと削除する
これにより、コンテキストスイッチの負担を減らし、開発効率を向上させることができます。ぜひ使ってみてください。
