TechQuant Blog

git worktree 実践Tips:ブランチ切り替えの沼から抜け出した話

8分で読める

機能ブランチで実装中、Slack で「本番で 500 出てる、ホットフィックス頼む」と飛んできた。手元の作業はビルド中、コミットも中途半端、git stash するにも未追跡ファイルが多くて気持ち悪い。あの瞬間、git worktree をちゃんと使えていたらと痛感した。

結論から言うと、ブランチを物理的に別ディレクトリへ展開できる git worktree は、複数ブランチを行ったり来たりする人ほど効く。一年ほど運用に組み込んでみて、もう git checkout でブランチを乗り換える機会は週に1回もなくなった。

git worktree とは何か(5秒で)

1つのリポジトリから、複数の作業ディレクトリを派生させられる仕組み。.git 本体は1箇所に置いたまま、../myrepo-fix../myrepo-review といった別フォルダに別ブランチをチェックアウトできる。

つまり、ブランチ ≒ ディレクトリとして扱える。エディタも別ウィンドウで開けるし、ビルド成果物も干渉しない。これが地味に強い。

基本コマンド:これだけ覚えれば足りる

細かいオプションはたくさんあるが、日常で使うのは4つだけ。

# 既存ブランチを別ディレクトリに展開
git worktree add ../myrepo-hotfix hotfix/login-500

# 新規ブランチを作りつつ展開
git worktree add -b feat/csv-export ../myrepo-csv main

# 一覧表示
git worktree list

# 不要になった worktree を片付ける
git worktree remove ../myrepo-hotfix

git worktree list で出てくる表示はこんな感じ。

/home/me/code/myrepo         a1b2c3d [main]
/home/me/code/myrepo-hotfix  e4f5g6h [hotfix/login-500]
/home/me/code/myrepo-csv     7890abc [feat/csv-export]

3つのブランチが3つの実体として並んでいる。エディタで ~/code/myrepo-hotfix を開けばそのブランチ、~/code/myrepo-csv を開けば別ブランチ。脳内のコンテキストスイッチがほぼゼロになる。

使いどころ1:緊急ホットフィックス

冒頭の例。本番障害でブランチを切り替える必要が出たとき、こうする。

cd ~/code/myrepo
git fetch origin
git worktree add ../myrepo-hotfix -b hotfix/login-500 origin/main
cd ../myrepo-hotfix
# ここで修正、テスト、push

元の作業ディレクトリは触っていない。書きかけのコード、ビルド中のキャッシュ、ローカルの node_modules、すべてそのまま残る。修正が終わったら git worktree remove ../myrepo-hotfix で一発で消えてくれる。

以前は焦って git stashcheckout → 修正 → checkoutstash pop の流れでやっていたが、stash pop でコンフリクトが出ると詰むときがある。worktree なら、その心配自体がない。

使いどころ2:レビュー専用ディレクトリ

同僚から「PR 見てほしい」と振られたとき、自分の作業中ブランチを止めてチェックアウトしたくない。そういうときはレビュー専用の worktree を1個固定で持っておく。

# 初回だけ
git worktree add ../myrepo-review --detach

# レビュー時
cd ../myrepo-review
git fetch origin pull/123/head:pr-123
git checkout pr-123
# 動かす、読む

--detach で始めると detached HEAD 状態で立ち上がるので、そのまま色々なブランチを試せる。レビューが終わったらまた git fetch して別の PR に切り替える。

正直、lazygit 等の TUI ツールでブランチを切り替える派閥もあるが、レビューはエディタを別ウィンドウで開きたい派にとって worktree は刺さる。

使いどころ3:長寿命ブランチでの並行開発

移行系の作業や、メジャーバージョン間の並行メンテをやっていると、main / next / legacy みたいに3つくらいのブランチを行き来する場面が出てくる。

うちでは Raspberry Pi 5 で動かしている自動売買システムの旧版(Python 3.10)と新版(3.12)の並行運用があり、それぞれ別 worktree にしている。.venv も別、依存も別、テストの実行も干渉しない。シェルセッションごとに cd する場所を変えるだけで「今はどっちの環境にいるか」が物理的に明確になる。

~/code/trader            # main(本番反映用)
~/code/trader-py312      # feat/python312-migration
~/code/trader-experiments # 思いつきの試作場

