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

名前

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 を使用せずに作業ツリーが削除された場合、リポジトリにある関連する管理ファイル(以下の「詳細」を参照)は最終的に自動的に削除されるか(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 を使用してチェックアウトを抑制し、sparse-checkout の設定などのカスタマイズを行うことができます。 git-read-tree[1] の "Sparse checkout" を参照してください。

--[no-]guess-remote

worktree add <path> で、<commit-ish> を指定せずに、HEAD から新しいブランチを作成する代わりに、<path> のベース名と一致するトラッキングブランチが 1 つのリモートにのみ存在する場合、新しいブランチをリモートトラッキングブランチに基づいて作成し、リモートトラッキングブランチを新しいブランチの "upstream" としてマークします。

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

--[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 で前の作業ツリーを指すことができます。

参照

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

一般に、すべての擬似参照は作業ツリーごとであり、refs/ で始まるすべての参照は共有されます。 擬似参照とは、$GIT_DIR/refs 内ではなく、$GIT_DIR の直下にある HEAD のようなものです。 ただし、例外があります。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=true の場合、core.bare を共有しないでください。

  • すべての作業ツリーで常にスパースチェックアウトを使用することが確実でない限り、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 で終了します。属性は、ラベルと値が1つのスペースで区切られてリストされます。ブール属性(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.quotePath の説明に従って引用符で囲まれます(git-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