4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Git Worktree実践ガイド:割り込み作業を爆速化する並行開発戦略

4
Posted at

「緊急のバグ修正が割り込んできたけど、今作業中の機能開発はまだコミットできない…」「PRレビューのためにブランチを切り替えたら、またIDEのインデックス再構築で数分待たされた…」

Gitでの開発において、このようなコンテキストスイッチの多さやブランチ切り替えの手間は、多くのエンジニアが直面する課題です。特に大規模なプロジェクトや複数のタスクを並行して進める必要がある場合、そのオーバーヘッドは無視できません。

この記事では、Git Worktree を活用して、これらの課題を劇的に改善し、複数の作業を爆速で並行開発するための具体的なワークフローと、その効果、そして注意点を解説します。これを読めば、もうブランチ切り替えによるイライラや時間のロスとは無縁になるでしょう。

Git Worktreeとは?なぜ並行開発に必須なのか

このセクションでは、Git Worktreeの基本的な概念と、それが従来のGitワークフローの課題をどのように解決し、並行開発を強力にサポートするのかを説明します。

Git Worktreeは、単一のGitリポジトリに対して複数のワーキングツリー(作業ディレクトリ)を同時に持つことができる機能です。通常のGitリポジトリは .git ディレクトリと、その中のファイルやディレクトリで構成される一つのワーキングツリーを持ちますが、Worktreeを使うと、同じ .git ディレクトリを参照しながら、異なるブランチをチェックアウトした複数の作業ディレクトリを持つことができます。

従来のGitワークフローの課題

Git Worktreeが解決する主な課題は以下の通りです。

  1. コンテキストスイッチのオーバーヘッド:
    • ブランチを切り替えるたびに、未コミットの変更を git stash したり、コミットしたりする手間が発生します。
    • IDE(VS Code, IntelliJなど)はブランチ切り替え時にインデックスの再構築やキャッシュのクリアを行うことが多く、その待ち時間が発生します。特に大規模なプロジェクトでは数分かかることも珍しくありません。
    • 依存関係(node_modules など)の再インストールやキャッシュの再構築が必要になる場合があります。
  2. 複数のタスクの並行処理の困難さ:
    • 緊急のバグ修正やPRレビューが割り込んだ際、現在作業中のブランチから別のブランチへ切り替えなければならず、集中が途切れます。
    • ある機能のビルドやテストに時間がかかっている間に、別の機能を開発するといった並行作業が困難です。
    • 異なるブランチのコードを比較したり、サイドバイサイドでテストしたりする場合、一度に一つのブランチしかアクティブにできないため、手間がかかります。

Git Worktreeが提供する解決策

Git Worktreeは、これらの課題に対し、以下のメリットを提供します。

  • 瞬時のブランチ切り替え: 異なるブランチはそれぞれ独立したワーキングツリーを持つため、ブランチを切り替える必要がなくなります。別のタスクに取り掛かる際は、単に別のワーキングツリーのディレクトリに移動するだけです。
  • コンテキストの完全な分離: 各ワーキングツリーは独自の作業ディレクトリを持つため、ファイルの状態、IDEのインデックス、依存関係などが完全に分離されます。これにより、IDEの再インデックス待ちや依存関係の再インストールが不要になり、コンテキストスイッチのコストを最小限に抑えられます。
  • 真の並行開発: 複数のタスクを同時にアクティブな状態で進めることができます。例えば、メインの機能開発を進めながら、別のワークツリーでホットフィックスを適用し、さらに別のワークツリーでPRレビューを行う、といったことが可能です。
  • 実験的な変更の安全性: メインの作業を中断することなく、新しいアイデアや破壊的な変更を安全に試すための独立した環境を簡単に作成できます。

Git WorktreeはGit 2.5で導入され、Git 2.7.0で大幅な機能強化が行われました。最新のGitバージョン(推奨: 2.30以降)であれば、安定して利用できます。

Git Worktreeの基本的な使い方

このセクションでは、Git Worktreeを使い始めるための基本的なコマンドと操作方法を具体的な例を交えて解説します。

1. 新しいワークツリーの作成

最も一般的な使い方は、新しいブランチを作成し、それを新しいワークツリーにチェックアウトすることです。

新しいブランチを作成してワークツリーにチェックアウトする

現在のブランチから派生した新しいブランチ(例: hotfix-bug-123)を作成し、それを専用のディレクトリ(例: ../hotfix-bug-123)にチェックアウトします。

# メインリポジトリのディレクトリで実行
# 現在のブランチから 'hotfix-bug-123' という新しいブランチを作成し、
# メインリポジトリの親ディレクトリに '../hotfix-bug-123' としてワークツリーを作成
git worktree add ../hotfix-bug-123 -b hotfix-bug-123

