Distributed Version Control Systems(分布式版本控制系统)在过去的几年里真正崛起,尽管它们已经存在了十多年。可能最大的增长发生在由Git引发的争议中,Git于2005年4月推出,提供了一个建立在文件系统模型上的坚实的分布式版本控制系统。仅仅在几个月内,Git就开始托管2.6.12版Linux内核源代码。
然而,尽管Git当时可能很受欢迎,但直到GitHub的诞生,Git才真正起飞。GitHub成立于2008年2月,将Git带到了更广泛的用户群体,并为公共Git存储库提供了一个免费的托管站点(以及用于私有存储库的商业计划)。有人认为,GitHub是Git比其他工具(如Hg和Bzr)更快地崛起的原因之一。
GitHub带来的是一种新模型的关注;与其创建补丁不同,GitHub鼓励对存储库进行普遍分支。因此,如果您想对现有存储库进行更改,您可以分叉它(并创建自己的克隆),进行更改,然后发送拉取请求。
pull
在Git工作流中与其他DVCS工具相比并没有什么重要的区别。毕竟,Pushing
和pulling
是DVCS工作流中的两个关键原语。但GitHub方法的新颖之处在于,pull
可以作为一条带外消息发送给上游存储库所有者,建议这个想法。
不仅如此,上游所有者随后将收到通知,并能够在原位查看请求,以及相应的差异(通过Web界面,而非邮件客户端)。随后的进展,例如通过Web界面进行分叉以修复拼写错误的能力,意味着任何人都可以通过Web提出更改,甚至无需在本地编译代码。
Pushing, Pulling, Patching or Proposing
Git存储库的工作流程可能会根据您使用的项目类型和托管环境而异。它们有:
- Pushing:您可以直接写入存储库,因此只需推送更改。
- Pulling:有人在本地进行了更改,并要求您从他们的存储库拉取更改。
- Patching:通过传输机制(bugzilla、电子邮件)发送差异/补丁供考虑。
- Proposing:您使用像Gerrit这样的工具提出更改,随后可以合并。
每个项目可能有不同的操作风格,没有一种“正确”的使用Git存储库的方法。例如,GitHub在从他人那里获取更改时,强烈倾向于采用拉取模型(当然,存储库所有者可以直接进行推送)。对于Linux内核来说,出于历史原因以及透明性和开放式讨论,它选择了打补丁(通过电子邮件)的模型。
最后一种——提议——是拉取、推送和打补丁模型的结合。它们类似于GitHub的拉取机制,因为项目所有者可以查看所有传入更改的列表并决定使用哪些;但基于推送的上传意味着不必在远程服务器上分叉原始存储库。最后,像Gerrit这样的工具可以用于生成补丁、在原地进行讨论,甚至作为通过标准的git fetch协议进行消耗的Git存储库。
GitHub的拉取模型的方法确实在愿意尝试该方法的用户数量上产生了广泛的影响。关于协作开发模型,他们在这个主题上有一篇说明:
1、
Fork + Pull
模型允许任何人分叉现有存储库并将更改推送到他们的个人分叉。这种模型减少了新贡献者的障碍,并且因为它允许人们独立工作而无需预先协调,所以在开源项目中很受欢迎。
2、共享存储库模型在小团队和组织协作私有项目时更为普遍。每个人都被授予对单个共享存储库的推送访问权限,并使用主题分支来隔离更改。
确实,如果存在较小的更改(比如文档中的拼写错误),与基于 Web 的界面结合使用的分叉 + 拉取模型可以极大地简化贡献者的工作。与必须在缺陷跟踪系统(或类似 Gerrit 的工具)上创建帐户相比,存储库可以被分叉、修复,并向存储库维护者发送拉取请求。在 GitHub 中的合并按钮的情况下,如果问题足够简单,维护者通常可以无需检出代码即可将修复合并进来。降低接受更改的障碍有助于保持活跃的开源项目活跃并向所有人开放。
Fork + Pull
模型唯一的问题在于如何将更改归因于用户。例如,一些开源基金会希望确保任何更改都是根据现有的开源许可证进行的(例如 Apache 或 Eclipse)。其他项目则不那么严格,愿意接受任何人的贡献,假设任何贡献者都同意了许可证。patches-to-bugzilla 或 gerrit push 提供的另一个服务是接受贡献者协议,该协议通常规定个人有权根据特定许可证授予代码。创建帐户的一个副作用通常意味着(明示或暗示)同意遵循该基金会的许可规则。
因此,使用 Git 没有“正确”的方式;不同的团队、基金会和项目会对使用特定策略有自己的偏好,并可能随时间演变。相反,了解可用的选项,以便为该项目做出正确的选择,了解可用的不同工作流程是很有用的。