我读了Github上git-worktree的帖子。他们写道:

假设您正在一个名为feature的分支的Git存储库中工作,这时用户在master中报告了一个高度紧急的错误。首先,您可以创建一个带有新分支、hotfix、相对于master[…]签出的链接工作树。您可以修复错误、推送hotfix并创建一个拉取请求。

当我在一个叫做feature的分支上工作时,master中报告了一些非常紧急的bug,我通常会把我正在做的东西藏起来,然后创建一个新的分支。当我完成时,我可以继续工作。这是一个非常简单的模型,我已经做了很多年了。

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

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

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

在git-worktree中,是否有什么东西是事先无法完成的,从而证明了这个全新的、复杂的功能是合理的?


我能看出这东西的用处。

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

所以有了git-worktree,我可以为另一个分支推出第二个想法。

另外,当我切换到其他分支做一些快速调查时,我的IDE认为很多文件突然发生了变化,并将索引所有这些更改,只是在我切换回来时必须重新索引它们。

第三个用例是使用git-diff以外的其他工具(如普通的diff)在两个目录之间(而不是两个分支)进行文件比较。

tl;dr:任何时候,无论出于什么原因,你想同时签出两个工作树,git-worktree是一种快速且节省空间的方法。

If you create another worktree, most parts of the repo (i.e. .git) will be shared, meaning if you create a branch or fetch data while you are in one work tree, it will also be accessible from any other work trees you have. Say you want to run your test suite on branch foo without having to push it somewhere to clone it, and you want to avoid the hassle of cloning your repo locally, using git-worktree is a nice way to create just a new checkout of some state in a separate place, either temporarily or permanently. Just like with a clone, all you need to do when you are done with it is delete it, and the reference to it will be garbage collected after some time.

For me, git worktree is the biggest improvement since a long time. I'm working in enterprise software development. There, it is very common that you have to maintain old versions like what you released 3 years ago. Of course you have a branch for each version so that you can easily switch to it and fix a bug. However, switching is expensive, because in the meantime you completely restructured the repository and maybe build system. If you switch, your IDE will run mad trying to adapt the project settings.

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

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

There are legitimate reasons why you may want/need multiple worktrees in the filesystem at once. manipulating the checked out files while needing to make changes somewhere else (eg. compiling/testing) diffing the files via normal diff tools during merge conflicts, I often want to navigate through the source code as it is on source side while resolving conflicts in the files. If you need to switch back and forth a lot, there is wasted time checkout out and rechecking out that you don't need to do with multiple worktrees. the mental cost of mental context switching between branches via git stashing is not really measurable. Some people find that there is mental cost to stashing that isn't there by simply opening files from a different directory. Some people ask "why not do multiple local clones". It is true that with the "--local" flag you don't have to worry about extra disc space usage. This (or similar ideas) is what I have done up to this point. Functional advantages to linked worktrees over local clones are: With local clones, your extra worktrees (which are in the local clones) simply do not have access to origin or upstream branches. The 'origin' in the clone will not be the same as the 'origin' in the first clone. Running git log @{u}.. or git diff origin/feature/other-feature can be very helpful and these are either not possible anymore or more difficult. These ideas are technically possible with local clones via an assortment of workarouns, but every workaround you could do are done better and/or simpler through linked worktrees. You can share refs between worktrees. If you want to compare or borrow changes from another local branch, now you can.

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

我在当地试过。

创建目录page1。 在里面创建目录SRC和git init它。 在SRC中创建带有少量内容的page1.html并提交。 $ git分支ver0 $ git工作树添加../ V0 ver0 在SRC master中添加更多文本到page1.html并提交。 $ git分支sty1 在sty1分支中编辑page1.html(添加一些独特的CSS样式)并添加提交。 $ git工作树添加../ S1 sty1

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

.\page1\src\page1.html //任何git当前的内容 .\page1\V0\page1.html //初始版本 \page1\S1\page1.html //实验风格的版本

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

我在一个相当大的代码库上工作,这需要相当长的时间来编译。我通常在我的机器上有当前的开发分支,以及我当前正在工作的特性分支,再加上主分支,它代表了活动系统的当前状态。

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

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

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

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

诚然,工作树并不是为此而设计的;我必须把Windows版本和Linux版本放在不同的分支上,尽管我真的希望它们放在同一个分支上。尽管如此,它还是在发挥作用,并且是一个不同寻常的工作树拯救世界的例子。

在我的新项目中,我创建了一个功能。 但一些规格失败了。为了与master比较结果,我创建了一个工作树repo。我在运行代码中一步一步地比较结果,直到了解哪里出了问题。

我正在使用git工作树进行机器学习开发。

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