7.合并导致了多少问题
商场门口竖起了巨大的圣诞树,上面点缀着五彩缤纷的各种小玩意儿。华灯初上的时候,圣诞树上的灯也闪亮起来。晓川的心情也不错。连续两次,都是星期四就完成了集成工作,不用周末加班喽。更重要的是,有小小的成就感!
但是说到担心,还是有的。这个项目是公司最大的项目。项目刚进行了一小半。还不断有新员工或者其他项目的程序员陆续加入这个项目。可以想见,未来提交会越来越多。很可能在不久的将来,又重新回到需要周末加班的状态,而且说不定还会再延长,延长到第二个星期去。怪不得当初订的是每两周集成一次,而不是每周集成一次!
看来还得继续改进啊。这次改进,去掉了大约一半的构建问题。得想办法把剩下的一半也去掉,或者至少是,进一步减少。
跟师傅请教,师傅说,估计是程序员合并的时候不认真。晓川觉得有些道理。更认真一点,当然会更好些。然而,根据晓川的观察,在合并代码的时候,绝大部分内容都是自动合并的,因为不同的程序员通常改动的是不同的文件或者一个文件的不同地方。只有碰巧遇到改同一个地方的时候,合并工具才会报合并冲突,晓川才会找程序员来人工合并这一处。而构建失败,固然可能是因为人工合并的这些地方有问题,也有可能是自动合并的地方没有合并对,产生了问题。
既然不论是人工还是自动,都可能出错,那就都再请人检查一遍好不好呢?晓川设想了一下这个情景,每当自动合并完一个提交后,就过来一个程序员,把自动合并的结果再审一遍。这个主意怎么样?要不要跟英英讨论一下呢?
但是很快晓川意识到这个方法并不可行。现在绝大多数内容的合并都是自动完成的,只有很少是人工完成的,尚且需要半天多的时间。若是全部合并都仔仔细细复审一遍,那就不是再增加一倍的时间的事了。虽然合并之后编译构建时遇到的错误会减少,但是合并阶段耗费的时间会延长不知多少,得不偿失啊。这招不行。
这样吧,还是再仔细研究一下,合并时发生了什么事情。第一个提交,不需要合并。第二个提交,要跟第一个提交合并。第三个提交,要跟第一个和第二个的合并的结果进行合并……画出图来。如图2所示。
图2 合并越来越困难(线段长度代表改动量大小)
这么看来,越到后来的提交,要合并的内容就越多,也就越困难。当然,前提是每个人提交的代码改动量都一样。而且这是有随机性的,这只是统计上宏观看到的结果。
真的是这样吗?好像确实有点那个意思,每轮集成,开始的时候,合并冲突会少些,越往后,合并冲突会越多。不过,并没有理论上分析的那么大的差别。嗯,现实和理论总是不太一样嘛。就像当年学物理,总是研究刚体、质点之类的理想情况,就是不考虑空气阻力之类的现实。
那么,回到对代码合并的分析。会不会是类似空气阻力的东西,影响了理论推导的结果呢?那么,这里的空气阻力到底是什么呢?
晓川决定实际调查一下。从本周的第一个提交研究起。按照刚才的理论,第一个提交应该没有合并问题:就这一个提交,跟谁合并去啊。然而晓川依稀记得,这次第一个提交就遇到了合并冲突。这是怎么一回事呢?
晓川去看版本控制工具里展示的版本树,仔细研究为什么会有合并。最后终于弄明白了,本周的第一个提交所对应的任务分支,并不是基于最新的基线,而是基于次新的基线,也就是最新基线之前的那个基线。而当晓川从任务分支往集成分支合并的时候,在任务分支上的改动,要跟上一轮集成的所有改动进行合并。如图3所示。
图3 为什么会有合并
原来不是因为有空气阻力,而是理论模型就不适用。
晓川有点儿沮丧,原来是自己弄错了。不过很快他就意识到,这其实是件好事儿,因为这意味着有可以改进的地方:既然是没有基于最新基线,多造成了很多合并的问题,那么基于最新基线,就能够有效地减少合并的问题了!