首页 > 解决方案 > git - 工作树和共享存储库之间的区别?

问题描述

git worktree 命令和通过使用 --shared 开关多次克隆来在本地共享存储库有什么区别?

我的目标是只将一个相对较大的存储库克隆到开发人员机器的磁盘上,然后使用该存储库在多个分支上进行开发。我们不能使用 git worktree,因为我们使用的是 Eclipse,而 Eclipse 目前不支持工作树

我尝试过并且似乎有效的方法如下:

  1. 从 GitLab 克隆一次存储库:git clone ssh://host/repo.git repository-master
  2. 再次克隆它,而不将任何内容作为共享存储库签出。这只是为第一个存储库中的包文件创建了一些参考文件,不会浪费任何磁盘空间: git clone --shared repository-master/ repository-branch1/
  3. 将 GitLab 存储库作为远程添加到共享存储库 repository-branch1:git remote add gitlab ssh://host/repo.git
  4. 获取数据git fetch
  5. 将所需的分支签出到第二个克隆存储库-branch1 中的新本地分支中:git checkout -b branch1 gitlab/branch1

这似乎解决了所有问题:

  1. 有多个分支同时签出。
  2. 您可以将提交推送到两个分支。
  3. 您可以将项目导入 Eclipse,Eclipse 将识别存储库。
  4. 磁盘上只有一个克隆的存储库。

我在这里错过了什么吗?当然,除了方便之外,一定有理由使用 worktree 命令吗?

标签: git

解决方案


使用的克隆--shared(或某些基于路径名的克隆隐含--shared)是一个单独的存储库。通过使用硬链接1(必须由您的操作系统支持),您可以获得节省磁盘空间的所有好处,2完全安全,因为 Git 从不覆盖任何现有数据,它只会添加新数据,或者在相对罕见的情况下,取消链接文件,这现在是无害的,因为这只会减少使用该文件的 Git 存储库的数量。

用 制作的工作树git worktree add不是单独的存储库。您在该工作树中所做的一切,对于您不在该工作树中的任何分支或标签,共享存储库的所有其他工作树都会立即看到。工作树有自己的HEAD(通常附加到分支名称,但可以选择分离)、自己的索引,当然还有自己的工作树。几乎所有其他内容都是共享的(还有一些其他神奇的私有引用,例如 for git bisect,但任何存储,例如,跨工作树共享)。

您现有的流程很好;请注意,磁盘空间共享最终会降级,如脚注 2 中所述。


1对某个底层文件对象进行硬链接会添加一个新名称,并增加链接计数。链接计数始终表示文件名称的数量。上面描述的unlink操作是name-delete,而不是file-delete;只有当最后一个引用消失时,文件本身才会消失。

2这种节省会随着时间的推移而降低。这两个独立的存储库最初共享所有底层存储,但在某些时候,一个存储库决定打包松散的对象,或者重新打包现有的包,从而破坏一些链接。本质上,另一个存储库现在拥有自己的私有副本。最终,所有链接都可能被切断,因此每个存储库都是真正独立的。存储库继续工作,但不再节省空间。


推荐阅读