なぜ -b オプションを使うのか?
-b は新しいブランチを作成し、そのブランチ名を指定します。この例では、ワークツリーのディレクトリ名とブランチ名を一致させていますが、これは分かりやすさのためであり、必須ではありません。

Git 2.30以降の簡略化された記法:
Git 2.30以降では、ブランチ名を省略し、-b, -B, --detached のいずれも使用しない場合、デフォルトで HEAD をベースにした新しいブランチが自動的に作成されます。

# 自動的に新しいブランチが作成され、そのブランチ名がワークツリーのディレクトリ名と一致する
git worktree add ../new-feature

既存のブランチをワークツリーにチェックアウトする

既に存在するブランチ(例: develop)を、新しいワークツリーにチェックアウトしたい場合です。これは、特定のブランチのコードを素早く確認したり、別の環境でテストしたりするのに便利です。

# 既存のブランチ 'develop' を '../dev-env' ディレクトリにチェックアウト
git worktree add ../dev-env develop

一時的なワークツリーをデタッチドHEADで作成する

特定のコミットの状態を一時的に確認したい場合や、実験的な作業をブランチとして残したくない場合に便利です。

# 現在のブランチと同じコミットでデタッチドHEADのワークツリーを '../experiment' ディレクトリに作成
git worktree add -d ../experiment

2. ワークツリーの一覧表示

現在設定されているすべてのワークツリーを確認するには、git worktree list コマンドを使用します。

git worktree list

出力例:

/path/to/main/repo   HEAD       main [main branch for project X]
/path/to/hotfix      a1b2c3d4   hotfix-bug-123 [緊急修正]
/path/to/dev-env     e5f6g7h8   develop
/path/to/experiment  f9a0b1c2   (detached HEAD)

この出力から、各ワークツリーのパス、現在のコミットハッシュ、チェックアウトされているブランチ(またはデタッチドHEAD)、そしてオプションで説明(git worktree add 時に --reason で指定可能)を確認できます。

3. ワークツリーの削除

不要になったワークツリーは、必ず git worktree remove コマンドを使って安全に削除しましょう。

# 削除したいワークツリーのディレクトリではない場所(例: メインリポジトリ)で実行
cd /path/to/main/repo
git worktree remove ../hotfix-bug-123

注意点:

  • 削除したいワークツリーのディレクトリ内にいる状態では、そのワークツリーを削除できません。メインのワークツリーや別のワークツリーに移動してから実行してください。
  • 削除するワークツリーに未コミットの変更がある場合、Gitは削除を拒否します。変更をコミットするか、--force オプションを使って強制的に削除してください(ただし、データ損失のリスクがあるため非推奨)。

4. 孤立したワークツリーのクリーンアップ

誤ってワークツリーのディレクトリを手動で削除してしまった場合など、Gitのメタデータが残ってしまうことがあります。このような「孤立した」ワークツリーの情報をクリーンアップするには、git worktree prune コマンドを使用します。

git worktree prune

Gitは定期的に自動でこれを実行しますが、手動で実行することも可能です。

5. ワークツリーのロックとアンロック

重要なワークツリーを誤って削除されるのを防ぐために、ロックすることができます。

# 特定のワークツリーをロックし、理由を添える
git worktree lock ../feature-branch --reason "作業中につき削除禁止"

# ロックされたワークツリーの削除を試みるとエラーになる
# git worktree remove ../feature-branch 
# -> fatal: worktree '/path/to/feature-branch' is locked.
#    (use 'git worktree unlock' to unlock it)

# ロックを解除する
git worktree unlock ../feature-branch

Git Worktreeを活用した並行開発ワークフロー

このセクションでは、Git Worktreeを実際の開発シーンでどのように活用し、効率的な並行開発を実現するかを具体的なシナリオで解説します。

シナリオ1: 緊急ホットフィックスへの対応

メインの機能開発中に、プロダクション環境で緊急のバグが発見された場合です。

  1. メインブランチで機能開発中: feature/payment ブランチで決済機能の開発中。まだコミットしていない変更がたくさんある。
  2. 緊急ホットフィックスの発生: プロダクションで致命的なバグが報告される。
  3. ホットフィックス用ワークツリーの作成: 現在の作業を中断せず、新しいターミナルを開き、メインリポジトリのディレクトリで以下のコマンドを実行。
    # mainブランチから新しいブランチ 'hotfix/prod-bug-critical' を作成し、
    # '../hotfix-prod-bug' ディレクトリにチェックアウト
    git worktree add ../hotfix-prod-bug -b hotfix/prod-bug-critical main
    
  4. ホットフィックス作業: ../hotfix-prod-bug ディレクトリに移動し、バグ修正とテストを行う。IDEもこのディレクトリを新しいウィンドウで開けば、メインの作業とは完全に独立した環境で作業できます。
  5. ホットフィックスのデプロイ: 修正をコミット、プッシュ、PR作成・マージ、デプロイ。
  6. メイン機能開発の再開: feature/payment ブランチのワークツリーに戻り、中断した箇所からスムーズに開発を再開。ホットフィックスの影響を受けません。
  7. ホットフィックスワークツリーの削除: デプロイ後、不要になった hotfix-prod-bug ワークツリーを削除。
    cd /path/to/main/repo
    git worktree remove ../hotfix-prod-bug
    git worktree prune # 念のためクリーンアップ
    

