👉 这是一个或许对你有用的社群
🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料:
《项目实战(视频)》:从书中学,往事上“练”
《互联网高频面试题》:面朝简历学习,春暖花开
《架构 x 系统设计》:摧枯拉朽,掌控面试高频场景题
《精进 Java 学习指南》:系统学习,互联网主流技术栈
《必读 Java 源码专栏》:知其然,知其所以然
👉这是一个或许对你有用的开源项目
国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。
功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:
Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本
本文作者 Greg Foster 是 Graphite.dev 联合创始人兼 CTO。作者说他很好奇当年 Facebook 为什么会放弃 Git,转而使用 Mercurial 作为版本控制工具,他通过查找资料,看技术讲座以及与当时参与迁移到 Mercurial 的工程师交流找到了答案,我们一起来看看 Greg Foster 找到的答案是什么。
我参与开发的 Graphite 项目,其实很大程度上受到了 Facebook 内部工具的启发。当我和朋友们开始着手创办一家公司时,我还没听说过 Mercurial,尽管我喜欢捣鼓各种开发工具。
此前,我的工作经验包括个人项目、大学作业、在 Google 做 iOS 开发和在 Airbnb 做基础设施开发。对我来说,Git 就像水一样常见。它如此普及,以至于我认为它是唯一可行的代码管理工具。
有趣的是,在 Airbnb 我的工位和 Mercurial 专家 Gregory Szorc 中间就隔了几个人,当时我只知道他是一个很好的同事,对他的专业背景一无所知。
2021 年,我的同事 Tomas 和 Nick 改变了我的看法。他们来自 Facebook,令我惊讶的是,他们几乎不懂 Git。他们对 Mercurial 的使用模式和 Facebook 的 “stacked diffs” 工作流程非常熟悉。
随着在一起工作的时间变长,他们让我看到了非 Git 工具和模式的优势,我们最终决定将公司早期的方向转向为 GitHub 开发者引入 stacked diffs。在这个过程中,我们创建了一个将 Mercurial 的理念融入 Git 的命令行工具。
这篇文章是关于过去三年来一直困扰我的一个问题的,即,为什么 Facebook 的员工不用 Git?为什么他们选择 Mercurial 并在其上构建自定义工作流程?
我知道 Google 不用 Git,那是因为 Google 的工程设计比 Git 早了五年多。但 Facebook 和 Git 几乎同时在 2004 年诞生,到 Facebook 认真评估版本控制工具时,Git 已经比 Mercurial 更受欢迎了。那为什么 Facebook 仍然不用 Git 呢?
研究这个问题的人虽然不多,但我觉得很有趣。如果 Facebook 在 2010 年代初期倾向于使用 Git 并为其做出贡献,那么今天的工程界可能会有所不同。Git 可能会更加用户友好,并且原生支持 stacked changes。GitHub 可能会更好地支持闭源软件开发。
像 Uber 和 Pinterest 这样的由前 Facebook 员工创办的公司也可能使用 Git 和 GitHub 作为他们的版本控制工具,而不是 Phabricator 和 Mercurial,从而在过去十年中形成一个更统一的生态系统。
但 Facebook 没有坚持使用 Git 作为他们的主要代码仓库。相反,他们选择了 Mercurial 作为版本控制工具,并逐步在其上添加自定义工具。为什么会这样?首先,我通过 Google 搜索找到了一篇权威的博客文章:
https://engineering.fb.com/2014/01/07/core-infra/scaling-mercurial-at-facebook/
这篇十年前的文章以及一些后来的 YouTube 技术讲座,给了我一个初步的答案:“因为性能问题。 ”
但我想更深入地了解一下,听听当初做出决定的工程师们是怎么想的。在一位同事的帮助下,我在前 Facebook 员工群组中发布了这个问题,咨询相关问题。我还给两位最初负责迁移到 Mercurial 的工程师发了邮件,他们很友好地给我打了电话,并私下讲述了这个项目的个人经历。
这是我所了解到的关于 Facebook 为什么不使用 Git 的全部原因 —— 希望这篇文章能进一步记录我们 2024 年工具选择的原因。
注意 :我从未在 Facebook 工作过,这是我作为一个外人对这件事的最佳理解。我与一些参与该项目的人交流,并获得了他们的许可,记录下了他们向我解释的内容。
为什么 Facebook 要放弃 Git?
根据 2014 年 Facebook 的博客介绍,Facebook 起初是使用 Git 的。正如人们猜测的那样,当时它是他们源代码控制系统的默认选择。但大约在 2012 年,他们开始遇到扩展限制。
文章称他们的代码库 “比 Linux 内核大很多倍,而 Linux 内核有 1700 万行代码和 44000 个文件。” 具体来说,Git 操作开始让工程师感到缓慢 。虽然没有慢到无法忍受的地步,但已经慢到足以引起调查。
关键问题在于 “stat-ing” 所有文件的过程。“Git 检查每个文件,随着文件数量的增加自然变得越来越慢。” 工程师们尝试运行模拟,创建了一个匹配 Facebook 未来几年预期规模的虚拟仓库。
结果令人震惊 —— 基本的 Git 命令需要超过 45 分钟才能完成。正如项目中的一位初始工程师所说,“这不是你能等到所有工程师都在抱怨时才去解决的问题。到那时,问题就难以处理了。尝试降低损失就是一项艰巨的任务了,更不用说提出一个更好的解决方案了。”
于是,一群不拘一格的软件工程师开始研究解决方案。首先,他们联系了 Git 的维护人员,看看要让 Git 更好地支持大型代码仓库需要做些什么。
以下是与 Git 维护人员的邮件交流中的一些精采对话 ——12 年后,再读起这些消息,我仍然觉得有些沮丧:
听起来你把所有东西都放在一个 .git 里。把这个庞大的仓库分割成多个较小的 .git 仓库。
虽然你可以这样做,但这不是一个好主意,你应该分割仓库。
我同意。我在一个有多年开发历史的公司工作,有几个巨大的 CVS 仓库,我们正在慢慢地将代码库从 CVS 迁移到 Git。分割这些东西。这将使你能够更好地重新组织东西,我认为没有任何缺点。
虽然 Git 可以更好地处理大型仓库(特别是在交互式 rebase 中应用提交时似乎会在较大的仓库中变慢),但对 130 万个文件进行 stat-ing 你能做的也只有这么多了。
Git 的回应并不积极 —— 对一个充满大型单一代码库来说,这种方式没有多大改变。Git 的维护者们拒绝改进性能,反而建议 Facebook 分片他们的单一代码库。但是,分片对 Facebook 团队来说根本不可能实现,他们对 Git 不愿意扩展的态度感到惊讶。一般来讲,大型科技公司提供的免费开源劳动力是一个备受欢迎的礼物,可以确保项目长久存在。
话虽如此,但 Git 也没有义务屈从于 Facebook 的要求 —— 我并不打算把他们描绘成这个故事的 “反派”。因为按 Facebook 的要求去做某件事并不是合理的生存方式。有趣的是,两年后当看到 Facebook 为 Mercurial 做出有价值的改进后,Git 维护者似乎改变了态度:
他们向邮件列表发了关于 Git 性能问题的邮件。从我的观察来看,反馈相对较少。
我的印象是,他们可能也有这种感觉,即 Git 开发社区对大规模存储库的性能问题没那么上心。
所以问题是,Git 社区是否有兴趣在这种大规模场景中保持竞争力 —— 而 Mercurial 似乎在这方面已经做到开箱即用了。
十年后,Git 在更好地支持单一代码库方面取得了明显进展。
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/ruoyi-vue-pro
视频教程:https://doc.iocoder.cn/video/
考虑的替代方案
2012 年,Git 的替代方案很少。团队考虑了闭源的 Perforce,即 Google 之前的源代码控制解决方案。在与 Perforce 售前工程师的早期调查电话中,Facebook 指出了 Perforce 在读写节点之间本地一致性的架构缺陷。但他们的回应不能让人放心 —— 售前工程师们并不清楚这个问题,也没有计划来解决这个问题。
其他解决方案,如 Bitkeeper,也被考虑过,但很快都被排除。最后一个选项是 Mercurial。它的性能与 Git 相似,但架构更清晰 。Git 是一个复杂的 Bash 和 C 代码网络,而 Mercurial 是用 Python 面向对象的编码模式构建的,设计上易于扩展。
其中一位调查工程师对在之前已经有了丰富的 Mercurial 使用经验,因此团队决定参加在阿姆斯特丹举行的 Mercurial 黑客松以进一步调查。
他们发现了一个易于扩展的系统和一个对 Facebook 团队的积极改变非常欢迎的维护者社区。
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/yudao-cloud
视频教程:https://doc.iocoder.cn/video/
迁移整个工程组织
在阿姆斯特丹黑客松之后,Facebook 团队已经下了决心。剩下的任务是说服公司其他人进行迁移。这是一项令人望而生畏的任务 —— 工程师们对工具的变化极其敏感(类似于 Vim 和 Emacs 之争),更换源代码控制系统是一件大事。
团队尽可能平稳地推进,以免引起其他工程师的反对。接下来发生的事情听起来像是内部开发工具迁移的典范。团队花了几个月的时间让工程师们接受了迁移到 Mercurial 的可能性,并花时间映射 Git 和 Mercurial 之间的所有常见命令和工作流程。他们甚至收集了全公司使用 Git 命令的频率,并特别记录了如何在 Mercurial 中执行最频繁的操作。
其次,他们提供了开发人员表达担忧和讨论可能在新系统中遇到任何边缘情况的机会。起初,团队以为他们会陷入关于复杂合并情况的争论。但令他们惊讶的是,他们的同事们表现得都很友好。“没有人站起来大喊大叫说他们的情况特殊。”
最后,他们承诺进行迁移,并将公司切换到 Mercurial。剩下的事情大家都知道了。Facebook 为 Mercurial 做出了性能改进,使其成为大型单一代码库的最佳选择。Evan Priestley 扩展了 Phabricator 以支持 Mercurial。Facebook 利用 Mercurial 的 “diffs” 概念创建了 “堆叠” 的模式,解锁了新的代码审查并行化。
前 Facebook 员工离开后到新公司,带来了他们的工作流程,创造了一个小而热情的堆叠 diff 爱好者社群。最终,我遇到了其中一些爱好者,并决定将我的 20 多年奉献给将 Mercurial 风格的堆叠 diff 带到 Git 和 GitHub 上。
结束语
这个故事的教训是什么?反思这些引文和采访,我想起了一个经典的智慧:历史上许多关键技术决策都是由人而不是技术推动的。
Facebook 采用 Mercurial 并不是因为它比 Git 性能更好。他们采用它是因为维护者和代码库对合作的态度更开放。Facebook 工程师与 Mercurial 维护者进行了面对面的交流,他们喜欢这种合作方式。在说服整个工程团队之前,这一决定是经过充分沟通和深思熟虑的 —— 而不仅仅是因为某项技术严格优于另一项。
善良和开放在开发工具的世界中非常重要,我希望在我为源代码控制历史做出贡献时继续保持这种价值观。
欢迎加入我的知识星球,全面提升技术能力。
👉 加入方式,“长按”或“扫描”下方二维码噢:
星球的内容包括:项目实战、面试招聘、源码解析、学习路线。
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)