日本語 ▾ トピック ▾ 最新バージョン ▾ git-worktree は 2.48.0 で最終更新されました

名前

git-worktree - 複数のワーキングツリーを管理する

概要

git worktree add [-f] [--detach] [--checkout] [--lock [--reason <string>]]
		   [--orphan] [(-b | -B) <new-branch>] <path> [<commit-ish>]
git worktree list [-v | --porcelain [-z]]
git worktree lock [--reason <string>] <worktree>
git worktree move <worktree> <new-path>
git worktree prune [-n] [-v] [--expire <expire>]
git worktree remove [-f] <worktree>
git worktree repair [<path>…​]
git worktree unlock <worktree>

説明

同じリポジトリにアタッチされた複数のワーキングツリーを管理します。

Gitリポジトリは複数のワーキングツリーをサポートできるため、一度に複数のブランチをチェックアウトできます。git worktree add を使用すると、新しいワーキングツリーがリポジトリに関連付けられ、同じリポジトリ内の他のワーキングツリーと区別するための追加のメタデータが追加されます。このワーキングツリーとメタデータは「ワークツリー」と呼ばれます。

この新しいワークツリーは、git-init[1] または git-clone[1] によって準備された「メインワークツリー」とは対照的に、「リンクされたワークツリー」と呼ばれます。リポジトリには1つのメインワークツリー(ベアリポジトリでない場合)とゼロ以上のリンクされたワークツリーがあります。リンクされたワークツリーが不要になったら、git worktree remove を使用して削除します。

最もシンプルな形式では、git worktree add <path><path> の最後のコンポーネントを名前に持つ新しいブランチを自動的に作成します。これは新しいトピックで作業する予定の場合に便利です。例えば、git worktree add ../hotfix は新しいブランチ hotfix を作成し、パス ../hotfix にチェックアウトします。代わりに、既存のブランチを新しいワークツリーで作業するには、git worktree add <path> <branch> を使用します。一方、既存の開発を妨げずにいくつかの実験的な変更やテストを行う予定がある場合は、どのブランチにも関連付けられていない一時的なワークツリーを作成するのが便利な場合があります。例えば、git worktree add -d <path> は現在のブランチと同じコミットにデタッチされた HEAD を持つ新しいワークツリーを作成します。

git worktree remove を使用せずにワーキングツリーが削除された場合、リポジトリに存在する関連する管理ファイル(下記の「詳細」を参照)は最終的に自動的に削除されるか(git-config[1]gc.worktreePruneExpire を参照)、またはメインまたはリンクされたワークツリーで git worktree prune を実行して、古くなった管理ファイルをクリーンアップできます。

リンクされたワークツリーのワーキングツリーが、常にマウントされているわけではないポータブルデバイスやネットワーク共有に保存されている場合、git worktree lock コマンドを発行し、必要に応じて --reason を指定してワークツリーがロックされている理由を説明することで、管理ファイルがプルーニングされるのを防ぐことができます。

コマンド

add <path> [<commit-ish>]

<path> にワークツリーを作成し、その中に <commit-ish> をチェックアウトします。新しいワークツリーは現在のリポジトリにリンクされ、HEADindex などのワークツリーごとのファイルを除き、すべてを共有します。便宜上、<commit-ish> はベアな「-」でも構いません。これは @{-1} と同義です。

<commit-ish> がブランチ名(<branch> と呼ぶ)で見つからず、-b-B--detach も使用されていないが、ちょうど1つのリモート(<remote> と呼ぶ)に一致する名前の追跡ブランチが存在する場合、以下と同等として扱います。

$ git worktree add --track -b <branch> <path> <remote>/<branch>

ブランチが複数のリモートに存在し、そのうちの1つが checkout.defaultRemote 設定変数によって名前が指定されている場合、<branch> がすべてのリモートで一意でない場合でも、曖昧さを解決するためにそのリモートを使用します。例えば、checkout.defaultRemote=origin に設定すると、<branch> が曖昧でも origin リモートに存在する場合は、常にそこからリモートブランチをチェックアウトします。git-config[1]checkout.defaultRemote も参照してください。

<commit-ish> が省略され、-b-B--detach も使用されていない場合、便宜上、新しいワークツリーは $(basename <path>) にちなんで名付けられたブランチ(<branch> と呼ぶ)に関連付けられます。<branch> が存在しない場合、-b <branch> が指定されたかのように、HEAD に基づく新しいブランチが自動的に作成されます。<branch> が存在する場合、それが他の場所でチェックアウトされていなければ、新しいワークツリーでチェックアウトされます。そうでない場合、コマンドはワークツリーの作成を拒否します(--force が使用されない限り)。

