自从分布式版本库控制系统(Mercurial/Hg、Bazaar、Git等)诞生之后,有越来越多的开源项目迁移了版本控制系统,例如从Subversion或CVS迁移到分布式版本控制系统。因为众多的开源项目逐渐认识到,集中式的版本控制管理方式阻止了更多的人参与项目的开发,对项目的发展不利。
集中式版本控制系统的最大问题是,如果没有在服务器端授权,就无法提交,也就无法保存自己的更改。开源项目虽然允许所有人访问代码库,但是不可能开放“写操作”授权给所有的人,否则代码质量无法控制(Gerrit审核服务器是例外)。于此相对照的是,在使用了分布式版本控制系统之后,任何人都可以在本地克隆一个和远程版本库一模一样的版本库,本地的版本库允许任何操作,这就极大的调动了开发者投入项目研究的积极性。
分布式的开发必然带来协同的问题,如何能够让一个素不相识的开发者将他的贡献提交到项目中?如何能够最大化的发动和汇聚全球智慧?开源社区逐渐发展出金字塔模型,而这也是必然之选。
金字塔模型的含义是,虽然理论上每个开发者的版本库都是平等的,但是会有一个公认的权威的版本库,这个版本库由一个或者多个核心开发者负责维护(具有推送的权限)。核心的开发人员负责审核其他贡献者的提交,审核可以通过邮件传递的补丁或者访问(PULL)贡献者开放的代码库进行。由此构成了由核心开发团队为顶层的所有贡献者共同参与的开发者金字塔。
Linux社区就是典型的金字塔结构。Linus Torvalds的版本库被公认为是官方的版本库,允许核心成员的提交。其他贡献者的提交必须经过一个或多个核心成员的审核后,才能经由核心成员代为推送的到官方版本库。
采用这种金字塔式协同模型不需要复杂的Git服务器设置,只需要项目管理者提供一个让其他人只读访问的版本库。当然管理者要能够通过某种方法向该版本库推送,以便其他人能够通过该版本库获得更新。
因为不能直接向项目只读共享的版本库提交,为了能让项目的管理者获取自己的提交,贡献者需要提供项目管理者访问自己版本库的方法。建立一个自己所有的只读共享版本库是一个简单易行的方法。在第5篇搭建Git服务器的相关章节,会介绍几种快速搭建只读Git版本库的方法,包括:用HTTP智能协议搭建Git服务器,用Git协议搭建Git服务器。
贡献者在自己的只读共享版本库建立后,需要对自己贡献的提交进行一下检查和整理。
贡献的提交要处于一个单独的特性分支中,并且要为该特性分支取一个有意义的名字。
使用贡献者的名字以及简单的概括性文字是非常好的特性分支名。例如为自己的特性分支命名为jiangxin/fix-bug-xxx。
贡献的提交是否是基于上游对应分支的最新提交?如果不是需要变基到上游最新提交,以免产生合并。
项目的管理者会尽量避免不必要的合并,因此会要求贡献者的提交尽量基于项目的最新提交。使用下面的方式建立跟踪远程分支的本地分支,可以很简单的实现在执行git pull操作时使用变基操作取代合并操作。
$ git checkout -b jiangxin/fix-bug-xxx origin/master
$ git config branch.jiangxin/fix-bug-xxx.rebase true
hack, hack, hack
$ git pull
然后贡献者就可以向项目管理者发送通知邮件,告诉项目管理者有贡献的代码等待他/她的审核。邮件中大致包括以下内容:
使用补丁文件方式贡献代码也是开源项目常用的协同方式。Git项目本身就是采用该方式运作的。
在第3篇第20章“补丁文件交互”已经详细介绍了该模式的工作流程,请参考相关章节。