Setup and Config
Getting and Creating Projects
Basic Snapshotting
Branching and Merging
Sharing and Updating Projects
Inspection and Comparison
Patching
Debugging
External Systems
Server Admin
Guides
- gitattributes
- Command-line interface conventions
- Everyday Git
- Frequently Asked Questions (FAQ)
- Glossary
- Hooks
- gitignore
- gitmodules
- Revisions
- Submodules
- Tutorial
- Workflows
- All guides...
Administration
Plumbing Commands
-
2.52.0
2025-11-17
- 2.48.1 → 2.51.2 no changes
-
2.48.0
2025-01-10
- 2.43.2 → 2.47.3 no changes
-
2.43.1
2024-02-09
- 2.42.2 → 2.43.0 no changes
-
2.42.1
2023-11-02
-
2.42.0
2023-08-21
- 2.39.1 → 2.41.3 no changes
-
2.39.0
2022-12-12
- 2.36.1 → 2.38.5 no changes
-
2.36.0
2022-04-18
- 2.35.1 → 2.35.8 no changes
-
2.35.0
2022-01-24
- 2.33.1 → 2.34.8 no changes
-
2.33.0
2021-08-16
- 2.31.1 → 2.32.7 no changes
-
2.31.0
2021-03-15
- 2.30.1 → 2.30.9 no changes
-
2.30.0
2020-12-27
- 2.29.1 → 2.29.3 no changes
-
2.29.0
2020-10-19
- 2.28.1 no changes
-
2.28.0
2020-07-27
- 2.22.1 → 2.27.1 no changes
-
2.22.0
2019-06-07
- 2.20.1 → 2.21.4 no changes
-
2.20.0
2018-12-09
- 2.19.3 → 2.19.6 no changes
-
2.19.2
2018-11-21
- 2.19.1 no changes
-
2.19.0
2018-09-10
- 2.18.1 → 2.18.5 no changes
-
2.18.0
2018-06-21
- 2.17.1 → 2.17.6 no changes
-
2.17.0
2018-04-02
-
2.16.6
2019-12-06
- 2.14.6 → 2.15.4 no changes
-
2.13.7
2018-05-22
-
2.12.5
2017-09-22
- 2.11.4 no changes
-
2.10.5
2017-09-22
-
2.9.5
2017-07-30
- 2.8.6 no changes
-
2.7.6
2017-07-30
-
2.6.7
2017-05-05
-
2.5.6
2017-05-05
概述
gitworktreeadd[-f] [--detach] [--checkout] [--lock[--reason<string>]] [--orphan] [(-b|-B) <new-branch>] <path> [<commit-ish>]gitworktreelist[-v|--porcelain[-z]]gitworktreelock[--reason<string>] <worktree>gitworktreemove<worktree> <new-path>gitworktreeprune[-n] [-v] [--expire<expire>]gitworktreeremove[-f] <worktree>gitworktreerepair[<path>…]gitworktreeunlock<worktree>
描述
管理附属于同一仓库的多个工作区。
一个 git 仓库可以支持多个工作区,允许你一次签出多个分支。 通过 git worktree add ,一个新的工作区与仓库相关联,同时还有额外的元数据,以区分该工作区与同一仓库中的其他工作区。 工作区目录树,连同这些元数据,被称为 "工作区"。
这个新的工作区被称为 "链接工作区",与 git-init[1] 或 git-clone[1] 所准备的 "主工作区 "相对应。 一个仓库有一个主工作区(如果它不是一个裸仓库)和零个或多个链接工作区。当你用完一个链接工作区后,用 git worktree remove 删除它。
在其最简单的形式中, git worktree add <路径> 自动创建一个新的分支,其名称是 <路径> 的最后一个组成部分,如果你计划在一个新的主题上工作,这很方便。例如, git worktree add ../hotfix 创建了新的分支 hotfix ,并在路径 ../hotfix 处签出它。如果要在一个新的工作区中处理现有的分支,可以使用 git worktree add <路径> <分支> 。另一方面,如果你只是打算做一些实验性的修改,或者在不影响现有开发的情况下进行测试,创建一个不与任何分支相关联的 "抛弃式 "工作区通常是很方便的。例如, git worktree add -d <路径> 在与当前分支相同的提交中,创建一个带有分离 HEAD 的新工作区。
如果没有使用 git worktree remove 就删除了工作区,那么它的相关管理文件,即驻扎在仓库中的文件(见下面的 "详细说明"),最终会被自动删除(见 git-config[1] 中的 gc.worktreePruneExpire),或者你可以在主工作区或任何链接工作区中运行`git worktree prune` 来清理任何过时的管理文件。
如果一个链接的工作区存储在便携设备或网络共享上,而这些设备并不总是被挂载,你可以通过发布`git worktree lock`命令来防止其管理文件被修剪,可以使用选项`--reason`来解释为什么工作树被锁定。
命令
-
add<path> [<commit-ish>] -
Create a worktree at <path> and checkout <commit-ish> into it. The new worktree is linked to the current repository, sharing everything except per-worktree files such as
HEAD,index, etc. As a convenience, <commit-ish> may be a bare "-", which is synonymous with@{-1}.If <commit-ish> is a branch name (call it <branch>) and is not found, and neither
-bnor-Bnor--detachare used, but there does exist a tracking branch in exactly one remote (call it <remote>) with a matching name, treat as equivalent to:$ git worktree add --track -b <分支> <路径> <远程仓库>/<分支>
If the branch exists in multiple remotes and one of them is named by the
checkout.defaultRemoteconfiguration variable, we’ll use that one for the purposes of disambiguation, even if the <branch> isn’t unique across all remotes. Set it to e.g.checkout.defaultRemote=originto always checkout remote branches from there if <branch> is ambiguous but exists on theoriginremote. See alsocheckout.defaultRemotein git-config[1].If <commit-ish> is omitted and neither
-bnor-Bnor--detachused, then, as a convenience, the new worktree is associated with a branch (call it <branch>) named after$(basename<path>). If <branch> doesn’t exist, a new branch based onHEADis automatically created as if-b<branch> was given. If <branch> does exist, it will be checked out in the new worktree, if it’s not checked out anywhere else, otherwise the command will refuse to create the worktree (unless--forceis used).If <commit-ish> is omitted, neither
--detach, or--orphanis used, and there are no valid local branches (or remote branches if--guess-remoteis specified) then, as a convenience, the new worktree is associated with a new unborn branch named <branch> (after$(basename<path>) if neither-bor-Bis used) as if--orphanwas passed to the command. In the event the repository has a remote and--guess-remoteis used, but no remote or local branches exist, then the command fails with a warning reminding the user to fetch from their remote first (or override by using-f/--force). -
list -
列出每个工作区的细节。 主工作区被首先列出,接着是每个链接工作区。 输出的细节包括该工作区是否为裸树,当前签出的修订版,当前检出的分支(如果没有则为 "分离的HEAD"),如果工作树被锁定则为 "锁定",如果工作树可以被`prune`命令修剪则为 "可修剪"。
-
lock -
如果一个工作区在便携式设备或网络共享上,而这个设备或网络共享并不总是被挂载,请锁定它以防止其管理文件被自动修剪。这也可以防止它被移动或删除。 可以选择用`--reason`选项来指定锁定的原因。
-
move -
将一个工作区移动到一个新的位置。注意,主工作区或包含子模块的链接工作区不能用此命令移动。(然而,如果你手动移动主工作区,`git worktree repair`命令可以重新建立与链接工作区的连接。)
-
prune -
修剪`$GIT_DIR/worktrees`中的工作区信息。
-
remove -
移除一个工作区。只有干净的工作区(没有未跟踪的文件和未修改的跟踪文件)可以被删除。脏工作区或有子模块的工作区可以用
--force删除。主工作区不能被删除。 -
repair[<path>...] -
如果可能的话,修复工作区的管理文件,如果它们由于外部因素而变得损坏或过时。
例如,如果主工作区(或裸仓库)被移动,链接工作区将无法找到它。在主工作区中运行
repair将重新建立从链接工作区到主工作区的连接。Similarly, if the working tree for a linked worktree is moved without using
gitworktreemove, the main worktree (or bare repository) will be unable to locate it. Runningrepairwithin the recently-moved worktree will reestablish the connection. If multiple linked worktrees are moved, runningrepairfrom any worktree with each tree’s new <path> as an argument, will reestablish the connection to all the specified paths.If both the main worktree and linked worktrees have been moved or copied manually, then running
repairin the main worktree and specifying the new <path> of each linked worktree will reestablish all connections in both directions. -
unlock -
解锁一个工作区,允许它被修剪、移动或删除。
选项
-
-f -
--force -
By default,
addrefuses to create a new worktree when <commit-ish> is a branch name and is already checked out by another worktree, or if <path> is already assigned to some worktree but is missing (for instance, if <path> was deleted manually). This option overrides these safeguards. To add a missing but locked worktree path, specify--forcetwice.moverefuses to move a locked worktree unless--forceis specified twice. If the destination is already assigned to some other worktree but is missing (for instance, if <new-path> was deleted manually), then--forceallows the move to proceed; use--forcetwice if the destination is locked.remove`拒绝删除一个脏工作区,除非使用--force`。 要删除一个锁定的工作区,需要指定`--force`两次。
-
-b<new-branch> -
-B<new-branch> -
With
add, create a new branch named <new-branch> starting at <commit-ish>, and check out <new-branch> into the new worktree. If <commit-ish> is omitted, it defaults toHEAD. By default,-brefuses to create a new branch if it already exists.-Boverrides this safeguard, resetting <new-branch> to <commit-ish>. -
-d -
--detach -
通过
add,在新的工作树中分离出HEAD。参见 git-checkout[1] 中的 “分离式 HEAD”。 -
--checkout -
--no-checkout -
By default,
addchecks out <commit-ish>, however,--no-checkoutcan be used to suppress checkout in order to make customizations, such as configuring sparse-checkout. See "Sparse checkout" in git-read-tree[1]. -
--guess-remote -
--no-guess-remote -
在`worktree add <路径>`下,如果没有_<提交号>_,则不从`HEAD`创建新的分支,而是在正好有一个与_<路径>_的基名相匹配的远程跟踪分支的情况下,将新的分支建立在远程跟踪分支上,并将远程跟踪分支标记为新分支的 "上游"。
这也可以通过使用`worktree.guessRemote`配置选项设置为默认行为。
-
--relative-paths -
--no-relative-paths -
Link worktrees using relative paths or absolute paths (default). Overrides the
worktree.useRelativePathsconfig option, see git-config[1].With
repair, the linking files will be updated if there’s an absolute/relative mismatch, even if the links are correct. -
--track -
--no-track -
When creating a new branch, if <commit-ish> is a branch, mark it as "upstream" from the new branch. This is the default if <commit-ish> is a remote-tracking branch. See
--trackin git-branch[1] for details. -
--lock -
在创建后保持工作区的锁定。这相当于在
gitworktreeadd之后执行gitworktreelock,但没有资源竞争。 -
-n -
--dry-run -
在使用`prune`时,不会删除任何文件;只会报告它要删除的东西。
-
--orphan -
With
add, make the new worktree and index empty, associating the worktree with a new unborn branch named <new-branch>. -
--porcelain -
使用
list时,脚本会以易于解析的格式输出。 这种格式在不同的 Git 版本和用户配置下都会保持稳定。 建议与-z搭配使用。 详见下文。 -
-z -
Terminate each line with a NUL rather than a newline when
--porcelainis specified withlist. This makes it possible to parse the output when a worktree path contains a newline character. -
-q -
--quiet -
用`add`,抑制反馈信息。
-
-v -
--verbose -
使用`prune`,报告所有的移除情况。
用`list`,输出关于工作区的额外信息(见下文)。
-
--expire<time> -
With
prune, only expire unused worktrees older than <time>.With
list, annotate missing worktrees as prunable if they are older than <time>. -
--reason<string> -
用`lock`或用`add --lock`,解释为什么工作区被锁定。
- <worktree>
-
工作区可以通过相对或绝对路径来识别。
如果工作区路径中的后几个层次在工作树中是唯一的,则它可以用来识别一个工作树。例如,如果你只有两个工作区,在`/abc/def/ghi`和`/abc/def/ggg`,那么使用`ghi`或`def/ghi`就足以指向前一个工作区。
引用
当使用多个工作区时,一些引用在所有工作区之间共享,但其他引用是特定于单个工作区的。比如:HEAD,它对每个工作树都是不同的。本节是关于共享规则,以及如何从另一个工作区访问一个工作区的引用。
一般来说,所有伪引用都是按工作区划分的,而所有以 refs/ 开头的引用都是共享的。伪引用与 HEAD 类似,直接位于 $GIT_DIR 下,而不是 $GIT_DIR/refs 内。但也有例外:refs/bisect、refs/worktree 和`refs/rewitten` 中的引用不共享。
每个工作区的引用仍然可以通过两个特殊的路径,即 主工作区`和 `从工作区,从另一个工作区访问。前者可以访问主工作区的每个工作区的引用,而后者可以访问所有链接的工作区。
例如,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的值为 `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/bisect、refs/worktree 和 refs/rewitten,所有工作区都共享引用。
更多信息见 gitrepository-layout[5]。经验法则是,当你需要直接访问`$GIT_DIR`或`$GIT_COMMON_DIR`内的东西时,不要对路径是否属于`$GIT_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 (裸) /path/to/linked-worktree abcd1234 [master] /path/to/other-linked-worktree 1234abc (分离式HEAD)
该命令还根据每个工作区的状态,显示其注释。 这些注释是:
-
locked,如果工作区被锁定。 -
prunable,如果工作区可以通过`git worktree prune`进行修剪。
$ git worktree list /path/to/bare-source (裸) /path/to/linked-worktree abcd1234 [master] /path/to/other-linked-worktree 1234abc (分离式HEAD)
对于这些注释,也可能有一个原因,这可以通过verbose模式看到。然后注释被移到下一行缩进,后面是附加信息。
$ git worktree list --verbose /path/to/linked-worktree abcd1234 [master] /path/to/locked-worktree-no-reason abcd5678 (分离的 HEAD) locked /path/to/locked-worktree-with-reason 1234abcd (brancha) 锁定:工作区路径被安装在一个可移动设备上 /path/to/prunable-worktree 5678abc1 (分离的 HEAD) 可修剪:gitdir 文件指向不存在的位置
注意,如果有额外的信息,注释将被移到下一行,否则它将与工作区本身保持在同一行。
上层命令格式
上层命令的每个属性有一行。 如果给了`-z`,那么这几行将以NUL(空字符)而不是换行来结束。 属性以标签和值的形式列出,用一个空格隔开。 布尔属性(如`bare`和`detached`)仅作为标签列出,并且仅在值为真时出现。 一些属性(如`locked')可以只作为标签列出,也可以根据是否有理由列出一个值。 工作区的第一个属性总是`工作树',一个空行表示记录的结束。 比如说:
$ 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 修剪的gitdir文件指向不存在的位置
除非使用`-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 # ... 嗨骇害 ... $ git commit -a -m '老板让我赶紧修复的问题' $ popd $ git worktree remove ../temp
配置
本节中这一行以下的内容都是从 git-config[1] 文档中摘录的。其内容与那里的内容相同:
|
Warning
|
Missing See original version for this content. |
GIT
属于 git[1] 文档