<commit-ish> が省略され、--detach--orphan も使用されておらず、有効なローカルブランチ(または --guess-remote が指定されている場合はリモートブランチ)がない場合、便宜上、新しいワークツリーは <branch> という名前の新しい誕生前のブランチ(-b-B も使用されていない場合は $(basename <path>) の後)に関連付けられます。これは --orphan がコマンドに渡されたかのように扱われます。リポジトリにリモートがあり、--guess-remote が使用されているが、リモートまたはローカルブランチが存在しない場合、コマンドはユーザーにまずリモートからフェッチするように促す警告(または -f/--force を使用して上書きするよう促す)とともに失敗します。

list

各ワークツリーの詳細をリスト表示します。最初にメインワークツリーがリストされ、次に各リンクされたワークツリーが続きます。出力の詳細には、ワークツリーがベアであるかどうか、現在チェックアウトされているリビジョン、現在チェックアウトされているブランチ(または何もない場合は「detached HEAD」)、ワークツリーがロックされている場合は「locked」、prune コマンドでワークツリーをプルーニングできる場合は「prunable」が含まれます。

lock

ワークツリーがポータブルデバイスまたはネットワーク共有上にあり、常にマウントされているわけではない場合、管理ファイルが自動的にプルーニングされるのを防ぐためにロックします。これにより、移動または削除も防止されます。オプションで、--reason を使用してロックの理由を指定します。

move

ワークツリーを新しい場所に移動します。このコマンドでは、メインワークツリーまたはサブモジュールを含むリンクされたワークツリーは移動できないことに注意してください。(ただし、git worktree repair コマンドを使用すると、メインワークツリーを手動で移動した場合でも、リンクされたワークツリーとの接続を再確立できます。)

prune

$GIT_DIR/worktrees 内のワークツリー情報をプルーニングします。

remove

ワークツリーを削除します。クリーンなワークツリー(追跡されていないファイルがなく、追跡されているファイルに変更がない)のみが削除できます。汚れたワークツリーやサブモジュールのあるワークツリーは --force で削除できます。メインワークツリーは削除できません。

repair [<path>…​]

外部要因により破損または古くなったワークツリー管理ファイルがあれば、可能な限り修復します。

例えば、メインワークツリー(またはベアリポジトリ)が移動された場合、リンクされたワークツリーはそれを見つけられなくなります。メインワークツリーで repair を実行すると、リンクされたワークツリーからメインワークツリーへの接続が再確立されます。

同様に、git worktree move を使用せずにリンクされたワークツリーのワーキングツリーが移動された場合、メインワークツリー(またはベアリポジトリ)はそれを見つけることができません。最近移動されたワークツリー内で repair を実行すると、接続が再確立されます。複数のリンクされたワークツリーが移動された場合、任意のワークツリーから repair を実行し、各ツリーの新しい <path> を引数として指定すると、指定されたすべてのパスへの接続が再確立されます。

メインワークツリーとリンクされたワークツリーの両方が手動で移動またはコピーされた場合、メインワークツリーで repair を実行し、各リンクされたワークツリーの新しい <path> を指定すると、両方向のすべての接続が再確立されます。

unlock

ワークツリーのロックを解除し、プルーニング、移動、または削除を可能にします。

オプション

-f
--force

デフォルトでは、add<commit-ish> がブランチ名で、既に別のワークツリーによってチェックアウトされている場合、または <path> が既に何らかのワークツリーに割り当てられているが存在しない場合(例えば、<path> が手動で削除された場合)には、新しいワークツリーの作成を拒否します。このオプションはこれらの安全対策を上書きします。不足しているがロックされているワークツリーパスを追加するには、--force を2回指定します。

move は、--force が2回指定されない限り、ロックされたワークツリーの移動を拒否します。宛先が既に他のワークツリーに割り当てられているが存在しない場合(例えば、<new-path> が手動で削除された場合)には、--force で移動を進めることができます。宛先がロックされている場合は --force を2回使用します。

remove は、--force が使用されない限り、クリーンでないワークツリーの削除を拒否します。ロックされたワークツリーを削除するには、--force を2回指定します。

-b <new-branch>
-B <new-branch>

add と共に、<commit-ish> を開始点として <new-branch> という名前の新しいブランチを作成し、その <new-branch> を新しいワークツリーにチェックアウトします。<commit-ish> が省略された場合、デフォルトは HEAD となります。デフォルトでは、-b は既に存在する新しいブランチの作成を拒否します。-B はこの安全対策を上書きし、<new-branch><commit-ish> にリセットします。

