283

在 git-worktree 上阅读了 Github 的帖子。他们写:

假设您正在一个名为 的分支上的 Git 存储库中工作,此时feature用户报告master. 首先,您创建一个带有新分支的链接工作树,hotfix相对于 master [...] 您可以修复错误、推送修补程序并创建拉取请求。

当我在一个名为 feature 的分支上工作并且报告了 master 中的一些高紧急错误时,我通常会隐藏我正在处理的所有内容并创建一个新分支。完成后,我可以继续工作。这是一个非常简单的模型,我多年来一直这样工作。

另一方面,使用 git-worktree 有其自身的局限性:

例如,不允许在两个链接的工作树中同时检出相同的分支,因为这将允许在一个工作树中提交的更改导致另一个工作树不同步。

为什么我要为已经解决的问题选择更复杂的工作流程?

有什么事情git-worktree是事先无法做到的,并且可以证明这个全新的、复杂的功能是合理的吗?

4

10 回答 10

282

对我来说,git worktree 是很长一段时间以来最大的改进。我从事企业软件开发。在那里,您必须像 3 年前发布的那样维护旧版本是很常见的。当然,每个版本都有一个分支,以便您可以轻松切换到它并修复错误。但是,切换成本很高,因为在此期间您完全重组了存储库并可能构建系统。如果您切换,您的 IDE 将疯狂地尝试调整项目设置。

使用工作树,您可以避免这种不断的重新配置。使用工作树检出单独文件夹中的旧分支。对于每个分支,您都有一个独立的 IDE 项目。

当然,这在过去可以通过多次克隆 repo 来完成,到目前为止,这一直是我的方法。然而,这也意味着浪费硬盘空间,更糟糕的是需要多次从 repo 中获取相同的更改。

于 2015-08-11T20:19:49.317 回答
93

我可以看到一些用途。

如果您有一个运行很长时间的测试套件,想象几个小时,然后您启动它,它会有效地阻止该工作副本,直到测试完成。在这些测试期间切换分支会以难以理解的方式破坏它们。

因此,git-worktree我可以为另一个在那里工作的分支机构启动第二个想法。

此外,当我切换到其他分支进行快速调查时,我的 IDE 认为很多文件突然更改并且会索引所有这些更改,只是在我切换回来时必须再次重新索引它们。

第三个用例是使用其他工具进行文件比较,而不是git-diff像 normal diff,在两个目录之间而不是在两个分支之间。

于 2015-08-11T07:45:18.663 回答
76

一个明显的用途是同时比较不同版本的行为(而不是来源) - 例如网站的不同版本或只是网页。

我在本地试过这个。

  • 创建一个目录page1

  • 在里面创建目录srcgit init它。

  • src创建page1.html一些内容并提交它。

  • $ git branch ver0

  • $ git worktree add ../V0 ver0

  • srcmaster 中添加更多文本page1.html并提交。

  • $ git branch sty1

  • page1.html在分支中编辑sty1(添加一些独特的 CSS 样式)并添加提交。

  • $ git worktree add ../S1 sty1

您现在可以使用网络浏览器同时打开和查看这 3 个版本:

  • ..\page1\src\page1.html // git 当前的任何内容

  • ..\page1\V0\page1.html // 初始版本

  • ..\page1\S1\page1.html // 实验风格的版本

于 2015-09-29T17:27:51.877 回答
33
  1. 您可能希望/需要一次在文件系统中创建多个工作树是有正当理由的。

    • 操作签出的文件,同时需要在其他地方进行更改(例如编译/测试)

    • 通过普通的差异工具对文件进行差异化

    • 在合并冲突期间,我经常想在源代码端导航源代码,同时解决文件中的冲突。

    • 如果您需要来回切换很多,那么就会浪费时间签出和重新签出,而您不需要处理多个工作树。

    • 通过 git stash 在分支之间切换心理上下文的心理成本并不是真正可衡量的。有些人发现,通过简单地从不同目录打开文件来存储不存在的文件会产生心理成本。

  2. 有人问“为什么不做多个本地克隆”。确实,使用“--local”标志您不必担心额外的磁盘空间使用。这(或类似的想法)是我到目前为止所做的。与本地克隆相比,链接工作树的功能优势是:

    1. 使用本地克隆,您的额外工作树(位于本地克隆中)根本无法访问原始分支或上游分支。克隆中的“原点”与第一个克隆中的“原点”不同。

      • 跑步git log @{u}..git diff origin/feature/other-feature可能非常有帮助,而这些要么不再可能,要么更加困难。这些想法在技术上可以通过各种解决方法在本地克隆中实现,但是您可以做的每个解决方法都可以通过链接的工作树做得更好和/或更简单。
    2. 您可以在工作树之间共享参考。如果您想比较或借用另一个本地分支的更改,现在您可以了。

