Posts Git git worktreeで並行作業をちょっと便利にする

git worktreeで並行作業をちょっと便利にする

はじめに

皆さんはgit worktreeというgitコマンドを利用したことがあるでしょうか。 私は恥ずかしながら、最近までこのコマンドの存在さえ知りませんでした。

このコマンドに出会ったのは、巷で話題のClaude Codeについて調べていた時のことです。 Anthropic社が公開しているClaude Code: Best practices for agentic codingというドキュメント内に、Use git worktreesという章がありました。

調べていると、2つ以上並行してClaude Codeを利用する以外にも便利に利用できそうであったため、備忘録を兼ねて記事にしたいと思います

TL;DR

  • git worktreeというコマンドを利用することで、独立した作業ディレクトリを作成することができる。 - その作業ディレクトリは、cloneしたリポジトリとコミットログなどを共有している
  • 複数ブランチをまたいだ開発時に、作業内容をstashしたり一旦commitしたりすることなく、別ブランチの作業ディレクトリを作成できるため、非常に便利

git worktreeコマンドとは

git worktreeは、同一リポジトリに対して複数の作業ディレクトリを作成できるGitコマンドです。 通常は、cloneしたディレクトリ上でブランチを適宜切り替えながら作業すると思いますが、git worktreeを利用することで複数の作業ディレクトリを作成できます。 ワークツリーの主な操作として、この記事では以下のコマンドを解説します。

  • git worktree add
  • git worktree list
  • git worktree remove
  • git worktree prune
  • git worktree lock
  • git worktree unlock

git worktree add

ワークツリー(作業ディレクトリ)を新たに作成するコマンドです。 以下のコマンドを実行すると、<ディレクトリの作成先のパス><対象ブランチ名>がチェックアウトされた状態の独立した作業ディレクトリを作成できます。

$ git worktree add <ディレクトリの作成先のパ> <対象のブランチ>
Preparing worktree (checking out '<対象のブランチ名>')
HEAD is now at <コミットID> <コミットメッセー>

また、制約として、既に別のワークツリーでチェックアウトしているブランチを指定するとエラーが発生します。 複数のワークツリーから一つのブランチに対して作業を行うことはできません。

また、新しいブランチを作成して、そのブランチのワークツリーを作るには-bオプションを利用できます

$ git worktree add <ディレクトリのパ> -b <対象のブランチ>
Preparing worktree (checking out '<対象のブランチ名>')
HEAD is now at <コミットID> <コミットメッセー>

git worktree list

現在作成されているワークツリーの一覧が表示できます

$ git worktree list
<ディレクトリパス> <HEADのコミットID> [<ブランチ名>]
<ディレクトリパス> <HEADのコミットID> [<ブランチ名>]
<ディレクトリパス> <HEADのコミットID> [<ブランチ名>]
……

git worktree remove

指定したワークツリーを削除するコマンドです。 ワークツリーの参照だけでなく、ディレクトリの内容も削除されます。

$ git worktree remove <ディレクトリのパ>

git worktree prune

不要なワークツリーの参照が削除されます。 例えば、作成したワークツリーのディレクトリがrmコマンドで削除された場合、実際にはワークツリーは存在しませんが、参照が残ってしまいます(git worktree listでも表示されます)。 git worktree pruneを実行することで、実際には存在しないワークツリーの参照を削除することができます。

$ git worktree prune

git worktree lock

ワークツリーをremovepruneによる削除から保護することできます。 例えば、クラウドストレージ上のワークツリーがpruneコマンドで誤って削除されるような悲劇を防ぐことができます。

$ git worktree lock <ディレクトリパ>

$ git worktree remove <ディレクトリパ>
fatal: cannot remove a locked working tree;
use 'remove -f -f' to override or unlock first

git worktree unlock

ワークツリーのロックを解除できます。

$ git worktree unlock <ディレクトリパ>

活用方法

ワークツリーの作成が有効なのは、複数のブランチで並行して作業を進めたい場合です。

例えば、自分がfeture-Aブランチで作業中に、feature-Bブランチのレビューを依頼されたとします。 ワークツリーを新規に作成しない場合には、以下の手順を踏むことになります。

  1. feature-Aブランチの変更をstash、もしくはcommitする
  2. feature-Bブランチにチェックアウト
  3. feature-Bブランチのレビューを実施
  4. feature-Aブランチにチェックアウトして、作業再開

これが、ワークツリーを作成するととてもシンプルになり、かつfeature-Aブランチの変更を退避する必要がありません。

  1. feature-Bブランチのワークツリーを作成
  2. feature-Bブランチのレビューを実施
  3. 不要になったfeature-Bのワークツリーは削除

もちろん、Claude Codeを利用するような、2つ以上の独立した修正を並行して進めるような場合にも効果を発揮します。

リポジトリを複数cloneする運用との違い

実は、以前からレビュー時の一時的な修正内容のstashを煩わしく感じていました。 その解決手段として自分が行っていたのは、レビュー専用に同じRepositoryをもう一つクローンしておくという解決策でした。

この方法に比べて、ワークツリーの作成にはいくつかの利点があると感じています。

  • .gitファイルが共有されることで、コミット履歴をfetchする必要なく共有できます
  • git worktree listコマンドで、ワークツリーのパスを一元管理できます。cloneを複数行った場合には、自分でパスを覚えておく必要があります。
  • repositoryのcloneはそのサイズによってはかなりの時間がかかります。ワークツリーの作成は、cloneに比べて短時間で終了します。

まとめ

git worktreeコマンドを活用することで、並行作業をシンプルな方法で進めることができます。 特に作業途中でレビューや緊急対応を行う必要があるときに、stashによる修正内容の対比を行う必要がないので便利です。 また、リポジトリを複数クローンしておく方法と比べても、その準備と管理のしやすさ両方に利点がありそうです。

Claude Codeでの同時並行な作業だけでなく、レビュー時などに積極的に利用できる機能だと感じました!