在 OpenAI 扩展 Git
在 OpenAI,我们的代码库规模庞大,每天有数百名工程师在其中工作。随着团队和仓库的不断增长,我们的 Git 工作流开始触及传统工具链的极限。本文是三篇系列文章的第一篇,介绍我们如何为超大规模重新思考 Git。
问题所在
我们单体的仓库(monorepo)已增长到数十 GB,提交历史跨越数年,每天都有数千次提交来自遍布全球的工程师和自动化系统。标准 Git 操作——clone、fetch、status、checkout——开始耗时数秒到数分钟,严重拖慢开发者效率。
具体痛点包括:
- 初始克隆缓慢:完整克隆仓库需要数十分钟,具体取决于网络位置。
status变慢:工作区越大,扫描未跟踪文件与变更的耗时越长。fetch沉重:每天拉取成百上千的分支和标签,使增量更新体积膨胀。- 引用过多:海量分支与标签使引用广告(ref advertisement)巨大,每次拉取都要传输。
- 工具链摩擦:围绕 Git 构建的内部工具(代码搜索、CI 检出、代码审查)都受制于这些瓶颈。
我们的方案
我们没有选择放弃 Git,而是系统性地分析瓶颈,并针对每个层面的扩展性问题采用相应技术。总体思路分三层:
- 减少传输的数据量:使用部分克隆(partial clone)和稀疏检出(sparse checkout),让工程师只获取自己需要的内容。
- 减少引用开销:通过引用过滤与协议层面的优化,避免每次拉取都广播全部引用。
- 加速本地操作:改进工作区扫描、文件系统监控与索引管理,让
status和checkout保持快速。
后续内容
本系列的下一篇将深入探讨部分克隆与稀疏检出在 OpenAI 的落地细节与效果;第三篇将介绍引用管理、协议优化以及我们围绕 Git 构建的内部工具。
%%IMG1%%
支持状态
我们在生产环境中逐步推出这些改动,并持续监控对开发者工作流的影响。部分特性仍处于试验阶段,我们会随进展更新支持状态。
快速入门
- 确保使用支持部分克隆的 Git 版本(Git 2.19 及以上)。
- 在克隆时启用过滤:
git clone --filter=blob:none。 - 按需配置稀疏检出:
git sparse-checkout set。 - 通过内部开发者文档获取我们推荐配置的完整说明。
技术栈
- Git:核心版本控制系统,使用部分克隆、稀疏检出与协议 v2。
- 自定义服务端:负责引用过滤、协议优化与访问控制。
- 文件系统监控:用于加速工作区状态扫描。
- 内部工具:代码搜索、CI 检出与代码审查系统,均适配新的 Git 工作流。
在 OpenAI 扩展 Git
构建面向智能体规模(agentic-scale)的源代码控制,同时持续投入 Git 生态。
作者:Aaron Friel、Taylor Blau、Ted Nyman,技术团队成员
分享
我们为什么需要新的源代码控制系统
标题:OpenAI 分享如何在超大规模下扩展 Git(第 2/3 段)
过去一年里,我们单体仓库(monorepo)的规模和对它的需求都以惊人的速度增长。显然,我们需要改造源代码控制系统,使其能够扩展到 Codex 所带来的并发工作水平。
OpenAI 单体仓库的季度提交增长
提交到 master 的增长情况(相对 2024 年第一季度)
实际增长
基准情形估算
我们构建了 Pando——一个面向 Git 仓库的新后端,全程没有中断任何工程工作,也没有改变团队使用 Git 的方式。如今,Pando 为 OpenAI 单体仓库中的所有开发工作提供支持。Pando 的设计旨在实现两个雄心勃勃的目标:第一,水平可扩展的写入,针对向众多分支的并发推送进行优化;第二,最大化读取吞吐量,使客户端能够以足够快的速度下载数据,从而充分利用其可用网络带宽。
我们在实现这些目标的同时,保持了对 Git 协议和客户端的兼容性,使我们既能让工程师、也能让智能体将 Pando 无缝接入现有工作流。在生产环境中,Pando 将推送延迟中位数降低近 5 倍。如今它每天交付近 1 PB 的 Git 数据。
在本文中,我们将介绍构建新源代码控制系统的动机,以及为什么选择保持与 Git 的兼容性。我们会将我们的系统与常见的 Git 扩展方案进行比较,说明为什么 Pando 能够独特地满足 OpenAI 的扩展性需求。我们还会讨论下一步计划,以及我们将如何继续为 Git 做贡献,以支持智能体规模的工作。
为什么我们需要一套新的源代码管理系统
Codex 改变了 OpenAI 的研发规模与节奏,让工程师可以并行推进远更多的工作。这意味着更多的分支与推送,更多的合并,以及来自开发环境、研究任务和 CI 的更多拉取与克隆。
这些需求会叠加放大。如今一名工程师可能同时有数个变更准备进入 CI,而每次推送都可能触发多个任务去拉取同一个提交。
大约从去年年底开始,支撑我们单一代码库(monorepo)的系统开始不堪重负。我们遭遇了拉取和推送缓慢、合并失败等问题,可靠性有时甚至跌破 90%。是 Git 本身达到了极限,还是我们服务单一代码库的方式达到了极限?Git 诞生于一个通过邮件交换内核补丁的社区。二十多年来,随着开发者构建软件的方式不断变化,他们一直在围绕 Git 调整自己的工具。当我们自己的单一代码库开始出现摩擦时,对我们而言重要的是:我们仍能在这套工作之上继续构建。
我们看到了一条路径:既保留这套熟悉的工作流,又重建后端,以支持并行推送到不同分支,并同时向众多读取者提供同一份历史。以 Git 作为我们源代码管理工作流的基础,意味着对客户端的改进可能惠及 OpenAI 之外的更多人。我们希望把来自我们那份 Git 副本(在新窗口打开)的改进贡献到上游,与更广泛的社区分享。
为规模化 Git 而做的工程
扩展一套源代码管理系统有两个关键维度:众多写入者向不同分支推送,以及众多读取者拉取同一份历史。Pando 针对这两点都做了优化。
首先,Pando 独立协调对每个分支的更新。对不相关分支的更新可以并行进行,读取某个分支的客户端会拿到该修订所需的历史。代价是,同时查看多个分支的读取者可能看到它们处于不同的时间点。
其次,Pando 在多次拉取之间复用包文件(packfile,Git 用于将多个对象压缩在一起的格式),而不是为每个客户端单独生成一个包文件。客户端可能会下载一些它已经拥有的对象,但服务器可以用很少的计算量把同样的字节提供给众多客户端。
这些选择让我们能够跨分支扩展写入,并从缓存中提供读取。为了看清它们如何协同工作,我们先从 Git 如何存储和传输历史说起。