シナリオ2: 複数のPRレビューとローカルテスト

複数のプルリクエスト(PR)が上がっており、それぞれをローカルで確認・テストしたい場合です。

  1. レビュー対象のPRブランチをワークツリーにチェックアウト:
    # PR-123のブランチ 'feature/user-profile-v2' を '../review-pr-123' にチェックアウト
    git worktree add ../review-pr-123 feature/user-profile-v2
    
    # PR-124のブランチ 'bugfix/search-filter' を '../review-pr-124' にチェックアウト
    git worktree add ../review-pr-124 bugfix/search-filter
    
  2. 各PRのレビューとテスト:
    • ../review-pr-123 ディレクトリでPR-123のコードを確認し、テストを実行。
    • ../review-pr-124 ディレクトリでPR-124のコードを確認し、テストを実行。
    • それぞれのワークツリーで独立して npm installyarn を実行し、必要な依存関係をインストールします。
  3. レビューコメントの追加: 各PRのレビュー結果をまとめてGitHubなどにコメント。
  4. ワークツリーの削除: レビューが完了したら、それぞれのワークツリーを削除。

シナリオ3: 長時間かかるビルドやテスト中の別作業

大規模なプロジェクトでは、ビルドやテストに数分から数十分かかることがあります。その待ち時間を有効活用します。

  1. メインワークツリーでビルド/テストを開始: main ブランチのワークツリーで、時間がかかるビルドやテストコマンドを実行。
  2. 別ワークツリーで別のタスクを開始: ビルド/テストが実行されている間に、別のターミナルで新しいワークツリーを作成し、別のタスク(例: ドキュメント修正、別の機能のプロトタイピング、メール返信など)を開始。
    git worktree add ../docs-update -b docs/api-spec
    
  3. 効率的な時間の利用: ビルドが完了したらメインワークツリーに戻り、完了したタスクのワークツリーは削除します。

シナリオ4: AIエージェントとの並行開発

AIエージェントがコード生成やリファクタリングを行うシナリオでもWorktreeは有効です。

  1. AIエージェント用ワークツリーの作成:
    git worktree add ../ai-agent-refactor -b ai/refactor-auth-module
    
  2. AIエージェントの実行: AIエージェントを ../ai-agent-refactor ディレクトリ内で実行させ、コードの変更やテストを行わせます。
  3. 人間によるレビューとマージ: 人間はメインのワークツリーで自分の作業を進めつつ、AIエージェントが生成した変更を ../ai-agent-refactor で確認し、問題なければメインブランチにマージします。

これにより、人間とAIが互いの作業を邪魔することなく、並行して開発を進めることが可能になります。

Git Worktreeの注意点とベストプラクティス

このセクションでは、Git Worktreeを効果的に活用するためのベストプラクティスと、遭遇しがちな問題とその回避策を解説します。

よくあるエラー・ハマりどころと回避策

エラー1: 同じブランチを複数のワークツリーでチェックアウトしようとする

現象: Gitは、同じブランチが2つのワークツリーで同時にアクティブになることを許可しません。例えば、main ブランチがメインのワークツリーでチェックアウトされている状態で、別のワークツリーでも main をチェックアウトしようとするとエラーになります。

回避策:

  • 新しいワークツリーには、別のブランチ名を使用します。
  • 既存のブランチを別のワークツリーで作業したい場合は、そのワークツリーでそのブランチをチェックアウトし、元のワークツリーでは別のブランチに切り替えるか、元のワークツリーを削除します。
  • 実験的な作業スペースがもう一つ必要な場合は、新しいブランチを作成します。

エラー2: ワークツリーディレクトリを手動で削除してしまい、Gitのメタデータが残る

現象: rm -rf などでワークツリーのフォルダを直接削除すると、Gitの内部状態が不整合になり、古いメタデータが残ることがあります。これにより、git worktree list で存在しないワークツリーが表示されたり、他のワークツリー操作で問題が発生したりします。

回避策:

  • ワークツリーを削除する際は、必ず git worktree remove <path> コマンドを使用します。
  • 残ってしまった古いメタデータは git worktree prune コマンドでクリーンアップできます。

エラー3: ワークツリーとアンコミットされたコミットに重複エントリがある (worktree and untracked commit have duplicate entries)