-d
--detach

add と共に、新しいワークツリーで HEAD をデタッチします。git-checkout[1] の「DETACHED HEAD」を参照してください。

--[no-]checkout

デフォルトでは、add<commit-ish> をチェックアウトしますが、--no-checkout を使用して、スパースチェックアウトの構成などのカスタマイズを行うためにチェックアウトを抑制できます。git-read-tree[1] の「Sparse checkout」を参照してください。

--[no-]guess-remote

worktree add <path><commit-ish> なしの場合、HEAD から新しいブランチを作成する代わりに、<path> のベース名に一致する追跡ブランチがちょうど1つのリモートに存在する場合、新しいブランチをそのリモート追跡ブランチに基づいて作成し、リモート追跡ブランチを新しいブランチの「アップストリーム」としてマークします。

これは worktree.guessRemote 設定オプションを使用してデフォルトの動作として設定することもできます。

--[no-]relative-paths

相対パスまたは絶対パス(デフォルト)を使用してワークツリーをリンクします。worktree.useRelativePaths 設定オプションを上書きします。git-config[1] を参照してください。

repair と共に使用すると、リンクが正しくても絶対/相対の不一致があれば、リンクファイルが更新されます。

--[no-]track

新しいブランチを作成する際、<commit-ish> がブランチの場合、それを新しいブランチの「アップストリーム」としてマークします。<commit-ish> がリモート追跡ブランチの場合、これがデフォルトです。詳細は git-branch[1]--track を参照してください。

--lock

作成後もワークツリーをロックしたままにします。これは git worktree add の後に git worktree lock を実行するのと同等ですが、競合状態はありません。

-n
--dry-run

prune と共に、何も削除せずに、削除されるであろうものを報告するだけです。

--orphan

add と共に、新しいワークツリーとインデックスを空にし、ワークツリーを <new-branch> という名前の新しい未誕生ブランチに関連付けます。

--porcelain

list と共に、スクリプトで解析しやすい形式で出力します。この形式はGitのバージョン間で安定しており、ユーザー設定に依存しません。これを -z と組み合わせて使用することをお勧めします。詳細は以下を参照してください。

-z

list--porcelain が指定されている場合、各行を改行ではなく NUL で終端します。これにより、ワークツリーパスに改行文字が含まれている場合でも出力を解析できます。

-q
--quiet

add と共に、フィードバックメッセージを抑制します。

-v
--verbose

prune と共に、すべての削除を報告します。

list と共に、ワークツリーに関する追加情報を出力します(以下を参照)。

--expire <time>

prune と共に、<time> よりも古い未使用のワークツリーのみを期限切れにします。

list と共に、不足しているワークツリーが <time> よりも古い場合、prunable として注釈を付けます。

--reason <string>

lock または add --lock と共に、ワークツリーがロックされた理由の説明。

<worktree>

ワークツリーは、相対パスまたは絶対パスで識別できます。

ワークツリーのパスの最後のパスコンポーネントがワークツリー間で一意である場合、それを使用してワークツリーを識別できます。例えば、/abc/def/ghi/abc/def/ggg に2つのワークツリーしかない場合、ghi または def/ghi は前者のワークツリーを指すのに十分です。

参照

複数のワークツリーを使用する場合、一部の参照はすべてのワークツリーで共有されますが、その他の参照は個々のワークツリーに固有です。一例として HEAD があり、これは各ワークツリーで異なります。このセクションでは、共有ルールと、あるワークツリーから別のワークツリーの参照にアクセスする方法について説明します。

一般に、すべての擬似参照はワークツリーごとに異なり、refs/ で始まるすべての参照は共有されます。擬似参照とは、HEAD のように $GIT_DIR/refs の内部ではなく $GIT_DIR の直下にあるものです。ただし、例外があります。refs/bisectrefs/worktree、および refs/rewritten 内の参照は共有されません。

ワークツリーごとの参照には、main-worktreeworktrees という2つの特別なパスを介して、別のワークツリーからアクセスできます。前者はメインワークツリーのワークツリーごとの参照にアクセスでき、後者はすべてのリンクされたワークツリーにアクセスできます。

