Git工作树 vs “克隆-参考”

10
使用git worktrees和使用--reference标志维护多个克隆版本的优缺点是什么? 我考虑的主要场景是当开发人员需要在磁盘上维护多个git仓库以供旧版本(release/1.0、release/2.0、release/3.0)时,因为在单个git仓库上切换分支并重新构建会很耗时。
使用worktrees,开发人员可以拥有一个仓库的单个克隆版本,任何旧版本都可以作为仓库的worktrees来创建,方法是使用命令:cd /opt/main/git worktree add /opt/old_release_1 release/1.0。使用参考克隆,开发人员在某个地方维护主克隆版本,并使用命令cd /opt/old_release_1, git clone --reference /opt/main/.git ssh://git@github.com/myrepo.git来为旧版本创建克隆仓库。
它们似乎都能达到相同的目的。从速度、磁盘空间等方面来看,它们中的其中一个是否更具优势?
1个回答

13
  • 它们都有一些重要的问题需要解决,但使用git worktree可能是最好的选择。

  • 一个克隆,我们称其为AD,使用--reference local-path进行依赖克隆,但没有使用--dissociate,它使用来自local-path 的对象。所谓“对象”,我指的是Git对象(以松散方式和/或打包文件存储)。另一个Git仓库——在local-path中的那个——不知道AD在使用这些对象。

    我们将基本克隆称为BC。现在,假设在BC中发生了某些事情,以至于不再需要某个对象,例如删除分支名称或远程跟踪名称。此时,在BC中运行git gc可能会对对象进行垃圾回收和删除。

    如果现在切换到AD克隆并运行各种Git操作,由于已删除对象,它们可能会失败。问题在于旧的BC克隆不知道新的AD克隆依赖它。

    请注意,AD中嵌入了BC的路径名。如果您移动BC,则必须编辑AD中的.git/objects/info/alternates文件。

  • 使用git worktree add创建的工作树也使用原始克隆中的对象。我们仍将原始克隆称为BC,只是加入的工作树被称为Wb。与上面的BC / AD设置有两个关键区别:

  • 每个新的工作目录 Wb 实际上使用来自 BC 的整个 .git 目录。

  • BC 存储了每个 Wb 的路径,因此它知道每个 Wb,您不会遇到对象意外消失的问题。

  • 然而,由于 BC 记录了每个 Wb,并且所有分支名称实际上都存储在 BC 中,因此有一个限制:无论哪个分支在 BC 中被检出,都不能在任何一个 Wb 中被检出。此外,Wb1 必须处于与 Wb2 不同的分支上。(您可以在 BC 和每个 Wb 中的任何一个或所有的地方处于 "detached HEAD" 模式,即没有任何分支。)

  • 由于 BC 记录了每个 Wb 的路径(反之亦然),如果您想要 移动 这些存储库中的任何一个,必须调整路径。


    我认为你在第一个要点中所写的关于在AD中使引用无效并造成问题的内容适用于--shared,但不适用于--reference - Sunday
    @Sunday:我在实践中已经做过这个(大约在2016年),使用“--reference”确实会出现这些问题。使用“--dissociate”可以解决这些问题,但代价是需要使用更多的磁盘空间。 - torek
    1
    是的,你说得对,它适用于两者,抱歉。我再次检查了git clone参考文档,关于“--reference”的段落也提到了有关“--shared”的段落中存在的警告提示。 - Sunday
    @Sunday:我最终在留给公司的代码中使用了“--dissociate”。不确定他们是否安装了它,尽管它将完整构建时间从2小时缩短到了15分钟。 :-) - torek

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接