現象: Gitの内部状態が不整合になった場合に発生し、特に複数のワークツリーを使用している場合やGitのインデックスが破損している場合に起こります。

回避策:

  • Gitインデックスの破損が原因である可能性があるため、git resetgit clean などでインデックスをリセットすることを検討します。
  • ワークツリーの同期の問題が原因である場合、ワークツリーを再作成するか、Gitの内部状態を修復するコマンド(git fsck など)を試す必要があるかもしれません。

ハマりどころ: どのワークツリーにいるのか忘れてしまう

現象: 複数のワークツリーで作業していると、現在どのディレクトリで、どのブランチで作業しているのか混乱することがあります。

回避策:

  • pwd コマンドや git branch --show-current コマンドで現在のディレクトリとブランチを常に確認する習慣をつけましょう。
  • ワークツリーには、ブランチ名と一致するような分かりやすいディレクトリ名を使用します。
  • シェルプロンプトに現在のGitブランチ名を表示させる設定(PS1 環境変数など)を活用すると便利です。

設計上のトレードオフ

Git Worktreeは非常に便利ですが、いくつかのトレードオフも存在します。

  • ディスクスペースの使用量: 複数の完全なリポジトリをクローンするよりは少ないですが、ワークツリーごとに作業ディレクトリが作成されるため、ある程度のディスクスペースは必要になります。ただし、すべてのワークツリーが同じ .git ディレクトリを共有するため、完全なクローンを複数作成するよりも効率的です。
  • 依存関係の管理: 各ワークツリーは独立した作業環境を持つため、Node.jsの node_modules やPythonの仮想環境のような依存関係はワークツリーごとにインストールする必要がある場合があります。これは、各ワークツリーで npm installpip install を実行することを意味します。
  • IDEのサポート: 多くのIDEはGitのコア機能に焦点を当てており、Worktreeの完全なサポートは提供されていない場合があります。しかし、VS CodeやJetBrains IDEsでは、Worktreeを管理しやすくする拡張機能やプラグインが存在します。VS Codeは組み込みでWorktreeのディレクトリを新しいウィンドウで開く機能も持っています。

ベストプラクティス

  • 予測可能な場所にワークツリーを保持する: メインのリポジトリの兄弟ディレクトリや、.worktrees のような専用の無視されたフォルダ内にワークツリーを配置するなど、一貫した場所を決めます。これにより、ワークツリーの管理が容易になります。
  • 記述的なディレクトリ名を使用する: ブランチ名と一致するような、ワークツリーの目的を明確に示すディレクトリ名を使用します。例: ../feature-x, ../hotfix-y, ../review-pr-z
  • 不要になったワークツリーは定期的にクリーンアップする: git worktree removegit worktree prune を使用して、 clutter を避け、環境を整理します。これはディスクスペースの節約にも繋がります。
  • 1つのワークツリーにつき1つの機能: 異なる機能のためにワークツリーを再利用するのではなく、主要なタスクごとに新しいワークツリーを作成し、完了したらクリーンアップすることをお勧めします。これにより、コンテキストの分離が保たれ、混乱を防ぎます。
  • サブモジュールをすぐに初期化する: サブモジュールを使用している場合、ワークツリー作成後に git submodule update --init --recursive を必ず実行します。
  • データベースインスタンスの調整: 複数のワークツリーが同じデータベースにアクセスする場合、競合を避けるためにワークツリーごとに異なるデータベースを使用するなどの戦略を検討します。Docker Composeなどで環境を分離するのも良い方法です。
  • ベアークローンとワークツリーの組み合わせ: ベアークローン(git clone --bare)をメインのリポジトリとして使用し、そこから複数のワークツリーを作成することで、Gitデータと作業ディレクトリを明確に分離し、複数の長期ブランチの管理を容易にできます。

まとめ

この記事では、Git Worktreeの基本的な概念から、具体的なコマンド、そして緊急修正やPRレビューといった実務での活用シナリオ、さらには注意点とベストプラクティスまでを網羅的に解説しました。

Git Worktreeは、従来の git stash や複数リポジトリクローンといった手法につきまとったコンテキストスイッチのオーバーヘッドを劇的に削減し、開発者が複数のタスクをスムーズに並行して進めることを可能にします。

  • 瞬時のブランチ切り替えで、思考の中断を最小限に。
  • コンテキストの完全な分離で、IDEの再インデックス待ちや依存関係の再インストールから解放。
  • 真の並行開発で、時間のロスをなくし、生産性を最大化。

今日からあなたの開発ワークフローにGit Worktreeを取り入れ、爆速な並行開発を体験してください。より詳細な情報や最新のオプションについては、Git公式ドキュメント git-worktree を参照することをお勧めします。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?