网络公司源码-谷歌的代码管理

Google和Facebook都只有一个代码仓库,整个公司的代码都放在这个仓库里。

我一直很困惑为什么要这样做,以及在一个库中拥有不同语言的项目有什么好处?

最新一期的《ACM Communications》(第59卷第7期)有一篇论文《谷歌为什么要把数十亿行代码放在一个库里?》 》,作者是Google基础设施团队的工程师,算是官方对这个问题的详细解答,读完感觉收获很大,以下为摘录。

1. 概述

Google首先使用CVS进行代码管理,并于1999年改为Perforce。当时是Perforce主机,加上各种缓存机器。

当时整个公司的代码都在一个仓库,这种做法就一直沿用至今。 由于规模不断扩大,Perforce已经不能满足需求,Google开始使用Piper,一个自己开发的版本管理系统。

Piper建立在Google自己的分布式数据库系统(以前称为Bigtable,现在更名为Spanner)之上,分布在全球10个数据中心,保证了全球Google员工良好的访问速度。

目前,该代码仓库包含10亿个文件、3500万条提交记录、86TB大小、数万用户。 工作日每秒有 500,000 个请求,高峰时段每秒有 800,000 个请求,大部分来自自动化构建和测试系统。

Google 90%以上的代码都放在Piper中。 对于那些需要外部协作的开源项目,代码放在Git中,主要是Android项目和Chrome项目。 Git的特点是所有历史记录都会复制到用户本地机器,因此不适合大型项目,必须拆分成较小的库。 以Android为例,该项目包含800多个独立仓库。

2 Piper 设计 2.1 结构

整个仓库采用树形结构。 每个团队都有自己的目录。 目录路径是代码的命名空间。 每个目录都有一个所有者,负责批准该目录的文件更改。

2.2 权限控制

Piper支持文件级权限控制。 99%的代码对所有用户可见,只有少数重要配置文件和机密关键业务有访问限制。

如果机密信息被意外放置在 Piper 上,文件可以被快速擦除。 而且,所有的读写都有日志,管理员可以查到谁读了该文件。

2.3 工作流程

Piper的工作流程如下图所示。

开发人员首先创建文件的本地副本,称为“工作区”。 开发完成后,工作区的快照将与其他开发人员共享以供代码审查。 审核通过后才能将代码合并到中央仓库。

2.4 客户端

大多数开发人员通过名为 CitC 的客户端访问 Piper。

开发者通过CitC在Piper上浏览和同步文件,但编辑和修改是在自己的工作区中,只保存更改的文件(一个工作区一般不超过10个文件)。 CitC有云存储机制,每个工作空间都是云端的一个目录。 这些文件在通过代码审查后从 Citc 合并到 Piper 中。

也允许不使用CitC,所有代码都存储在本地,最后用Git客户端提交给Piper。 然而,由于 CitC 提供了更多功能,目前使用率为 80%。

2.5 骨干网开发

谷歌使用“基于主干的开发”。 代码一般都提交到主干的头部。 这可确保所有用户看到相同代码的最新版本。

“主干开发”避免了合并分支的麻烦。 Google一般不使用分支开发,分支仅用于发布。 大多数时候,发布分支是主干在某个时间点的快照。 未来的调试和功能增强会提交到主干,并在必要时挑选到发布分支。 trunk的长期并行开发分支在Google是非常少见的。

由于Google不采用“分支开发”,引入新功能时,一般在代码中使用开关控制。 这避免了启动另一个分支,并且还可以轻松地通过配置切换功能,并在新功能出现故障时切换回旧功能。 等到新功能稳定后再完全删除旧代码。 Google有类似A/B测试的路由算法来评估代码的性能,由于配置开关的存在,很容易实现。

2.6 代码审查

所有代码在合并到存储库之前都必须经过审查。 大多数评论对任何人开放,任何 Google 员工都可以对代码发表评论或提交更改。

代码审查基于 Google 代码风格指南。 谷歌有一个名为 Critique 的工具,可以查看每一行代码的历史演变。

2.7 自动测试

审核完成后,测试将自动运行。 测试通过后,代码将合并到Piper存储库中网络公司源码网络公司源码,整个过程不需要人工干预。

3、优点

单一代码仓库主要有以下优点。

(1)统一版本

整个公司的代码有统一的版本和路径,不存在找不到最新版本文件的问题。

(2) 广泛的代码共享和复用

任何人都可以浏览和使用全公司的代码,极大地方便了代码共享和复用。

(3) 简化的依赖管理

如果你是一个库文件或API的作者,由于每个人的代码都在一个库中,所以很容易找到所有依赖于你的下游代码。

每当代码更改时,所有依赖于您的代码都会自动构建。 如果大量构建失败,系统会自动撤消本次提交。 这也保证了所有代码都依赖于最新版本,避免了依赖不同版本带来的冲突。

此外,由于代码的边界很明确,因此不会发生循环依赖。 而且,API的作者可以很容易地了解其他人如何使用他的API。

(4) 原子变化

由于每次代码变更所造成的影响都在一个仓库中,因此都是原子变更。 因此,很容易撤销或预先测试其影响。

为了防止错误提交,Google引入了“预提交”(即在提交之前,分析依赖它的代码是否会构建失败)。

(5)大规模代码销毁

单一代码存储库为查找和分析代码提供了极大的便利。

Google 的静态分析引擎 Tricorder 定期运行来分析代码。 例如,C++11标准发布后,很容易找到所有需要改进以进行性能优化的变量声明语句。 该引擎还为许多错误提供“一键修复”,同时产生大量统计数据。

此外,编译团队还会分析不同语言的所有代码,以查找不合理的代码和过时的 API。

4、缺点

单一代码存储库的主要缺点是所有工具都必须自己编写,因为市场上没有软件可以管理这种规模的代码存储库。

五、总结

单一代码仓库适合崇尚透明、开放的大型软件公司,但不适合小公司和拥有大量私有代码的公司。

(超过)