git 工作树与 "clone --reference"

git worktrees vs "clone --reference"

使用 git 工作树与维护带有 --reference 标志的多个克隆有什么优缺点?我考虑的主要场景是开发人员需要在磁盘上为旧版本维护多个 git 存储库(release/1.0,release/2.0,release/3.0 ) 因为在单个 git 回购上切换分支并重建会很昂贵。

使用工作树,开发人员可以拥有存储库的单个克隆,并且可以使用 cd /opt/main/git worktree add /opt/old_release_1 release/1.0 创建任何旧版本作为存储库的工作树。使用参考克隆,开发人员在某处维护一个主克隆,并使用 cd /opt/old_release_1git clone --reference /opt/main/.git ssh://git@github.com/myrepo.git 为旧版本创建克隆存储库。

看来他们都可以完成同一个目标。在速度、磁盘 space... 其他方面是否有优势?

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

  • 一个克隆,让我们称这个为AD 用于后依赖克隆,with --reference <em>local-path</em> but without --dissociate uses objects from local-path。 "objects",我的意思是文字 Git 对象(松散地存储在包文件中 and/or)。另一个 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 从字面上使用整个 .git 目录 BC.

    • BC仓库记录了每个Wb的路径,所以它知道每个 Wb。不会有对象意外消失的问题。

    • 然而,由于BC记录了每个Wb和所有分支名称实际上存在于 BC 本身,有一个约束:在 BC 中检出的任何分支都不能在任何 [=41] 中检出=]Wb。此外,Wb1 必须是 "on"(如 git status 中所说的 on branch ...)与Wb2,等等。 (您可以处于 "detached HEAD" 模式,即,根本不在任何分支上,在任何或所有 BC 和每个 W b.)

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