设置和配置
获取和创建项目
基本快照
分支和合并
共享和更新项目
检查和比较
补丁
调试
电子邮件
外部系统
服务器管理
指南
管理
底层命令
- 2.48.1 → 2.49.0 没有更改
-
2.48.0
2025-01-10
- 2.43.2 → 2.47.2 没有更改
-
2.43.1
2024-02-09
- 2.42.2 → 2.43.0 没有更改
-
2.42.1
2023-11-02
-
2.42.0
2023-08-21
- 2.39.1 → 2.41.3 没有更改
-
2.39.0
2022-12-12
- 2.36.1 → 2.38.5 没有更改
-
2.36.0
2022-04-18
- 2.35.1 → 2.35.8 没有更改
-
2.35.0
2022-01-24
- 2.33.1 → 2.34.8 没有更改
-
2.33.0
2021-08-16
- 2.31.1 → 2.32.7 没有更改
-
2.31.0
2021-03-15
- 2.30.1 → 2.30.9 没有更改
-
2.30.0
2020-12-27
- 2.29.1 → 2.29.3 没有更改
-
2.29.0
2020-10-19
- 2.28.1 没有更改
-
2.28.0
2020-07-27
- 2.22.1 → 2.27.1 没有更改
-
2.22.0
2019-06-07
- 2.20.1 → 2.21.4 没有更改
-
2.20.0
2018-12-09
- 2.19.3 → 2.19.6 没有更改
-
2.19.2
2018-11-21
- 2.19.1 没有更改
-
2.19.0
2018-09-10
- 2.18.1 → 2.18.5 没有更改
-
2.18.0
2018-06-21
- 2.17.1 → 2.17.6 没有更改
-
2.17.0
2018-04-02
-
2.16.6
2019-12-06
- 2.14.6 → 2.15.4 没有更改
-
2.13.7
2018-05-22
-
2.12.5
2017-09-22
- 2.11.4 没有更改
-
2.10.5
2017-09-22
-
2.9.5
2017-07-30
- 2.8.6 没有更改
-
2.7.6
2017-07-30
-
2.6.7
2017-05-05
-
2.5.6
2017-05-05
概要
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
,以便始终从origin
远程存储库中检出远程分支(如果<branch>
是模糊的,但在origin
远程存储库中存在)。 另请参阅 git-config[1] 中的checkout.defaultRemote
。如果省略了
<commit-ish>
并且未使用-b
、-B
或--detach
,那么为了方便起见,新的工作树会与一个分支(称之为<branch>
)相关联,该分支以$(basename <path>)
命名。如果<branch>
不存在,则会自动创建一个基于HEAD
的新分支,就好像给出了-b <branch>
一样。如果<branch>
确实存在,则它将在新的工作树中检出,如果它未在其他任何地方检出,否则该命令将拒绝创建工作树(除非使用--force
)。如果省略了
<commit-ish>
,既没有使用--detach
,也没有使用--orphan
,并且没有有效的本地分支(或者如果指定了--guess-remote
则没有远程分支),那么为了方便起见,新的工作树会与一个名为<branch>
的新未出生的分支相关联(如果既没有使用-b
也没有使用-B
,则按照$(basename <path>)
命名),就好像--orphan
被传递给命令一样。 如果仓库有一个远程仓库并且使用了--guess-remote
,但没有远程或本地分支存在,那么该命令将失败,并显示一个警告,提醒用户首先从其远程仓库获取(或者使用-f/--force
覆盖)。 - list
-
列出每个工作树的详细信息。 首先列出主工作树,然后列出每个链接的工作树。 输出详细信息包括工作树是否为 bare,当前检出的修订版本,当前检出的分支(如果没有,则为“分离的 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
-
默认情况下,当
<commit-ish>
是一个分支名称并且已被另一个工作树检出时,或者如果<path>
已分配给某个工作树但已丢失(例如,如果手动删除了<path>
),add
将拒绝创建新的工作树。 此选项会覆盖这些安全措施。 要添加丢失但锁定的工作树路径,请指定--force
两次。除非指定
--force
两次,否则move
拒绝移动锁定的工作树。 如果目标已分配给其他工作树但已丢失(例如,如果手动删除了<new-path>
),则--force
允许继续移动; 如果目标被锁定,请使用--force
两次。除非使用
--force
,否则remove
拒绝删除不干净的工作树。 要删除锁定的工作树,请指定--force
两次。 - -b <new-branch>
- -B <new-branch>
-
使用
add
,创建一个名为<new-branch>
的新分支,从<commit-ish>
开始,并将<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>
的基本名称匹配的跟踪分支时,将新分支建立在该远程跟踪分支上,并将该远程跟踪分支标记为新分支的“上游”。也可以使用
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>
旧,则将其标记为可修剪。 - --reason <string>
-
使用
lock
或add --lock
,解释工作目录被锁定的原因。 - <worktree>
-
可以通过路径(相对或绝对路径)来标识工作目录。
如果工作目录路径中的最后一个路径组件在工作目录中是唯一的,则可以使用它来标识工作目录。例如,如果您只有两个工作目录,分别位于
/abc/def/ghi
和/abc/def/ggg
,则ghi
或def/ghi
足以指向前者工作目录。
REFS
使用多个工作目录时,某些引用在所有工作目录之间共享,但其他引用特定于单个工作目录。一个例子是 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/config
之后读取配置文件 .git/worktrees/<id>/config.worktree
。
列表输出格式
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
对于这些注释,可能还提供了一个原因,并且可以使用 verbose 模式查看。然后,注释将移动到缩进的下一行,后跟附加信息。
$ 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
)仅列出标签,并且仅在值为 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] 套件的一部分