设置和配置
获取和创建项目
基本快照
分支和合并
共享和更新项目
检查和比较
修补
调试
电子邮件
外部系统
服务器管理员
指南
管理
管道命令
- 2.43.2 → 2.47.0 无更改
- 2.43.1 02/09/24
- 2.42.2 → 2.43.0 无更改
- 2.42.1 11/02/23
- 2.42.0 08/21/23
- 2.39.1 → 2.41.2 无更改
- 2.39.0 12/12/22
- 2.36.1 → 2.38.5 无更改
- 2.36.0 04/18/22
- 2.35.1 → 2.35.8 无更改
- 2.35.0 01/24/22
- 2.33.1 → 2.34.8 无更改
- 2.33.0 08/16/21
- 2.31.1 → 2.32.7 无更改
- 2.31.0 03/15/21
- 2.30.1 → 2.30.9 无更改
- 2.30.0 12/27/20
- 2.29.1 → 2.29.3 无更改
- 2.29.0 10/19/20
- 2.28.1 无更改
- 2.28.0 07/27/20
- 2.22.1 → 2.27.1 无更改
- 2.22.0 06/07/19
- 2.20.1 → 2.21.4 无更改
- 2.20.0 12/09/18
- 2.19.3 → 2.19.6 无更改
- 2.19.2 11/21/18
- 2.19.1 无更改
- 2.19.0 09/10/18
- 2.18.1 → 2.18.5 无更改
- 2.18.0 06/21/18
- 2.17.1 → 2.17.6 无更改
- 2.17.0 04/02/18
- 2.16.6 12/06/19
- 2.14.6 → 2.15.4 无更改
- 2.13.7 05/22/18
- 2.12.5 09/22/17
- 2.11.4 无更改
- 2.10.5 09/22/17
- 2.9.5 07/30/17
- 2.8.6 无更改
- 2.7.6 07/30/17
- 2.6.7 05/05/17
- 2.5.6 05/05/17
概要
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] 创建的“主工作树”。存储库有一个主工作树(如果它不是裸存储库)和零个或多个链接的工作树。完成链接的工作树后,使用 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>
检出到其中。新工作树链接到当前存储库,共享除每个工作树文件(如HEAD
、index
等)之外的所有内容。为了方便起见,<commit-ish>
可以是裸的“-
”,它与@{-1}
同义。如果
<commit-ish>
是分支名称(称为<branch>
)并且未找到,并且未使用-b
或-B
或--detach
,但确实存在一个远程(称为<remote>
)中具有匹配名称的跟踪分支,则视为等效于$ git worktree add --track -b <branch> <path> <remote>/<branch>
如果该分支存在于多个远程中,并且其中一个由
checkout.defaultRemote
配置变量命名,我们将使用该变量来消除歧义,即使<branch>
在所有远程中并不唯一。将其设置为例如checkout.defaultRemote=origin
,如果<branch>
模棱两可但在origin
远程存在,则始终从那里检出远程分支。另请参见 git-config[1] 中的checkout.defaultRemote
。如果省略了
<commit-ish>
且未使用-b
或-B
或--detach
,则为了方便起见,新工作树将与一个名为$(basename <path>)
的分支(称为<branch>
)关联。如果<branch>
不存在,则会自动创建一个基于HEAD
的新分支,就像给出了-b <branch>
一样。如果<branch>
存在,它将在新工作树中检出,如果它没有在其他任何地方检出,否则命令将拒绝创建工作树(除非使用--force
)。如果省略了
<commit-ish>
,未使用--detach
或--orphan
,并且没有有效的本地分支(或如果指定了--guess-remote
则为远程分支),则为了方便起见,新工作树将与一个新的未创建的分支关联,该分支名为<branch>
(如果未使用-b
或-B
,则为$(basename <path>)
之后),就像将--orphan
传递给命令一样。如果存储库具有远程并且使用--guess-remote
,但不存在远程或本地分支,则命令将失败并显示警告,提醒用户先从远程获取(或通过使用-f/--force
覆盖)。 - list
-
列出每个工作树的详细信息。首先列出主工作树,然后列出每个链接的工作树。输出详细信息包括工作树是否为裸存储库、当前检出的修订版本、当前检出的分支(如果不存在则为“分离的 HEAD”)、如果工作树被锁定则为“已锁定”、如果工作树可以被
prune
命令修剪则为“可修剪”。 - 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
-
默认情况下,当
<commit-ish>
是分支名称并且已被另一个工作树检出,或者如果<path>
已分配给某个工作树但丢失(例如,如果<path>
被手动删除)时,add
会拒绝创建新的工作树。此选项会覆盖这些安全措施。要添加丢失但已锁定的工作树路径,请指定两次--force
。除非指定了两次
--force
,否则move
会拒绝移动已锁定的工作树。如果目标已分配给其他某个工作树但丢失(例如,如果<new-path>
被手动删除),则--force
允许移动继续;如果目标已锁定,请指定两次--force
。除非使用
--force
,否则remove
会拒绝删除不干净的工作树。要删除已锁定的工作树,请指定两次--force
。 - -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>
时,Git不会从HEAD
创建新分支。如果存在一个远程分支,其名称与<path>
的基本名称完全匹配,则 Git 会将新分支基于此远程跟踪分支创建,并将此远程跟踪分支标记为新分支的“上游”分支。也可以使用
worktree.guessRemote
配置选项将此设置为默认行为。 - --[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>
时间,则将其注释为可修剪。 - --reason <string>
-
使用
lock
命令或add --lock
选项时,说明工作树被锁定的原因。 - <worktree>
-
工作树可以通过路径来识别,路径可以是相对路径或绝对路径。
如果工作树路径中的最后一个路径组件在所有工作树中是唯一的,则可以使用它来识别工作树。例如,如果您只有两个工作树,分别位于
/abc/def/ghi
和/abc/def/ggg
,则ghi
或def/ghi
足以指向前一个工作树。
引用
当使用多个工作树时,某些引用在所有工作树之间共享,而其他引用则特定于单个工作树。例如HEAD
,每个工作树的HEAD
都不同。本节介绍共享规则以及如何从另一个工作树访问一个工作树的引用。
通常,所有伪引用都是每个工作树的,所有以refs/
开头的引用都是共享的。伪引用是指像HEAD
这样的引用,它们直接位于$GIT_DIR
下,而不是位于$GIT_DIR/refs
内部。但是,也有一些例外:refs/bisect
、refs/worktree
和refs/rewritten
内部的引用不共享。
每个工作树的引用仍然可以通过两个特殊路径从另一个工作树访问,即main-worktree
和worktrees
。前者用于访问主工作树的每个工作树引用,而后者用于访问所有链接的工作树。
例如,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.bare
和core.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/bisect
、refs/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
命令有两种输出格式。默认格式在单行上显示带列的详细信息。例如
$ 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
请注意,如果提供附加信息,则注释将移动到下一行,否则它将保留在与工作树相同的行上。
瓷器格式
瓷器格式每个属性一行。如果给出-z
,则行以NUL而不是换行符结尾。属性以标签和值列出,标签和值之间用单个空格分隔。布尔属性(如bare
和detached
)仅列出标签,并且仅在值为真时存在。某些属性(如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]套件的一部分