【问题标题】:Version Control: How does forking a repository work on source code hosting facilities?版本控制:分叉存储库如何在源代码托管设施上工作?
【发布时间】:2016-06-21 23:15:30
【问题描述】:
我只是有点好奇,像 Bitbucket、GitHub 和 Launchpad 这样的源代码托管设施实际上是如何管理来自主存储库的分叉过程,以及当这些存储库在服务器上分叉时它们如何设法节省服务器磁盘空间- 侧面。
例如,如果我从 GitHub 上的存储库分叉:我的存储库上的复制代码是否会从 GitHub 服务器上的主存储空间占用额外的磁盘空间(我的意思是它会导致存储重复性)?
提前致谢。
【问题讨论】:
标签:
github
version-control
bitbucket
launchpad
【解决方案1】:
基于this answer 看来,GitHub 至少在分叉时不会复制存储库。相反,它会创建带有用户名的新分支(例如,我的分叉主分支将被引用为 lightcc.master,而不是 master)。
这在 Git 如何存储文件和引用它们以及为什么它能够如此高效地存储 repos 的上下文中非常有意义。如果一个 fork 是一个 repo 的完美副本,那么需要做的就是创建新的分支(跟踪引用)并跟踪谁有权查看它们以及向/从它们推/拉。如果我 fork 一个 repo,但从未对其进行更改,那么我的跟踪引用可能在上游 repo 之后,但它们将始终与那些旧提交相同(除非原始 repo 做了一些非常糟糕的事情 [tm] 和通过 rebase、squashing 等将其历史重写为现有提交)。
换句话说,在原始分叉时,不需要复制原始存储库,因此唯一的成本是创建新跟踪引用所需的字节数,每个现有分支约为 40 个字节。它甚至可能在您真正偏离原始存储库之前(或者直到您设置跟踪引用并将其推送到给定分支的 fork 之前 - 所以 master 可能是自动的?)。
鉴于 cmets,这似乎是 GitHub 所做的,因此 GitLab 实际复制 repo 的行为(根据 0xcaff 的回答)更类似于创建重复进程的 Unix fork。 GitHub 以一种非常敏捷的方式希望等到最后一刻才创建任何新对象,因为分叉实际上与原始存储库不同。
这可能就是为什么 GitHub 有一些关于将分叉与原始存储库完全分开的规则,以及为什么需要参与支持的原因。这样做会消耗他们的存储空间,如果他们让每个人都可以轻松免费地做到这一点,那么随着时间的推移,他们可能会花费大量的存储空间等。
【解决方案2】:
这是一个很好的问题,让我想知道同样的事情。
Gitlab
还好有一个开源的git repo管理工具,叫做gitlab,我们可以看看。
在gitlab-shell 中,fork_project 函数处理分叉。检查传递的参数是否有效后,执行以下行:
cmd = %W(git clone --bare -- #{full_path} #{full_destination_path})
system(*cmd) && self.class.create_hooks(full_destination_path)
所以 GitLab 只是克隆存储库,复制源代码。
相关问题