git worktree で始める並行開発。ブランチ切り替えの手間を減らす基本操作と運用の工夫
目次
開閉
機能開発に集中している最中、Slackで「至急この不具合の再現確認をお願いできますか?」「別ブランチのPRを出したので手元で動作を見てほしい」と声をかけられる。Web開発の現場では、避けて通れない日常茶飯事の光景です。
こうした割り込み作業が入ったとき、多くの現場で取られているのが git stash で作業中の変更を一時退避し、目的のブランチへ git switch(または git checkout)する方法でしょう。
しかし、この手順には地味ながら無視できないコストが潜んでいます。
- ブランチを行き来するたびに
node_modulesや依存パッケージの再インストールが発生する - ローカルの開発サーバーやDockerコンテナの再起動、ビルドキャッシュの破棄で数分〜十数分が奪われる
- 用件を終えて元のブランチに戻り
git stash popを叩いた瞬間、退避したことを忘れていたファイルと衝突してコンフリクトする
作業のコンテキストが強制的にリセットされ、「さっき自分はどのファイルのどこまで手を付けていたんだっけ?」と思い出すまでの認知負荷は、開発のリズムを大きく削ぎ落とします。
こうした切り替え摩擦を根本から解消してくれるのが、Git標準機能である git worktree です。
本稿では、特別な外部ツールを導入することなく、Git標準のコマンドだけで「複数ブランチを別ディレクトリとして同時に展開し、並行開発を進める」ための基本操作と、現場で破綻させないための実践的な運用の工夫を整理します。
そもそも git worktree とは何か?
通常、Gitリポジトリを git clone すると、プロジェクトのルートディレクトリに .git という隠しフォルダが作られ、作業ディレクトリ(ワーキングツリー)と1対1で結びつきます。そのため、1つのディレクトリの中では「常に1つのブランチ」しかチェックアウトできません。
これに対して git worktree は、1つの .git ディレクトリ(オブジェクトデータベースや履歴情報)を共有したまま、複数の作業ディレクトリをローカルの別の場所に展開できる機能 です。
【通常運用(1つの作業ディレクトリ)】
my-project/
├── .git/ (履歴やブランチ情報を一元管理)
└── (作業ファイル群) ← ここでブランチを都度切り替える(要stash・再ビルド)
【git worktree 運用(作業ディレクトリの並行展開)】
my-project/ (メイン作業ツリー: mainブランチ)
├── .git/
└── (mainブランチの作業ファイル群)
my-project-hotfix/ (追加worktree: hotfixブランチ)
├── .git (ファイル) ← 親の .git への参照ポインタ
└── (hotfixブランチの作業ファイル群)「別名で git clone する」との決定的な違い
「作業ディレクトリを分けたいだけなら、別のフォルダに新しく git clone すればいいのでは?」と思うかもしれません。
しかし、単純な別名クローンにはいくつかの明確なデメリットがあります。
- ストレージ容量の無駄遣い: プロジェクトの全履歴やコミットオブジェクトが丸ごと複製されるため、巨大なリポジトリではディスクを無駄に圧迫します。
- 履歴やローカルブランチが分断される: 別個のリポジトリ扱いになるため、手元で作成した未pushのブランチをもう一方から参照するには、一度リモートへpushするか手動で同期する手間が発生します。
- リモートへの不要な通信: 最新のコミットを取得するために、それぞれのクローン先で個別に
git fetchを実行しなければなりません。
git worktree であれば、裏側のデータ実体は1つの .git を参照している ため、ディスク容量を最小限に抑えられます。さらに、メイン側で git fetch すれば追加した全worktreeで即座に最新リモートブランチが使えますし、手元で切ったローカルブランチも何の手間もなく相互にチェックアウト可能です。
基本のコマンド操作:これだけ覚えれば実務で動かせる
git worktree の操作体系は非常にシンプルです。日常の作業で必要になる基本コマンドは以下の4つに集約されます。
1. 既存のブランチを別ディレクトリに展開する
急ぎのレビューや動作確認などで、すでに存在するブランチを別ディレクトリにチェックアウトしたい場合は、git worktree add を使います。
# 書式: git worktree add <展開先パス> <既存ブランチ名>
git worktree add ../my-project-review origin/feature/user-auth
このコマンドを実行すると、1つ上の階層に my-project-review ディレクトリが生成され、指定したブランチの内容が展開されます。
2. 新規ブランチを切りながら別ディレクトリに展開する
「現在作業中のブランチはそのまま残し、別の緊急修正用ブランチを新しく切って作業したい」という場合は、-b オプションを付与します。通常の git switch -c と同じ感覚です。
# main から派生させた新ブランチ hotfix/login-bug を別ディレクトリに展開
git worktree add -b hotfix/login-bug ../my-project-hotfix main
これで、メインの作業ディレクトリは何一つ触ることなく、独立した my-project-hotfix ディレクトリでクリーンな状態から修正に着手できます。
3. 現在の worktree 一覧を確認する
今どのディレクトリにどのブランチが紐付いているかは、git worktree list でいつでも確認できます。
git worktree list
実行すると、以下のように一覧が表示されます。
/Users/username/develop/my-project a1b2c3d [main]
/Users/username/develop/my-project-hotfix e4f5g6h [hotfix/login-bug]
/Users/username/develop/my-project-review 7i8j9k0 [feature/user-auth]
一番上がメインのリポジトリで、それ以降が git worktree add によって追加された追加ツリーです。
4. 用件が済んだ worktree を安全に削除する
修正をコミット・pushし、PRの作成やレビューが終わったら、不要になったworktreeを片付けます。
通常の rm -rf でフォルダごと消すのではなく、専用の git worktree remove コマンドを使うのが原則です。
# 書式: git worktree remove <worktreeのパス>
git worktree remove ../my-project-hotfix
このコマンドを実行すると、作業ディレクトリが削除されると同時に、親の .git/worktrees/ 配下に残っていた管理用メタデータも綺麗に掃除されます。
現場で破綻しない「ディレクトリ配置」の工夫
git worktree を導入したエンジニアが最初に悩むのが、「追加する作業ディレクトリをどこに配置するか」という運用のルール作りです。
自由に適当な場所へ作っていると、デスクトップや親フォルダにプロジェクト名のディレクトリが散乱し、どれが本尊でどれが使い捨てなのか分からなくなります。実務では、以下の2つのパターンのいずれかに揃えるのがおすすめです。
パターンA: 親ディレクトリに並べる「兄弟並列型」(おすすめ)
メインリポジトリと同じ階層に、接尾辞を付けて並べる構成です。
develop/
├── my-project/ ← メイン(常に最新の main または develop)
├── my-project-hotfix/ ← 緊急修正用
└── my-project-review/ ← PRレビュー用
- メリット: ディレクトリ階層が浅く、ターミナルでの移動やVS Codeの起動(
code ../my-project-hotfix)が直感的に行える。 - ポイント: 親フォルダが散らからないよう、作業が終わったらその都度
git worktree removeで片付ける習慣を徹底します。
パターンB: リポジトリ内に隠す「サブディレクトリ集約型」
メインリポジトリの内部に .worktrees/ というディレクトリを掘り、その中にすべてを収める構成です。
my-project/
├── .git/
├── .worktrees/ ← すべての追加ツリーをここに集約
│ ├── hotfix/
│ └── review/
├── src/
└── package.json
この構成を採用する場合は、親リポジトリの .gitignore に必ず除外設定を追加 してください。
# .gitignore
.worktrees/
- メリット: プロジェクト関連のファイルが単一のディレクトリ配下に収まるため、フォルダ全体の把握がしやすい。
- 注意点: 深い階層になりがちで、エディタの検索対象やファイル監視(Watchers)に巻き込まれないよう適切な除外設定が必要です。
実務で直面する注意点と回避テクニック
日々の現場で git worktree を快適に使い倒すために、あらかじめ知っておくべき仕様とハマりどころが3点あります。
1. 「同一ブランチの二重チェックアウト」は禁止されている
もっとも遭遇しやすいエラーがこちらです。
fatal: 'main' is already checked out at '/Users/username/develop/my-project'
Gitは安全のため、複数のworktreeでまったく同一のブランチを同時にチェックアウトすることを許可していません。仮に2箇所から同じブランチへ同時にコミットされると、HEADのポインタ整合性が保てなくなるためです。
2. .env や非Git管理ファイルの引き継ぎ
git worktree add で新しく作られたディレクトリは、Gitで管理されているファイルのみが展開された「まっさらな状態」です。
そのため、ローカル開発に必要な環境変数ファイル(.env や .env.local)、各種ツールのローカル設定など、.gitignore されているファイルは自動的には引き継がれません。
この問題に対しては、以下のいずれかの方法で手早く整えるのが実務的です。
- 方法1: 1行コマンドでコピーする
cp ../my-project/.env ../my-project-hotfix/.env - 方法2: シンボリックリンクを貼る(Mac / Linux / WSL)
※すべてのworktreeで共通のローカル設定を参照したい場合は、シンボリックリンクにしておくと更新の手間が省けます。ln -s ../my-project/.env ../my-project-hotfix/.env
3. VS Codeなどのエディタは「別ウィンドウ」で開く
作業ディレクトリが分かれたら、エディタも作業ごとに独立したウィンドウで開くのがもっとも快適です。
VS Codeを使っている場合、既存のウィンドウに追加ワークスペースとして読み込ませる(マルチルートワークスペースにする)と、Gitレンズや言語サーバー(TypeScript / ESLint等)のプロセスが混ざり、型チェックやインデックス作成が混乱することがあります。
# 新しいウィンドウとして独立して起動する
code -n ../my-project-hotfix
ターミナルから -n オプションを付けて開けば、完全に独立した環境として作業でき、修正が終わればそのウィンドウを閉じるだけで頭の切り替えが完了します。
なお、複数リポジトリやディレクトリの行き来をターミナルから爆速化したい場合は、過去記事で紹介した「ghq × fzf」の組み合わせとも非常に相性が良いです。
思考のメモリを消費しない開発フローをつくる
「作業を一時退避するためにstashして、戻ってきたらpopして、衝突したら解消して……」という手順は、一つひとつの操作自体は数分で済むかもしれません。
しかし、「今の作業状態を壊したくない」「stashの中身が何だったか忘れないようにしなきゃ」という心理的なプレッシャーは、確実にエンジニアの集中力を削り取ります。
git worktree の本質的な価値は、単にコマンドの実行時間を節約すること以上に、「物理的にディレクトリを分けることで、自分の頭の中のワーキングメモリを一切汚さずに作業を並行できること」 にあります。
- メイン作業はそのまま温存しておく
- 割り込み作業は別ディレクトリでサクッと片付けてPRを出す
- 用が済んだらディレクトリごと安全に破棄する
Gitが最初から備えているこの仕組みを取り入れるだけで、日々の割り込みタスクに対する身軽さは劇的に変わります。次に「ちょっと別ブランチを見てほしい」と頼まれた際は、ぜひ git stash ではなく git worktree add を試してみてください。