プログラミング
Git worktree を使用して、面倒な並列開発を回避する
Parallel development without the headaches using Git worktree (barrd.dev)
要約
Git の worktree 機能は、単一のリポジトリ履歴を共有しながら、それぞれ独自のディレクトリで複数のブランチを同時に作業できるようにする強力なツールです。これにより、ブランチ間の頻繁な切り替えや stashing の手間が省け、特に緊急の修正作業が発生した場合でも、コンテキストの切り替えを最小限に抑え、作業を整理しやすくなります。この記事では、worktree の基本的な使い方から、並列開発の具体的なシナリオ、そして worktree の管理方法までを解説しています。
全文翻訳
Git worktree を使用して、面倒な並列開発を回避する
作成日: 2026年1月1日
更新なし… 約10分で読める、1,916語。
はじめに
最近、特に厄介なプロジェクトに取り組んでいる際に、Git の worktree 機能に出くわしました。これは、単一のリポジトリ履歴をすべて共有しながら、それぞれ独自のディレクトリで複数のブランチを同時に作業できるツールです。
簡単な視覚化:
~/Herd/
├── my-project/ # メインの worktree、ブランチ `main`
│ └── .git/ # メインの git ディレクトリ
├── my-project-feature/ # リンクされた worktree、ブランチ `feature/login-form`
└── my-project-hotfix/ # リンクされた worktree、ブランチ `hotfix/payment-bug`
上記のすべてのディレクトリは、同じコミット履歴を共有し、同じ .git オブジェクトデータベースにリンクされていますが、それぞれ独自のワーキングディレクトリの状態を持っています。各ディレクトリは通常のチェックアウトのように動作し、ファイルを編集し、コミットし、プッシュすることができますが、単一のワーキングツリーでのブランチの頻繁な切り替えを回避できます。
Git ロゴ
Git バージョン管理のロゴが、傾いた黒い四角の中に分岐図として表示されています。
従来、複数のブランチで作業するには、git checkout と git stash を頻繁に使用して作業場所を保存し、コンテキストを切り替え、重要なものを失わないように祈る必要がありました。特に、本番環境のバグが作業の流れを中断した場合、迷子になりやすいです。
git worktree を使用すると、任意のブランチ(既存または新規)に対して新しいワーキングディレクトリを追加し、ワークストリームを分離できます。
例:
# 既存のブランチを worktree として追加
git worktree add ../my-project-feature feature-branch
# または、新しいブランチと worktree を一度に作成
git worktree add -b new-feature ../my-project-new-feature
これにより、指定したブランチにチェックアウトされた新しいディレクトリが、メインプロジェクトと同じレベルに作成されます。これで、メインのワーキングディレクトリに触れることなく、各ディレクトリでファイルを編集、コミット、プッシュできます。
セットアップは次のようになります。
my-project/ # メインの worktree、ブランチ `main`
my-project-feature/ # `feature-branch` 用の worktree
my-project-new-feature/ # `new-feature` 用の worktree
1つの重要な制限は、同じブランチを複数の worktree で同時にチェックアウトできないことです。各 worktree は一意のブランチをチェックアウトする必要があります。実際には、これは「1つのタスク、1つのブランチ、1つのディレクトリ」という整然としたマッピングを奨励し、精神的に方向感覚を保ちやすくします。
実用例:フィーチャーとホットフィックスの切り替え
現実的なシナリオとして、チェックアウト機能に取り組んでいるときに、本番環境のバグが発生した場合を考えます。
初期レイアウト:
~/Herd/
└── shop/ # メインの worktree、ブランチ `main`
└── .git/
フィーチャーの worktree を作成:
cd ~/Herd/shop
git worktree add -b feature/checkout ../shop-checkout
新しいレイアウト:
~/Herd/
├── shop/ # メインの worktree、ブランチ `main`
│ └── .git/
└── shop-checkout/ # リンクされた worktree、ブランチ `feature/checkout`
shop-checkout でチェックアウト機能の開発を続けながら、shop を main でレビュー用に保持できます。
本番環境のバグが発生し、ホットフィックスの worktree を作成:
cd ~/Herd/shop
git worktree add -b hotfix/payment-fail ../shop-payment-hotfix
レイアウトは次のようになります。
~/Herd/
├── shop/ # メインの worktree、ブランチ `main`
├── shop-checkout/ # フィーチャーの worktree、`feature/checkout`
└── shop-payment-hotfix/ # ホットフィックスの worktree、`hotfix/payment-fail`
この時点で、次のことができます。
shop-payment-hotfix worktree で本番環境のバグを修正およびテストする。
shop-checkout worktree で feature/checkout のイテレーションを続ける。
shop を main でマージやコードレビューのために空けておく。
worktree を別のブランチにマージする方法
worktree ブランチからの変更のマージは、他の Git マージと同様ですが、各ブランチが独自のディレクトリに存在するため、コンテキストがより明確になります。フィーチャーブランチを main にマージする典型的なワークフローを次に示します。
フィーチャー worktree で作業を完了し、変更をコミットします。
メインの worktree ディレクトリに切り替えます。
cd ../my-project && git checkout main
フィーチャーブランチをマージします。
git merge feature-branch
競合を解決し、プッシュします。
各 worktree は単一のブランチ専用であるため、間違ったブランチに誤ってコミットしたり、ホットフィックスがフィーチャー作業を中断したときに場所を失ったりする可能性がはるかに低くなります…まあ、それが理論です。 😉
現在の worktree の確認
何かを削除または刈り込む前に、Git が現在認識している worktree を確認すると役立ちます。
git worktree list
例:
/Users/barrd/Herd/shop 66c16256 [main]
/Users/barrd/Herd/shop-checkout 0c8ba118 [feature/checkout]
/Users/barrd/Herd/shop-payment-hotfix a16e4be2 [hotfix/payment-fail]
これは次のように視覚的にマッピングできます。
[main] → /home/user/Herd/shop
[feature/checkout] → /home/user/Herd/shop-checkout
[hotfix/payment-fail] → /home/user/Herd/shop-payment-hotfix
どのブランチがチェックアウトされており、どこにあるかが明確になり、すでに別の worktree にアタッチされているブランチを再利用しようとするのを避けるのに役立ちます。
worktree の削除方法
worktree が不要になったら、整理するのが良い習慣です。安全に行うには、変更をコミットまたは stash した後、次のコマンドを実行します。
git worktree remove ../my-project-feature
これは、クリーンな worktree(未コミットの変更や追跡されていないファイルがない状態)でのみ機能します(--force を渡さない限り)。メインの worktree を削除することはできません。
worktree の削除はワーキングディレクトリのみを削除し、ブランチ自体は削除しないことを忘れないでください。
削除する前に、その worktree で git status を確認して、未コミットの作業を失わないようにしてください。
stale な worktree の prune によるクリーンアップ
worktree ディレクトリを手動で削除した場合、Git はメインリポジトリの worktrees ディレクトリの下にメタデータを保持します。その場合、git worktree list は欠落しているとマークされたエントリを表示します。
次のコマンドで stale なエントリをクリーンアップできます。
git worktree prune
一定期間使用されていないエントリのみを prune するには、有効期限を追加できます。
git worktree prune --expire 7.days.ago
--expire を使用すると、stale な worktree メタデータがすぐにすべて削除されます。これは、古い不要なディレクトリを頻繁に削除するローカル開発環境で役立ちます。
最終的な考え
これは v2.5 から存在しており、約10年前ですが、私はそれを一度も使用したことがありませんでした…しかし、それは私のワークフローを変革しました。特に、並列フィーチャーや緊急のホットフィックスを切り替える際に役立ちます。すべての要素を分離し、コンテキストの切り替えを減らし、stash がまれな例外になりました。
シンプルでシーケンシャルな作業には、従来のブランチングが依然として最善の方法ですが、同時に複数の場所にいたいと思ったことがあるなら、git worktree を試してみてください。
もしお気に入りのワークフローのバリエーションがあれば、ぜひ教えてください。
// 記事終了
記事情報
カテゴリ: テクニカル
トピック: #Tech-Stack
さらに読む
Git's Database Internals (github.blog)
Git Worktree Docs (git-scm.com)
関連記事 / ページ
Git switch – 間違ったブランチにいる場合の stash の代替 (記事)
Laravel Herd から未使用の PHP バージョンを削除する (記事)
Valet と PHP Monitor を維持しながら Laravel Herd を使用する (記事)
Starship、超高速クロスシェルプロンプト (記事)
Dave A.K.A. 'barrd'
Dave はブリストル在住のスコットランドからの移民で、20年以上のウェブ開発経験があります。ギターを弾くこと、読書、SF鑑賞、テクノロジーのいじくり回しを楽しんでいます。
Dave A.K.A. 'barrd' について
Dave はブリストル在住のスコットランドからの移民で、20年以上のウェブ開発経験があります。ギターを弾くこと、読書、SF鑑賞、テクノロジーのいじくり回しを楽しんでいます。詳細はこちら