一位局外人对 Scion 与 Mononoke 的看法

Lobsters Hottest 新闻

摘要

一位 Databricks 源代码管理工程师以局外人的视角分享了对 Anthropic 新推出的集中式版本控制系统 Scion 的看法,将其与 Facebook 的 Mononoke 及 Mercurial 进行对比,并强调版本控制工具设计应以用户为中心。

<p><a href="https://lobste.rs/s/s2qeww/outsider_s_perspective_on_scion_mononoke">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/11/01 15:37

# 一个局外人对 Scion 和 Mononoke 的看法 来源:https://typesanitizer.com/blog/scion.html Lobste\.rs 上的讨论 (https://lobste.rs/s/s2qeww/outsider_s_perspective_on_scion_mononoke) 最近,Anthropic 发布了一篇关于其新版集中式版本控制系统的博客文章 Scion (https://www.anthropic.com/research/redesigning-source-control)。作为 Databricks 源码管理团队的一员,我们拥有一个庞大的 monorepo 并正在探索各种方案,我觉得在这里分享一下我的观点可能会有用。 (例行声明:本文仅代表我个人的观点,不代表我的雇主。) 我建议先阅读 Anthropic 的文章再继续阅读本文。你可能还想预先读一下 Rain Paharia 的 Anthropic 的 Scion 深受 Mononoke 启发 (https://sunshowers.io/posts/anthropic-mononoke/) 以及后续文章 更多关于 Anthropic 的 Scion 抄袭 Mononoke 的内容 (https://sunshowers.io/posts/anthropic-mononoke-2/)。 ## 我与版本控制的历史 在深入细节之前,了解一下我的背景可能对你有帮助。如果你对此不感兴趣,可以直接跳到 技术评论 (https://typesanitizer.com/blog/scion.html#technical-commentary) 部分。 --- 我从未在 Facebook 工作过,但我有史以来最喜欢的技术演讲之一是 Durham Goode 在 Git Merge 2017 上的 Scaling Mercurial at Facebook (https://www.youtube.com/watch?v=gOVD-DrUpwQ)。Goode 是 Facebook 源码管理团队中任职时间最长、资历最深的成员。(来源 (https://news.ycombinator.com/item?id=50106738)) 这场演讲涵盖了服务器端和客户端的许多有趣方面。在服务器端,包括通过服务端 rebase(pushrebase)解决推送争用、使用可扩展的对象存储来存储提交、将各种源码管理查询迁移到服务器端等。在客户端方面,提到了 smartlog 以及其他用于更方便地操作历史(相比 Git 中的 rebase)的 CLI 命令。 然而,与其说是演讲的技术方面(本身就很有趣!),不如说这些年来一直留在我脑海中的主要因素是 Goode 的语气和言辞中所体现的*对用户的深切关怀*。没有声音的力量很难传达这一点,你应该去看这个演讲!但以下是一些能体现这一点的引文: 在 `hg smartlog` 的上下文中:`hg smartlog` 为你提供一个聚焦视图,展示*你的*分支以及它们与开发主干的关系。 > 我知道 Git 如果你知道咒语也能产生这种 UI,但这里的关键不在于它能做到这一点;而在于它成为他们源码管理环境的默认视图。力量就来自于此:让用户真正直观地使用源码管理,无需阅读 man 手册就能理解相关概念。 在 `hg absorb` 的上下文中:`hg absorb` 自动地识别提交栈中正确的提交,将修复 squash 进去并相应地重写历史。这使得处理堆叠式的变更更加容易。 > 这正是我们需要为用户发明的 UI 类型:匹配他们的意图并尽其所能地完成,而无需用户理解他们所要做的一切。这有一点点魔法,但它是以一种非常干净的方式呈现的魔法。我认为很多用户体验都能从这种方法中受益。 关于从错误中恢复: > 在 Mercurial 中,如果你想撤销一次 amend 或撤销提交的一部分,你只需运行 unamend 和 uncommit 就行了。你不需要理解 reflog;你不需要为了理解 reset 而获得博士学位。它就是能工作,它给用户信心,让他们知道自己可以从错误中恢复。这是我们能做的最重要的事情之一:提供让用户对他们所做的事情有信心的用户体验。 在接近尾声时,总结道: > 在用户体验方面,我们作为源码管理社区需要更好地构建易于访问、直观的 UI,让新手用户也能成为高级用户。我刚才所讲的一切就是我们在 Facebook 为用户所做的。如果 Git 社区能做到这一点,庞大的 Git 用户群体有可能重新定义整整一代人的生产力。 多年来,当我继续使用 Git 工作时,这些工作流的可能性一直萦绕在我脑海里。我尝试在 `git` CLI 之上构建自己的封装来做其中的一些事情,但由于一切都总是调用 `git`,我无法获得合理的性能,而且我对 Git 内部原理的理解还不够深入,无法做得更好。 我最终一直使用原生 Git,直到 Waleed Khan(Waleed 曾在 Facebook 从事开发工具工作,后来在 Twitter 从事与版本控制相关的工作)创建了 git-branchless (https://github.com/arxanas/git-branchless),支持 smartlog、内存中的 rebase、undo 等功能。我迫不及待地采用了它。我也经常使用 Stephen Jung 的 git-absorb (https://github.com/tummychow/git-absorb)。即使在今天,`git absorb` 的 README 开头仍然引用了 Mozilla 邮件列表上对 `hg absorb` 的提及作为关键灵感。 最后,今年早些时候(2026 年),我在几次尝试后基本转为使用 jj (https://www.jj-vcs.dev/latest/)。jj 由 Martin von Zweigbergk 创建,他曾为 Git 做过贡献,后来加入 Google 并从事他们内部 monorepo 的 Mercurial 客户端工作。来源:Mercurial at Google(2023)(https://mercurial.paris/download/Mercurial%20at%20Google.pdf)。 所以,尽管我在整个职业生涯中几乎只使用过 Git,但从某种意义上说,我对 Goode 以及其他众多贡献者在 Mercurial 上所做的工作心存感激。 --- 我已经谈了一些我个人使用版本控制工具的经历。让我简要介绍一下我从事过的与版本控制相关的工作。 从 2021 年底到 2025 年底,我在 Sourcegraph 从事代码索引和导航工作。在其中的最后两年,我更多地从事用 Go 编写的后端工作,其中代码导航与版本控制紧密耦合。(这是因为代码导航数据可以上传到*任何*提交上。) 在此期间,一个反复出现的事故来源是镜像到 Postgres 中的提交图结构的(非)增量更新,以便能够高效地计算在哪个提交上"可见"哪些代码导航数据(存储在 Postgres 中)。 我记得对此感到沮丧,并半开玩笑地提出最好迁移到更定制的存储方案,或者在 Git 存储旁边建立自定义索引。那个提议并没有特别进展(我也并不期望它会),但对 Git 作为一个难以运维的数据库的挫败感一直伴随着我。 自 2026 年 3 月左右以来,我一直在 Databricks 从事源码管理工作。我做过的一些工作包括: - 在我们的开发机上强制执行一致的 Git 配置。 - 创建各种安全网,防止 agent 以触发病态性能的方式搞乱 Git 仓库。 - 根因定位并修复各种客户端 Git 性能问题。 所以在某种意义上,过去几个月里我大约*负责*监控和维护数千个 git checkout(我们庞大的内部 monorepo——根据压缩的具体情况,`master` 分支的历史大小在 20-50GB 范围内)的健康状况。(人生教训:不要因为一个数据库难以运维而对它发怒,免得猴爪收拢?😄) 除了本职工作,我还花了数十个小时研究 jj、Mononoke (https://github.com/meta/sapling/blob/main/eden/mononoke/README.md)(Facebook VCS 的开源服务器)、TigerBeetle (https://github.com/tigerbeetle/tigerbeetle),以及在较小程度上研究 RocksDB 和关于 LSM 树的论文。我还用 Tiger Style (https://tigerstyle.dev/) 原型实现了一个最小的代码存储服务器。 在此期间,我还有幸参加了 Git Merge 2026。(有趣的是,赞助商包括 OpenAI、Google、GitHub、Cursor 等,与会者包括大量从事 Sapling/Mononoke 工作的 Meta 员工,但据我所知没有 Anthropic 员工出席。) --- 呼,这真是大量的文字!至少,我希望这能帮助你理解我在写下以下各点时的背景。 本节涵盖我对 Scion 博文中所描述的整体设计和开发流程的看法。 ### 熟悉的部分 研究过 Sapling/Mononoke 之后,并且花了一些时间思考如何构建版本控制服务器,以下内容对我来说是显而易见的(因此不值得强调),并且/或者是抄袭的(没有明确注明出处): - 用 changeset 而不是 Git 风格的树 (https://git-scm.com/book/en/v2/Git-Internals-Git-Objects) 来表示提交:抄自 Mononoke。这部分出处是在 Rain 的博客登上 HN 首页后,博文后来更新时才添加的。 - 客户端-服务器不对称:据我所知,没有哪个大型 monorepo 在这方面是对称的。即使是 Git,也有某些配置选项只适用于客户端或服务器。 - 版本控制的 API:这是客户端-服务器不对称的自然结果。 - 水平可扩展性:对于 VCS 服务器来说,水平可扩展性很大程度上是免费获得的,因为它借用了对象存储的能力。(特别是,使缓存变得棘手的一件事是处理缓存失效,但这对内容寻址存储不适用。) - "提交必须廉价、增量且无锁":一旦你决定了"提交是不可变的内容寻址对象",这一点就自然产生了。 - "工作副本是可选的,并且按设计是稀疏的":在这个规模上,没有人会在所有地方一直将数百万个文件物化到磁盘上。 - 按目录的 ACL:Perforce、Piper 和 Mononoke 都支持这一功能。 - 没有运行完整 CI 的合并队列:(我是在字里行间推断的——博文中的措辞"当数百甚至数千个变更可以在测试运行期间合并时,CI 到底意味着什么?我们没能有效地复制业界标准的全局仓库锁定合并队列"并没有明确说明它指的是什么。)Mononoke 也做同样的事情。在较小的规模上,Uber 的 SubmitQueue (https://github.com/uber/submitqueue) 也不运行完整的 CI。 ### 惊人/新颖的部分 #### 迁移速度 > 为了支持这种增长,我们构建了 Scion——一个内部的版本控制系统——并在五个月内将我们的 monorepo 完全从 git 迁移过来。我们还在同一时间段内构建并发布了代码审查界面(称为 Antique)、代码搜索、丰富的源码管理 IAM 系统、管理并落地大量已审查代码的新方法等等。 这是由一个 7 人的团队和数量未披露的 Claude token 完成的。 读到这里,我的第一反应是:"这仍然是相当大量的工作。"使用 Git 时,人们(或 agent)很容易想出复杂操作来做特定的事情,而这些操作可能很难原封不动地映射到其他 VCS 上。所以他们能够完全剥离 Git 是令人印象深刻的。(博文里并没有百分之百清楚他们是否做到了这一点,但我是根据博文中的措辞做出的假设。) 我猜测以下一项或多项为真:(1)他们的 monorepo 缺少基于文件的 OWNERS 系统(2)OWNERS 系统在很大程度上通过 Claude 的自动批准来完成(因此不会在人工批准上形成瓶颈)或者(3)他们使用了一些有针对性的旁路手段,来修改人们的代码以使用他们自定义的 `scn` 客户端而不是 `git`。 #### "超级粉丝"Claude > 我们创建了 Slack 频道,让 Claude 专注于单一组件的健康状况。我们称这些 Claude 为"超级粉丝"。我们有一个 scion-daemon 超级粉丝,一个 scion-cache 超级粉丝,一个 Antique 合并队列超级粉丝 [....] 它们可以访问我们的遥测和日志,表现得像一个经验丰富的工程师,除了刷新图表和寻找任何异常之外无事可做。我们所有系统也有传统的告警,但我们的超级粉丝能够检测到细微而新颖的问题,相比之下让这些告警显得非常单一。 这是我(个人)没有听说过的、在其他地方部署过的模式,大概很大程度上是因为前沿模型 token 的成本。我猜测随着 token 价格的下降,这将变得更加普遍。 如果他们能给出一些这些超级粉丝发现的"细微而新颖的问题"的例子就更好了。 ### 奇怪的部分 #### 在开发循环中不鼓励使用 ref > Scion 的开发生命周期不鼓励使用 ref(指向提交的指针,如分支和标签),除了主 ref 或发布分支以外,因为每个服务器都必须达成一致的全局状态是一个迫在眉睫的扩展性问题。 这一点对我来说不太说得通。与 ref 相关的数据量非常小——就是 ref 的名字和它指向的对象的 ID。如果你把临时 ref(用于落地/组织工作)和长期 ref(用于发布分支)区分开来,那么临时 ref 可以自动清理,其数量将与进行中的变更数量成正比。长期 ref 反正也会不断累积(并且可能对预期的扩展性问题有所贡献)。 那么,在开发循环中不使用 ref 如何帮助呢? 我可以理解避免 ref 的一个下游*正确性*论点,即很容易不小心编写一个作业,该作业(如果与 ref 配合工作)在 ref 移动时意外拉入两个不同的提交,而不是检测 ref 移动并触发失败/重试。然而,仅使用提交 ID 工作也很容易犯另一种错误——你可能会继续运行一个由于推送而变得不可达的提交的作业。 #### 资源利用效率低下 文章中有若干关于资源利用的点,在我看来不太说得通。 > 除此之外,大型 monorepo 还有一些标准的变通方法,如内部 git 镜像和保存在 blob 存储中的仓库快照(种子)。我们都用过——在峰值时,我们运营了数百个内部 git 镜像来应对负载。 在 Databricks,我们用参考仓库做了类似的事情,每约 2 小时更新一次,我们的 git 镜像不到 10 个来应对 CI 负载,尽管仓库大小处于大致相同的数量级。即使有这么多镜像,CPU 负载也完全可控,而且将快照频率从 2 小时提高到比如 1 小时甚至 30 分钟——这会降低镜像上的 CPU 负载——稍微做点工作就能实现。 所以很难想象什么样的工作负载需要"数百个" git 镜像。也许是 CI 中非常宽的测试扇出? 类似地,关于稍后维护镜像还有另一个点: > 在峰值时,我们运行了数百个 git 镜像,这显著地消耗了容量,一旦仓库超出了镜像的磁盘或内存限制,就不再能扩展了 不清楚一个在主分支上有 100GB 历史的仓库如何能超出现代云实例的磁盘限制,而这些实例可以有若干……

