48

在我的远程存储库中有 3 个分支(主分支和 2 个长期运行的分支):

master  #the common features are here like Core, DAL,...
north   #customized for A company (long-running)
razavi  #customized for B company (long-running)

在我的办公室 PC 上,我worktree为这些northrazavi分支添加了 2 个:

$ git worktree list
C:/Source/nis     a6fb6e1 [master]
C:/Source/north   ebc7670 [north]
C:/Source/razavi  eed08a2 [razavi]

到目前为止一切正常,我也决定在家中处理这个项目,但是在我的家用 PC 中,当我尝试为这两个分支添加工作树时,它给了我一个错误:

$git worktree add -b north ../north north
fatal: A branch named 'north' already exists.

我删除了-b不添加新分支的开关,但它也不起作用。

如何worktree从现有分支添加一个不是本地但远程的?

4

4 回答 4

64

TL;DR:你可能想要git worktree add ../north north

首先,提醒(或其他遇到此问题的信息):git worktree add想要创建一个新的工作树同时确保这个新的工作树使用与其他所有工作树不同的分支名称. 这是因为,虽然每个添加的工作树都有自己的索引和HEAD,但HEAD文件最终会共享共享存储库中的底层分支指针。拥有两个具有独立索引对象但具有相同底层分支的不同工作树会导致用户处理一些棘手的问题。而不是试图弄清楚如何为了解决这些问题——通过教育程序员或提供解决问题的工具——<code>git worktree 完全禁止这种情况。

因此,在创建新工作树时想要创建一个的分支名称是非常典型的。根据定义,一个新的分支名称自动不同于每个现有的分支名称:

$ git checkout -b newbranch
Switched to a new branch 'newbranch'
$ git checkout -b newbranch
fatal: A branch named 'newbranch' already exists.

这似乎很自然:没有人对此感到惊讶。

您正在git worktree add以类似于 的方式运行,只是git checkout -b结帐发生在新添加的工作树中。但是您已经有一个名为north.

如果这个现有north分支没有用,您可以将其删除。现在您没有命名的本地分支north,您可以创建一个新分支。

如果这个现有north分支有用,请不要删除它如果它已经在某个现有的工作树中签出,请移至该工作树并在那里进行处理。如果它没有在一些现有的工作树中被检出,你可以创建一个新的工作树来检出它您只需要避免使用-b标志(和相应的分支名称):

git worktree add ../north north

请注意,当您创建分支时,您不必重复自己:

git worktree add -b newbranch ../path

将在 中创建一个新的工作树../path,并用于git checkout -b newbranch填充它。只有在以下情况下才需要分支名称:

  1. 你没有使用-b, 和
  2. path参数不以分支名称结尾。

例如,如果您想zorg在 path 的新工作树中检查现有分支../zorg,您可以运行:

git worktree add ../zorg

在这里,由于既没有 a-b zorg也没有 final 参数,Git 通过使用 的最后一部分来计算分支名称../zorg,当然这只是zorg,所以这会尝试将现有分支检出zorg到新的工作树中。

于 2017-08-03T18:17:31.463 回答
6

对于这个问题,worktree add确实需要一个--checkout开关来做到这一点:

$ git worktree add --checkout ../north north
$ git worktree add --checkout ../razavi razavi
于 2017-08-15T18:11:20.197 回答
5

除了“猜测远程分支”之外,正如我在另一个答案中解释的那样,Git 2.18(2018 年第二季度)将提供一个新功能:
git worktree add”学会检查现有分支。

