协作开发和二进制管理

因为经济的原因,协作开发一直是仅做源代码管理,由开发者checkout代码后自行编译。

但在有大笔资源的情况下,时效应该是更为重要的东西,为什么不考虑二进制管理?

在公司,一个项目编译出来需要3到5个小时。。(会跑来这里写东西的原因也说出来了。。)。。反正提交代码之前每个人都必须做build, 做测试,然后才能提交的,为啥不一开始就把大家build的结果保留下来,需要用的人自取呢?

这正好可以跟系统每天的daily-build和test-suite结合起来,一起完成。

开发过程还是一样,checkout, update,之后提交。但这个时候提交的内容不要直接进main branch. 先在他checkout的版本基础上,patch上他的update,之后做buddy-build和test-suite。如不通过,打回重练。这个过程可以以天或者以周为单位。以天为例吧。每天晚上12点,系统尝试将通过测试的patch进行合并。如果合并失败的话,就把导致合并失败的patch拿掉,直至合并成功为止。如果成功合并,进main branch, 并且做daily-build和test-suite。假如合并之后导致新的bug或build break产生,应该知道这些问题是协作造成的,将受影响的文件或模块相关的patch除去,重新build-test。直至没有bug产生为止。次日早晨发邮件给没进main branch的patch的owner们,让他们解决问题。

关键在于编译。在编译脚本里面可以加上新的机制,允许从服务器下载跟本地版本相符的obj,lib,dll,exe等内容。即编译器需要和源代码管理器协作,确定即将编译的一段代码是否被edit过。如果没有被edit过,检查目前版本的代码在服务器上是否有相应的二进制目标文件。如果有就可以直接下载,如果没有才考虑自己编译。这个过程跟编译顺序相反,是自顶向下,从最终目标开始比较,尽可能下载整个的lib,dll之类,这样就可以避免下载很多可能本地根本用不到的obj文件。

当然,由于二进制文件没有有效的增量备份算法,在服务器上不可能保存所有版本的二进制文件。但至少可以保存最近几天或几周的版本的,还有历史上的几个milestone版本的。

当然在这种机制下必须要求所有人都在最新版本下工作,否则必须新开branch。每天的patch都只能接受从当天版本号基础上checkin。如果有旧版本的patch提交,可以有两种选择,一种是要求开发者更新到最新,然后重新提交patch,另一种是要求开发者开新branch, 并在新branch上做开发。具体选择哪一种看具体需求以及开branch的成本了。

毕竟当项目变大,每个人要处理的模块都是很小的一部分,其余的部分只需要lib,dll就可以了,没有必要自己编译。并且,如果不需要编译,其实开发人员的机器配置就没有必要那么高,节省的成本可以做更好的服务器机器。其实这种策略也更符合所谓“云计算”。当然更加有趣的是,可以让编译本来就发生在由所有客户机结成的计算网格上面。并且所有的二进制文件也都分布式存储在这些分散的机器上面。服务器仅仅是一台或几台管理信号的中转路由。这样做可能可以进一步降低成本,并且对于每个计算网格而言,本地编译某个模块,然后二进制文件就存储在本地,也没有太多网络开销。当然具体算法如何实现,这个恐怕要仔细研究了。(研究生课题?:)