例えば、main-worktree/HEAD または main-worktree/refs/bisect/good は、それぞれメインワークツリーの HEAD および refs/bisect/good と同じ値に解決されます。同様に、worktrees/foo/HEAD または worktrees/bar/refs/bisect/bad$GIT_COMMON_DIR/worktrees/foo/HEAD および $GIT_COMMON_DIR/worktrees/bar/refs/bisect/bad と同じです。

参照にアクセスするには、$GIT_DIR の中を直接覗くのではなく、git-rev-parse[1]git-update-ref[1] のようなコマンドを使用するのが最善です。これらのコマンドは参照を正しく処理します。

設定ファイル

デフォルトでは、リポジトリの config ファイルはすべてのワークツリーで共有されます。core.bare または core.worktree の構成変数が共通の設定ファイルに存在し、extensions.worktreeConfig が無効になっている場合、それらはメインワークツリーにのみ適用されます。

ワークツリー固有の設定を行うには、worktreeConfig 拡張機能をオンにします。

$ git config extensions.worktreeConfig true

このモードでは、特定の設定は git rev-parse --git-path config.worktree が指すパスに保持されます。git config --worktree を使用して、このファイルに設定を追加または更新できます。古いGitバージョンは、この拡張機能が有効なリポジトリへのアクセスを拒否します。

このファイルでは、core.barecore.worktree の例外はなくなります。$GIT_DIR/config にそれらが存在する場合は、メインワークツリーの config.worktree に移動する必要があります。また、この機会に、すべてのワークツリーで共有したくない他の設定を見直して移動することもできます。

  • core.worktree は決して共有されるべきではありません。

  • core.bare は、値が core.bare=true の場合は共有すべきではありません。

  • core.sparseCheckout は、すべてのワークツリーで常にスパースチェックアウトを使用することが確実な場合を除き、共有すべきではありません。

詳細については、git-config[1]extensions.worktreeConfig のドキュメントを参照してください。

詳細

各リンクされたワークツリーは、リポジトリの $GIT_DIR/worktrees ディレクトリにプライベートなサブディレクトリを持っています。プライベートサブディレクトリの名前は通常、リンクされたワークツリーのパスのベース名であり、一意にするために数値が付加されることがあります。例えば、$GIT_DIR=/path/main/.git の場合、コマンド git worktree add /path/other/test-next next/path/other/test-next にリンクされたワークツリーを作成し、同時に $GIT_DIR/worktrees/test-next ディレクトリ(または test-next が既に使用されている場合は $GIT_DIR/worktrees/test-next1)を作成します。

リンクされたワークツリー内では、$GIT_DIR はこのプライベートディレクトリを指すように設定され(例では /path/main/.git/worktrees/test-next)、$GIT_COMMON_DIR はメインワークツリーの $GIT_DIR を指すように設定されます(例では /path/main/.git)。これらの設定は、リンクされたワークツリーの最上位ディレクトリにある .git ファイルで行われます。

git rev-parse --git-path を介したパス解決は、パスに応じて $GIT_DIR または $GIT_COMMON_DIR のいずれかを使用します。例えば、リンクされたワークツリーで git rev-parse --git-path HEAD/path/main/.git/worktrees/test-next/HEAD/path/other/test-next/.git/HEAD/path/main/.git/HEAD ではない)を返し、git rev-parse --git-path refs/heads/master$GIT_COMMON_DIR を使用して /path/main/.git/refs/heads/master を返します。これは、refs/bisectrefs/worktree、および refs/rewritten を除く参照はすべてのワークツリーで共有されるためです。

詳細については gitrepository-layout[5] を参照してください。$GIT_DIR の中にあるものに直接アクセスする必要がある場合、パスが $GIT_DIR に属するか $GIT_COMMON_DIR に属するかについて仮定しないことが経験則です。最終的なパスを取得するには git rev-parse --git-path を使用してください。

リンクされたワークツリーを手動で移動した場合、エントリのディレクトリにある gitdir ファイルを更新する必要があります。例えば、リンクされたワークツリーが /newpath/test-next に移動され、その .git ファイルが /path/main/.git/worktrees/test-next を指している場合、/path/main/.git/worktrees/test-next/gitdir を更新して代わりに /newpath/test-next を参照するようにします。さらに良いのは、git worktree repair を実行して接続を自動的に再確立することです。

$GIT_DIR/worktrees エントリがプルーニングされるのを防ぐため(エントリのワークツリーがポータブルデバイスに保存されている場合など、一部の状況で役立ちます)、git worktree lock コマンドを使用します。これにより、エントリのディレクトリに locked という名前のファイルが追加されます。このファイルには、ロックの理由がプレーンテキストで含まれています。例えば、リンクされたワークツリーの .git ファイルが /path/main/.git/worktrees/test-next を指している場合、/path/main/.git/worktrees/test-next/locked という名前のファイルは、test-next エントリがプルーニングされるのを防ぎます。詳細については gitrepository-layout[5] を参照してください。

