Git worktreeで並行開発の頭痛を解消:ブランチごとに独立した作業ディレクトリを
Parallel development without the headaches using Git worktree

Gitのworktree機能を使うと、複数のブランチをそれぞれ独立したディレクトリで同時にチェックアウトでき、ブランチの切り替えやstashに悩まされることなく、機能開発と緊急バグ修正を並行して進められます。本記事では、worktreeの基本から、実践的な活用例(機能開発中に本番バグが発生した場合の対処)、マージ方法、一覧表示、削除・整理までを、具体的なコマンドとともに解説します。
「1つのタスク、1つのブランチ、1つのディレクトリ」というクリーンなマッピングが、精神的な見通しを保ちやすくしてくれます。
HNでの議論
48- zmmmmm
並行開発の本当の問題は、並行開発環境が互いに干渉せずにシームレスに共存できることを保証することです。そのうちの1つがポートを開こうとしたり、外部データベースと通信したり、テストの一部として共有場所に書き込もうとすると、互いに衝突します。
これは主にレガシー開発の問題であり、そもそも並行する一時的な開発環境が使われるという想定はあまりありませんでした。しかし、レガシー開発は依然として開発の大部分を占めています。
- tlarkworthy
私はトップレベルのメタリポジトリを使って、すべてのリポジトリの仮想モノレポを作成し、その上流をベンダリングしています。そして、サブモジュールからworktreeを使ってパッチを準備します。複数のエージェントがいても、ルートのメタリポジトリからディレクトリを変更する必要はありません。実際にはどの部分も所有することなく完全なモノレポ体験が得られ、各エージェントは独立したworktreeを持つため衝突しません。
- therealmarv
頑固かもしれませんが、AIの時代でも、私は同じプロジェクトの複数のgitクローン/ディレクトリを使い続けています。例:
~/dev/projectx
~/dev/projectx2
~/dev/projectx3
~/dev/projectx4
プロジェクトごとに4〜5個以上使うことはめったにありません。おそらく、worktreeを理解して実際に試すことを避けているだけでしょう。
利点:これらのクローンは半永続的なディレクトリとして機能します:
- ヘビーなDocker使用時のキャッシュに役立ちます(繰り返しの並列ユニットテストやE2Eテストを考えてください)
- 各クローンにターミナルタブの色を付けて、どこにいるかを一目でわかるようにしています(タブグループを色で分けるようなもの)
もし何らかの理由でプロジェクトのクローンが2桁必要になったら、その時はgit worktreeを使わざるを得なくなるでしょう。なぜなら、どのディレクトリにどのブランチのクローンがあるかを覚えるのが面倒になるからです。
- irskep
私は毎日git worktreeを使っています。使ったことがない人に説明するのがどれほど難しいかに驚いています。最近は「クローンに似ているが、.gitディレクトリを共有している」という説明に落ち着きました。記事ではブランチと比較して説明しようとしていますが、私はクローンの方が比較対象として直感的だと思います。
コマンドの冗長さや、.envファイルのコピーや依存関係のインストールなどの手動コマンドなど、いくつかの使い勝手の問題を解決するために、autowtという軽量で強力なworktreeマネージャーを書きました:https://steveasleep.com/autowt/
CLIの使い勝手を調整したら、タスクを切り替えるために「git checkout <branch>」と入力するのを基本的にやめました。タスクを切り替えるときに作業ディレクトリの状態を無視する方が簡単だからです。
- pkghost
worktreeの深みに約1か月はまりましたが、複数のエージェントが複数のリポジトリにわたって作業できるようにするために、複数のチェックアウトに切り替えることにしました。
私のエージェントの作業が主に単一のリポジトリに限定されているときは、worktreeは非常にうまく機能しました(最終的にレート制限に達しましたが、それが目標だったわけではありません)。ホームラボが拡大するにつれて、エージェントは複数のリポジトリにまたがって作業することが増え、その時点で(私のアプローチの)worktreeは機能しなくなりました。エージェントはリポジトリのworktreeで生成されたため、特別な指示なしに同じリポジトリ内の他のエージェントの邪魔をすることはありませんでしたが、別のリポジトリに触れる必要があるとすぐに、worktreeを使わずにそのリポジトリで直接作業するのがデフォルトになり、他のエージェントと衝突し、メインのリポジトリのクローンがクリーンであることを期待するマージプロセスを混乱させました(これは不要な設計上の癖であることが判明しましたが、それを解決してもエージェントがセカンダリリポジトリで互いに邪魔をし合うのを止めることはできませんでした)。
ZFSデータセットのクローンと、各エージェントプロセスに対して/srv/src/が異なる階層に見えるようにするマウントの魔法を経由した後、私はさらに簡素化し、各エージェントにベアディレクトリ(/srv/dev/<slug>/など)を与え、そこで好きなリポジトリをチェックアウトできるようにしました。gitリモート(/srv/git/)が唯一の統合ポイントになります。
おそらく、コンテナに移行すべきかもしれませんが、パフォーマンスは良いものの、使い勝手にはまだがっかりしています。
編集:実際にはZFSデータセットを保持するかもしれません…