于 2015-09-29T16:44:20.460 回答
17

我最喜欢也可能是每个人都应该使用的最常见用例git worktree是审查队友的拉取请求,同时仍在主工作树中处理您的更改。

于 2020-11-15T18:11:25.413 回答
12

tl;dr:无论出于何种原因,无论何时您想要同时检查两个工作树,git-worktree都是一种快速且节省空间的方法。

如果您创建另一个工作树,则存储库的大部分(即.git)将被共享,这意味着如果您在一个工作树中创建分支或获取数据,那么您也可以从您拥有的任何其他工作树访问它。假设您想在分支 foo 上运行您的测试套件,而不必将其推送到某个地方来克隆它,并且您想避免在本地克隆您的 repo 的麻烦,使用git-worktree是一种在 a 中创建某个状态的新签出的好方法单独的地方,无论是暂时的还是永久的。就像克隆一样,完成后您需要做的就是删除它,并且对它的引用将在一段时间后被垃圾收集。

于 2015-08-11T20:05:37.270 回答
10

在想知道这些花哨的工作树可以用来做什么之后,我最初偶然发现了这个问题。从那时起,我将它们整合到我的工作流程中,尽管我最初持怀疑态度,但我发现它们非常有用。

我在一个相当大的代码库上工作,这需要相当长的时间来编译。我的机器上通常有当前的开发分支以及我当前正在处理的功能分支以及代表实时系统当前状态的主分支。

对我来说最大的好处之一显然是我不必在每次切换分支(即工作树)时重新编译整个东西。一个很好的副作用是我可以去开发工作树,在那里做一些事情,将目录更改为我当前功能分支的工作树,然后重新设置它而无需先拉动。

于 2016-04-22T07:32:19.420 回答
7

我有一个相当不寻常的:我在同一台机器上进行 Windows 和 Linux 开发。我的 Windows 机器中有一个运行 Linux 的 VirtualBox。VirtualBox 会挂载一些 Windows 目录并直接在 Linux 机器内部使用它们。这让我可以使用 Windows 来管理文件,但在 Linux 中构建。这是一个跨平台项目,因此它从相同的目录结构构建在 Windows 和 Linux 上。

问题是 Linux 和 Windows 构建系统在同一目录中使用时会相互崩溃;下载使用相同目录名称的库等有一些复杂的构建步骤。Windows 版本的构建系统下载 Windows 特定的库,Linux 版本的构建系统下载 Linux 特定的库。

在理想情况下,构建系统将被修改,以便 Windows 和 Linux 可以在目录中共存,但目前,问题正在通过工作树解决。“Linux”文件夹可以生成 Linux 特定的构建工件,“Windows”文件夹可以生成 Windows 特定的构建工件。虽然这不是一个理想的解决方案,但在等待构建系统错误得到解决时,它是一个很好的权宜之计。

诚然,worktree 不是为此而设计的。我必须将 Windows 版本和 Linux 版本保存在不同的分支上,即使我真的希望它们在同一个分支上。尽管如此,它仍在完成这项工作,并且是工作树节省一天的一个非常规的案例。

于 2016-07-18T22:59:57.533 回答
3

我正在git worktree用于机器学习开发。

我有一个主要的功能代码,然后我想拆分不同实验的分支(不同的算法和不同的超参数)。git worktree允许我将dvc与专门针对不同算法的不同版本的代码集成在一起。在运行所有训练作业后,我评估最终指标并合并以掌握最佳分支/模型。

于 2019-06-17T20:31:10.723 回答
1

在我的新项目中,我创建了一个功能。但有些规格失败了。为了将结果与master我创建了一个work-treerepo 进行比较。我在运行代码中逐步比较结果,直到了解出了什么问题。

于 2016-09-12T06:34:05.753 回答