日本語 ▾ トピック ▾ 最新バージョン ▾ 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つのメインワーキングツリー(ベアリポジトリでない場合)と、0個以上のリンクされたワーキングツリーがあります。リンクされたワーキングツリーが不要になったら、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を使用せずに削除された場合、リポジトリに存在する関連する管理ファイル(下記の「DETAILS」を参照)は、最終的に自動的に削除されます(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が指定されている場合はリモートブランチ)がない場合、便宜上、新しいワークツリーは、コマンドに--orphanが渡されたかのように、<branch>-bまたは-Bのいずれも使用されていない場合は$(basename <path>)にちなんだ名前)という名前の新しいアンボーンブランチに関連付けられます。リポジトリにリモートがあり、--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を実行すると、接続が再確立されます。複数のリンクされたワーキングツリーが移動された場合、任意のワークツリーから各ツリーの新しい<path>を引数としてrepairを実行すると、指定されたすべてのパスへの接続が再確立されます。

メインワーキングツリーとリンクされたワーキングツリーの両方が手動で移動またはコピーされた場合、メインワーキングツリーで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つのリモートに存在する場合、そのリモートトラッキングブランチを新しいブランチのベースとし、リモートトラッキングブランチを新しいブランチの「upstream」としてマークします。

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

--[no-]relative-paths

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

repairを使用すると、リンクが正しい場合でも、絶対/相対パスの不一致がある場合、リンクファイルが更新されます。

--[no-]track

新しいブランチを作成する際、<commit-ish>がブランチである場合、新しいブランチの「upstream」としてマークします。<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>より古い場合、剪定可能と注釈を付けます。

--reason <string>

lockまたはadd --lockでは、ワークツリーがロックされている理由を説明します。

<worktree>

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

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

参照

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

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

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

例えば、main-worktree/HEADまたはmain-worktree/refs/bisect/goodは、それぞれメインワーキングツリーのHEADrefs/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/worktreerefs/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エントリが剪定されるのを防ぐには(これは、エントリのワークツリーがポータブルデバイスに保存されている場合など、一部の状況で役立ちます)、エントリのディレクトリにlockedというファイルを追加するgit worktree lockコマンドを使用します。このファイルには、理由がプレーンテキストで含まれています。例えば、リンクされたワークツリーの.gitファイルが/path/main/.git/worktrees/test-nextを指している場合、/path/main/.git/worktrees/test-next/lockedという名前のファイルが存在すると、test-nextエントリの剪定が防止されます。詳細はgitrepository-layout[5]を参照してください。

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

LIST出力形式

worktree listコマンドには2つの出力形式があります。デフォルト形式は、詳細をカラム形式の単一行で表示します。例えば

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

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

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

  • prunable:ワークツリーがgit worktree pruneを介して剪定できる場合。

$ 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