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_1
、git 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路径(反之反之亦然),如果你想移动这些存储库中的任何一个,你必须调整路径。
使用 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_1
、git 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 fromlocal-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路径(反之反之亦然),如果你想移动这些存储库中的任何一个,你必须调整路径。