请参阅Thomas Gummerer ( ) 的提交 f60a7b7提交 6427f87提交 2c27002提交 d861d34(2018 年 4 月 24 日。 帮助者:Eric Sunshine ( )(由Junio C Hamano 合并 -- --提交 10174da中,2018 年 5 月 23 日)tgummerer
sunshineco
gitster

工作树:教“ add”检查现有的分支

当前,“ git worktree add <path>”默认创建一个以路径的基本名称命名的新分支。
如果已存在具有该名称的分支,则该命令拒绝执行任何操作,除非--force给出了 ' ' 选项。

但是,我们可以做得比这更好一些,如果没有在其他任何地方签出,请检查分支。
这将帮助只想将现有分支检出到新工作树
中的用户,并节省一些击键。

由于当前的行为是简单的 ' die()' 当具有路径基本名称名称的分支已经存在时,这里不存在向后兼容性问题。

die()如果分支在另一个工作树中签出,我们仍然会' ',除非--force标志被传递。

文档现在指出

$ git worktree add --track -b <branch> <path> <remote>/<branch>

如果<commit-ish>省略且既不使用也不-b使用,则为方便起见,新工作树与以命名的分支(称为 )相关联。-B--detach<branch>$(basename <path>)

  • 如果<branch>不存在,则会自动创建一个基于 HEAD 的新分支,就像-b <branch>给定的一样。
  • 如果<branch>确实存在,它将在新的工作树中检出,如果它没有在其他任何地方检出,否则该命令将拒绝创建工作树(除非--force使用)。

git worktree addGit 2.30(2021 年第一季度)修复了在“ ” man子命令中带有两个占位符的错误消息的表述。

请参阅Matheus Tavares ( ) 的提交 b86339b(2020 年 11 月 20 日(由Junio C Hamano 合并——提交 f73ee0c中,2020 年 11 月 30 日)matheustavares
gitster

worktree:修复错误消息中的参数顺序

签字人:Matheus Tavares
审核人:Eric Sunshine

git worktree add( man ) (without --force) 当给定一个已经注册为工作树的路径并且该路径在磁盘上丢失时会出错。
但是cmdpath字符串打开错误消息。
让我们解决这个问题。

这是关于错误消息:

<path> is a missing but locked worktree
use '<cmd> -f -f' to override, or 'unlock' and 'prune' or 'remove' to clear

或者:

<path> is a missing but already registered worktree
use '<cmd> -f' to override, or 'unlock' and 'prune' or 'remove' to clear

评论

它不起作用!我尝试git worktree add ../north north,正如我所说,它给了我一个致命的错误:

'north' is already checked out at 'C:/Source/nis'

该错误消息现在应该更清楚(2022 年第一季度)。

在 Git 2.35(2022 年第一季度)中,“ git worktree addman向标准输出流显示“正在准备工作树”消息,但是当它失败时,来自die()标准错误流的消息。
根据程序结束时刷新 stdio 流的顺序,这会导致输出混乱。
它已通过将所有闲聊消息发送到标准错误流来纠正。

请参阅Eric Sunshine ( ) 的提交 b502524提交 da8fb6b(2021 年 12 月 2 日(由Junio C Hamano 合并——提交 986eb34中,2021 年 12 月 15 日)sunshineco
gitster

worktree: 向标准错误发送“健谈”消息

报告人:Baruch Burstein
签字人:Eric Sunshine

不保证刷新标准输出和标准错误流的顺序在平台或libc实现之间是相同的。
如果在错误 (stderr) 输出之后刷新正常 (stdout) 输出,则这种确定性的缺乏可能导致异常和可能令人困惑的输出。
例如,以下输出清楚地表明由于致命错误导致的失败:

% git worktree add ../foo bar
Preparing worktree (checking out 'bar')
fatal: 'bar' is already checked out at '.../wherever'

已报告在 Microsoft Windows 上显示为:

% git worktree add ../foo bar
fatal: 'bar' is already checked out at '.../wherever'
Preparing worktree (checking out 'bar')

这可能会让读者误以为该命令以某种方式恢复并运行完成,尽管出现了错误。

之所以会出现此问题,是因为“闲聊”状态消息“Preparing worktree”被发送到 stdout,而“致命”错误消息被发送到 stderr。

Git 中的一个常见做法是将“闲聊”消息发送到 stderr。
因此,更合适的解决方法是git-worktree通过将其闲聊消息发送到 stderr 而不是当前情况下的 stdout 来调整以符合该实践。

可能有人担心将消息从 stdout 重定位到 stderr 可能会破坏现有工具,但是,这些消息已经国际化,因此不稳定。
而且,事实上,“Preparing worktree”消息已经成为2c27002中一些重大变化的主题(“ worktree:在创建新工作树时改进消息”,2018-04-24,Git v2.18.0-rc0 --合并列于第 6 批)。
此外,还有现有的先例,例如68b939b(“ clone:将诊断消息发送到 stderr”,2013-09-18,Git v1.8.5-rc0 -- merge)同样将“闲聊”消息从 stdout 重新定位到 stderr for git-克隆。

于 2018-05-24T20:46:03.640 回答
3

除此之外git worktree add --checkout,Git 2.16 (Q1 2018) 将提出另一种替代方案:

git worktree add”方式决定了从哪里创建哪个分支,新工作树中的结帐已经更新了一点。

请参阅Thomas Gummerer ( ) 的提交 e92445a提交 71d6682(2017 年 11 月 29 日)和提交 4e85333提交 e284e89提交 c4738ae提交 7c85a87(2017 年 11 月 26 日(由Junio C Hamano 合并 -- --66d3f19 提交中,2017 年 12 月 19 日)tgummerer
gitster

添加worktree.guessRemote配置选项

一些用户可能希望--guess-remote默认启用上一次提交中引入的选项,因此他们不必在每次创建新工作树时都输入它。

添加一个配置选项worktree.guessRemote,允许用户为自己配置默认行为。

git config的文档现在显示为:

worktree.guessRemote::

使用add,如果没有分支参数,并且既没有给出-b-B没有--detach给出,该命令默认从 HEAD 创建一个新分支。
如果worktree.guessRemote设置为 true,worktree add则尝试查找名称与新分支名称唯一匹配的远程跟踪分支。

  • 如果存在这样的分支,则将其检出并设置为新分支的“上游”。
  • 如果找不到这样的匹配,它会回退到从当前 HEAD 创建一个新分支。

实际上,Git 2.21(2019 年第一季度)澄清了此选项的文档,该选项直接使用“With add”,但没有解释这add是“git worktree”的子命令。

请参阅Eric Sunshine ( ) 的提交 b4583d5(2018 年 12 月 23 日(由Eric Sunshine 合并 -- --提交 b4583d5中,2018 年 12 月 28 日)sunshineco
sunshineco

该文档现在显示:

worktree.guessRemote

如果没有指定分支并且既不使用-b也不使用,则默认从 HEAD 创建一个新分支。-B--detachgit worktree add

于 2017-12-20T22:25:27.087 回答