正文
图6
基于 trunk 的开发是有益的,因为它避免了合并长支链分支时的痛苦。 尽管代码分支通常用于发布上线,但是在 Google 代码分支支持的不好。 通常在 trunk 上开发 bug fix 和必须添加到版本中的增强功能,然后将其引入到 release 分支中(参见图6 )。 由于需要保持稳定性并限制发布分支上的流失,所以 release 通常是“head”的快照,根据需要从”head”拉出可选的少量带代码。在 branch 和 trunk 上并行开发的长寿命 branch 是非常罕见的。
Piper 和 CitC 可以在 Google 代码库的规模下,使用单一源代码库进行有效的工作。
当开发新功能时,新旧代码路径通常同时存在,通过使用条件标志来控制。 这种技术避免了开发分支的需要,并且通过配置更新来打开或者关闭功能。 虽然开发人员还需要一些额外的复杂性,但是避免了开发分支合并问题。 标志翻转使得用户切换具有问题的新实现变得更加容易和快捷。 该方法通常用于项目特定的代码,而不是通用的库代码,最终会删除标志和旧代码。 Google 使用类似的方法来对不同代码做测试。 这样的A / B test 可以从代码性能到与产品变化相关的参数。
Google 工作流程
。 需要几种最佳实践和支持系统,以避免在基于 trunk 的开发模式中碰到的问题。 例如,Google 有一个自动测试基础设施,可以在几乎每个提交上启动所有受影响的依赖项测试。 如果一次代码更改造成构建破坏,系统就会自动撤消更改。 为了减少发生的错误代码的发生率,高度可定制的 Google “预提交”基础架构可以在更改代码添加到代码库之前自动进行测试和分析。 针对所有更改运行一组全局预先提交分析,代码所有者可以创建仅在其指定的代码库中的目录上运行的自定义分析。 仅有一小部分非常低级别的核心库使用branch的机制,以保证在新版本暴露给客户端代码之前执行其他测试。
鼓励代码质量的一个重要方面是期望在提交到代码库之前对所有代码进行 review。 大多数开发人员可以在代码库的任何地方查看和建议更改(除了一组更加精心控制的高度机密代码之外)。 不熟悉的开发人员更改相关代码的风险通过代码 review 过程和代码所有权的概念得到缓解。Google 代码库以树结构布局。 每个目录都有一组所有者控制是否接受目录中文件的更改。 所有者通常是在相关目录中处理项目的开发人员。 变更通常会从一位开发人员收到详细的代码审查开始,从而评估变更的质量,以及所有者的认可批准,评估变更对的适用性。
代码 review 者会对代码质量方面进行评论,包括设计,功能,复杂性,测试,命名,评论质量和代码风格。 Google 已经编写了一个名为 Critique 的代码审查工具,允许审阅者查看代码的演变,并对任何一行的更改进行评论。 它鼓励进一步的修改和 review,以达到所有者的要求。
Google 的静态分析系统(Tricorder [10] )和预提交基础设施还可以在 Google 代码审查工具中自动提供有关代码质量,测试覆盖率和测试结果的数据。 这些计算密集型检查被定期触发,发送代码修改以供 review。 Tricorder 还为许多错误提供了修改的建议。 这些系统提供重要数据,以提高代码审查的有效性,并保持 Google 代码库的健康。
Google 开发人员小组不时进行代码清理,以进一步维护代码库的健康。 执行这些更改的开发人员通常将过程分为两个阶段。 首先进行大的向后兼容的更改。 一旦完成,可以进行第二个较小的更改以删除不再引用的代码。 Rosie 工具支持这种大规模清理和代码更改的第一阶段。 使用 Rosie,开发人员可以创建一个大补丁。 Rosie负责将大补丁分成较小的补丁,独立测试,发送出去进行代码 review,并在通过测试和代码审查后自动提交。 Rosie 根据项目目录行拆分补丁,依靠前面描述的代码所有权层次结构将补丁发送给适当的审阅者。
图7
图7报告了每月通过 Rosie 进行的更改次数,表明 Rosie 作为 Google 大规模代码更改的工具的重要性。 使用Rosie需要注意其使用成本。随着 Rosie 的流行度和使用率的增长,显而易见,必须建立一些控制措施,以将 Rosie 的用途限制高价值变化中。 2013 年,Google 通过了正式的大规模变化 review 流程,导致了从 2013 年到 2014 年的 Rosie 数量的减少。在评估 Rosie 变更时,评审委员会将变更的收益与审阅者时间和存储库流失的成本相平衡。我们稍后更仔细地研究类似的权衡。
总而言之,Google 开发了许多工具来支持其庞大的代码库,包括基于 trunk 的开发,分布式源代码存储库 Piper,工作区客户端 CitC 以及工作流支持工具 Critique,CodeSearch,Tricorder,和 Rosie。 我们在这里讨论这个模型的利弊。
分析
本节概述并扩展了单一代码库的优势以及与维护此类模型规模相关的成本。
优点
。 支持超大规模的 Google 代码库,同时为千上万的用户服务,保持良好的性能是一个挑战,但由于其引人注目的优势,Google 已经拥抱了单一代代码库。
最重要的是它支持:
单一代码库提供统一的版本控制和单一代码来源。 对于哪个存储库托管文件的权威版本,并不存在任何混淆。 如果一个团队想要依赖另一个团队的代码,可以直接依赖。 Google代码库包含大量有用的库,而单一代码库可以引导广泛的代码共享和重用。
Google构建系统[5]可以轻松地在目录之间包含代码,从而简化依赖关系管理。 对项目的依赖性的更改会触发依赖代码的重建。 由于所有代码都在相同的存储库中进行版本控制,所以只有一个版本,也不关心依赖关系的独立版本。