地味だが、direnv と組み合わせると cd した瞬間に venv が切り替わるので、運用が一段と楽になる。詳しくは以前書いたdirenv のプロジェクト別環境管理の記事を参照してほしい。

運用で気をつけている3つのルール

1. worktree のディレクトリは親フォルダを統一する

~/code/myrepo を本体としたら、worktree は必ず ~/code/myrepo-* という命名にする。バラバラの場所に置くと git worktree list を見たときに「これどこから生やしたっけ」と迷子になる。

2. 作業が終わったら worktree を消す

消し忘れた worktree が10個くらい溜まると、ブランチが消えていても作業ディレクトリだけ残って git worktree list がノイズだらけになる。週次で棚卸しする運用にしている。

# 古い worktree を一括チェック
git worktree list

# 物理ディレクトリは消したのに git の管理が残っているとき
git worktree prune

3. .git 本体のあるリポジトリ(メイン worktree)は壊さない

これは1回ハマった。メイン側のディレクトリを rm -rf したら他の worktree が全部死んだ。.git は1個しかないので、それを抱えているメインを消すと連鎖崩壊する。消すなら派生 worktree から。これは沼。

よくあるハマりどころと対処

同じブランチを2箇所に出せない

worktree は仕様として、同じブランチを複数の作業ディレクトリにチェックアウトできない。

$ git worktree add ../foo main
fatal: 'main' is already checked out at '/home/me/code/myrepo'

これは --force でも基本的に避けたほうがいい。複数箇所で同じブランチを編集すると、どっちでコミットしたかわからなくなって事故る。新しいブランチを切ってから worktree にする方が安全。

node_modules や venv が共有されない

これは仕様。worktree ごとに独立した作業ツリーなので、依存物も別物になる。最初は「ディスク容量がもったいない」と感じたが、逆にバージョンが混ざらない安心感の方が大きい。気になる人はパッケージマネージャ側のキャッシュ機能(uv や pnpm のグローバルストア)に任せれば実コストはかなり減る。

シェルプロンプトで現在のブランチを見失う

worktree を増やすと、ターミナルが多重化したときに「今どこのブランチか」を見失いやすい。Starship や powerlevel10k のようなプロンプトでブランチ名を表示しておくのは半ば必須。これがないと事故る。

tmux + worktree という組み合わせ

ここは正直まだ試行錯誤中だが、tmux のウィンドウごとに worktree を割り当てる運用にしてから、頭の切り替えがさらに減った。

# セッション起動スクリプト(抜粋)
tmux new-session -d -s work -c ~/code/myrepo
tmux new-window -t work -n hotfix -c ~/code/myrepo-hotfix
tmux new-window -t work -n review -c ~/code/myrepo-review

ウィンドウ番号 = ブランチの役割。Ctrl-b 1 で main、Ctrl-b 2 でホットフィックス、みたいに体に染み込む。脳のリソースを「どのブランチにいるか」に使わなくて済む。

VPS や複数マシン運用との相性

家の Raspberry Pi 5 と外部 VPS の両方で開発している関係で、worktree は両端でほぼ同じ運用にしている。本番デプロイ用 VPS では main の worktree だけ、開発機では複数 worktree という形。

VPS 側でも作業ディレクトリ管理を整えると運用が安定する。コスパ重視ならお名前.comの高性能VPSあたりは月数百円から始められて、検証用途には十分だった。本格的な自動化の話はRaspberry Pi × Claude Code で組む自動売買システムの Book にもまとめている。

導入の最小ステップ

いきなり全プロジェクトに導入しようとせず、こうやって始めるのがおすすめ。

  1. 1つのプロジェクトを選ぶ(できれば長寿命ブランチがあるもの)
  2. レビュー専用の worktree を1個だけ作る
  3. 1週間運用してみる
  4. 慣れたらホットフィックス用、実験用と増やす

最初の1個を作って cd でブランチが切り替わる体験をすると、もう git checkout オンリーには戻れない。たぶん。

結論

git worktree は派手な機能ではない。でも、ブランチ切り替えに伴う細かいストレス(stash の不安、ビルドキャッシュの破棄、エディタの再読み込み)が積み重なると、それが集中力をじわじわ削っている。

小さく試して、合えば残す、合わなければ捨てる。それでいい。少なくとも自分は、これを入れてから「ブランチを切り替えたくないから後回し」という判断をしなくなった。それだけで十分元は取れている。