相似文章

关于 Anthropic 的 Scion 抄袭 Mononoke 的更多细节

Hacker News Top

一篇后续博客文章指出,Anthropic 的 Scion 源代码控制系统有意抄袭了 Meta 的 Mononoke,两者的相似之处不仅限于派生数据,还涉及整个 Bonsai 风格的变更集数据模型和术语体系。

Anthropic 如何重新设计源码版本控制

Anthropic Engineering

Anthropic 分享了他们如何在五个月内打造内部版本控制系统 Scion,以取代其 monorepo 中的 git。AI 驱动的编码使每日合并量从 2,500 次增长到超过 30,000 次,期间他们还推出了代码审查系统(Antique)、代码搜索以及 IAM。

@RoundtableSpace:有人开源了 Anthropic 的 Scion。Anthropic 曾表示其 Git 替代品 Scion 将保持内部使用。如今却出现了开源版本……

X AI KOLs Timeline

一个名为 gitai 的非官方开源实现,将 Anthropic 内部的 Scion 版本控制设计带到了公众视野,在普通 Git 仓库之上提供了对智能体友好的功能,包括部分克隆、服务端历史记录以及可选的 AI 冲突解决器。该项目虽与 Anthropic 无关且仍处于 v0.1 阶段,但在 MIT 许可证下,社区可以运行并改进这一设计。

重新设计 Anthropic 的源代码版本控制

Simon Willison's Blog

Anthropic 分享了其自研源代码管理系统 Scion 的设计动机:内部代码合并量从每天约 2,500 次暴涨至 30,000 次,Git 无法满足 100GB 历史与每天 2500 万次 CI 检出的需求。新系统由 7 人团队在五个月内完成迁移,并配套了名为 Antique 的新代码评审系统。