extensions.worktreeConfig が有効になっている場合、設定ファイル .git/worktrees/<id>/config.worktree.git/config の後に読み込まれます。

リスト出力形式

worktree list コマンドには2つの出力形式があります。デフォルト形式は、詳細を1行に列で表示します。例:

$ git worktree list
/path/to/bare-source            (bare)
/path/to/linked-worktree        abcd1234 [master]
/path/to/other-linked-worktree  1234abc  (detached HEAD)

このコマンドは、各ワークツリーの状態に応じて注釈も表示します。これらの注釈は次のとおりです。

  • ワークツリーがロックされている場合は locked

  • git worktree prune でワークツリーをプルーニングできる場合は prunable

$ git worktree list
/path/to/linked-worktree    abcd1234 [master]
/path/to/locked-worktree    acbd5678 (brancha) locked
/path/to/prunable-worktree  5678abc  (detached HEAD) prunable

これらの注釈には理由も利用できる場合があり、これは詳細モードで確認できます。その場合、注釈は次の行にインデントされて移動し、その後に追加情報が続きます。

$ git worktree list --verbose
/path/to/linked-worktree              abcd1234 [master]
/path/to/locked-worktree-no-reason    abcd5678 (detached HEAD) locked
/path/to/locked-worktree-with-reason  1234abcd (brancha)
	locked: worktree path is mounted on a portable device
/path/to/prunable-worktree            5678abc1 (detached HEAD)
	prunable: gitdir file points to non-existent location

追加情報がある場合、注釈は次の行に移動しますが、そうでない場合はワークツリーと同じ行に留まることに注意してください。

ポーセリン形式

ポーセリン形式では、属性ごとに1行が割り当てられます。-z が指定されている場合、行は改行ではなく NUL で終端されます。属性は、ラベルと値が単一のスペースで区切られてリストされます。ブール型属性(baredetached など)はラベルのみがリストされ、値が true の場合にのみ存在します。一部の属性(locked など)は、理由が利用できるかどうかに応じて、ラベルのみでリストされるか、値と共にリストされます。ワークツリーの最初の属性は常に worktree であり、空行はレコードの終わりを示します。例:

$ git worktree list --porcelain
worktree /path/to/bare-source
bare

worktree /path/to/linked-worktree
HEAD abcd1234abcd1234abcd1234abcd1234abcd1234
branch refs/heads/master

worktree /path/to/other-linked-worktree
HEAD 1234abc1234abc1234abc1234abc1234abc1234a
detached

worktree /path/to/linked-worktree-locked-no-reason
HEAD 5678abc5678abc5678abc5678abc5678abc5678c
branch refs/heads/locked-no-reason
locked

worktree /path/to/linked-worktree-locked-with-reason
HEAD 3456def3456def3456def3456def3456def3456b
branch refs/heads/locked-with-reason
locked reason why is locked

worktree /path/to/linked-worktree-prunable
HEAD 1233def1234def1234def1234def1234def1234b
detached
prunable gitdir file points to non-existent location

-z が使用されない限り、ロック理由内の改行などの「通常でない」文字はエスケープされ、理由全体は構成変数 core.quotePathgit-config[1] を参照)で説明されているように引用符で囲まれます。例:

$ git worktree list --porcelain
...
locked "reason\nwhy is locked"
...

リファクタリングセッションの途中で上司が来て、すぐに何かを修正するように要求しました。通常は git-stash[1] を使って変更を一時的に保存するかもしれませんが、あなたのワーキングツリーは(新規ファイル、移動されたファイル、削除されたファイル、その他の散らばった断片など)混乱状態にあるため、それを動かしたくありません。代わりに、一時的なリンクされたワークツリーを作成して緊急修正を行い、完了したらそれを削除し、以前のリファクタリングセッションを再開します。

$ git worktree add -b emergency-fix ../temp master
$ pushd ../temp
# ... hack hack hack ...
$ git commit -a -m 'emergency fix for boss'
$ popd
$ git worktree remove ../temp

バグ

複数チェックアウトは一般にまだ実験段階であり、サブモジュールのサポートは不完全です。スーパープロジェクトの複数チェックアウトを行うことは推奨されません。

GIT

git[1]スイートの一部

scroll-to-top