在版本控制系统中,Monorepo(“mono”意为“单一”,“repo”是“存储库”的缩写)是一种软体开发策略,其中多个专案的程式码存储在同一个存储库里面。[1] 这种做法至少可以回溯到 2000 年代初期,当时这种做法通常被称为共享程式码库。[2] Google,[3] Meta,[4] Microsoft,[5] Uber,[6] Airbnb, 以及Twitter[7] 所有这些公司都采用非常大的单一储存库(Monorepo),采用不同的策略来扩充具有大量程式码和日常改版的建置系统和版本控制软体。

一个相关的概念是庞大应用程式,但是庞大应用程式将其子专案组合成一个大专案,而单一存储库(Monorepo)可能包含多个独立专案。[8][9][10]

优点

与个体存储库相比,单一存储库有许多潜在优势:[3][11]

方便重复利用程式码
类似的功能或沟通协定可以抽像到共享工具库中并直接包含在专案中,而不需要依靠套件管理器。
简化相依性套件管理
在多个专案依赖于第三方相依性套件的多存储库环境中,该相依性套件可能会被多次下载或构建。在 monorepo 中,可以轻松优化构建,因为所引用的相依性套件都储存于同一程式码库中。
原子化提交(Atomic commit)
当一起运作的专案包含在单独的存储库中时,发布需要同步一个专案的哪些版本与另一个专案一起运作。在相当庞大的专案中,管理相依套性件之间的相容版本可能会变成相依套件地狱(Dependencies hell)。在 monorepo 中,这个问题可以被解决,因为开发者可以原子化的方式修改多个专案。[12]
大规模程式码重构
由于开发者可以存取整个专案,重构可以确保专案的每一个地方在重构之后可以继续运作。
跨团队协作
在使用原始相依性套件(从原始程式码编译的相依性套件)的 monorepo 中,团队可以改善其他团队正在进行的专案。这样能让程式码所有人更富有弹性。

限制与缺点

损失版本资讯
虽然不是必要的,但一些 monorepo 构建在存储库中的所有专案中使用同一个版本号。 将会导致损失每个专案的语义版本控制。[13]
缺乏每个专案的存取控制
使用分离式存储库,可以根据需要授予对存储库的存取权限。 monorepo 可以对项目中的所有软体进行读取,可能会带来新的安全问题。[14] 要注意的是在某些版本控制系统中,此限制不是问题。 例如,当使用 Subversion 时,可以下载存储库的任何部分(甚至是单个目录),并且可以使用基于路径的授权来限制对存储库某些部分的存取。
预设需要更多存储空间
使用分离式存储库,在预设的情况下只能接收感兴趣的专案。使用 monorepo,在预设情况下您可以取出(check out)所有专案。 这样将会占用大量存储空间。 虽然所有版本都有执行部份取出(partial checkout)的机制[15][16] 但这样的做法会破坏 monorepo 的一些优点。

可扩充性的挑战

拥有大型专案的公司都会遇到了 monorepos 的障碍,特别是与构建工具和版本控制系统有关。 Google的monorepo被认为是世界上最庞大,符合超大规模系统的分类[3] ,每天必须在超过 80 TB 的存储库中处理数万个贡献提交。[17]

扩充版本控制软体

使用或改用现有版本控制软体的公司发现,该软体无法有效处理大型 monorepo 所需的资料量。 Facebook 和微软分别选择贡献或对现有的版本控制软件 Mercurial 和 Git建立分叉版本,而谷歌最终建立了自己的版本控制系统。十多年来,Google 一直依靠托管在单一机器上的 Perforce。 2005 年,Google 的构建伺服器可能一次被锁定长达 10 分钟。谷歌在 2010 年将其改进为 30 秒 - 1 分钟。[18] 因为扩充问题,Google 最终开发自己的内部分散式版本控制系统,称为 Piper。[3]

Facebook 遇到了版本控制系统 Mercurial 的性能问题,并为客户端做出了上游贡献,[19] 并在 2014 年 1 月使该系统比起 Git 中的竞争解决方案更快。[20]

2017 年 5 月,Microsoft 宣布几乎所有 Windows 工程师都使用 Git monorepo。[5] 在过渡期内,Microsoft 对 Git 客户端做出了大量的上游贡献,移除不必要的档案存取并改善使用 Git 虚拟档案系统处理大型档案的能力。[21]

扩充构建软体

很少有构建工具在 monorepo 中有良好表现-[7],并且在存入时执行整个存储库的构建和持续整合测试的流程会导致的性能问题。[13][14] 有定向式图型构建 Buck、Bazel、Pants 和 Please 等系统,通过将构建和测试划分到活跃的开发区域来解决这个问题。[22]

Twitter 于 2011 年开始开发 Pants,因为在当时 Facebook 的 Buck 和谷歌的 Bazel 都是不是开始原始程式码的工具。[23] Twitter 以 Apache 2.0 授权的方式于 2012 年开放 Pants 的原始程式码。[24]

Please 是一款基于 Go 语言的构建系统,由 Thought Machine 在 2016 年开发,Thought Machine 也是受到 Google 的 Bazel 的启发,同时也是因为对 Facebook 的 Buck 不满。[25]

参考文献

  1. ^ Infrastructure as Code | Second edition. Thoughtworks. 2021-02-25 [2022-12-01]. (原始内容存档于2023-06-02) (美国英语). 
  2. ^ Mark "Nurgle." Collins. Linux Game Programming. Prima Tech. 2001 [2023-04-11]. ISBN 978-0-7615-3255-2. OCLC 1044194694. (原始内容存档于2023-05-01) (美国英语). 
  3. ^ 3.0 3.1 3.2 3.3 Levenberg, Rachel Potvin, Josh. Why Google Stores Billions of Lines of Code in a Single Repository. Communications of the ACM. July 2016 [20 July 2018]. (原始内容存档于2020-05-28). 
  4. ^ 引用错误:没有为名为scaling_mercurial的参考文献提供内容
  5. ^ 5.0 5.1 Lardinois, Frederic. Microsoft now uses Git and GVFS to develop Windows. TechCrunch. 24 March 2017 [20 July 2018]. (原始内容存档于2023-04-15) (美国英语). 
  6. ^ Aimee Lucido. Uber Technology Day: Monorepo to Multirepo and Back Again. 7 April 2017 [24 July 2018]. (原始内容存档于2023-05-06). 
  7. ^ 7.0 7.1 Dorothy Ordogh. Pants and Monorepos. 5 April 2018 [24 July 2018]. (原始内容存档于2023-05-03). 
  8. ^ Reece, Brock. From Monolith to Monorepo. From Monolith to Monorepo. Since starting at Croud. November 7, 2017 [March 19, 2019] (美国英语). 
  9. ^ Savkin, Victor. Misconceptions about Monorepos: Monorepo != Monolith. blog.nrwl.io. August 14, 2019 [June 16, 2020] (美国英语). 
  10. ^ Oberlehner, Markus. Monorepos in the Wild. Jun 12, 2017 [July 25, 2018]. (原始内容存档于2020-05-11) (美国英语). 
  11. ^ Brousse, Nicolas. The issue of monorepo and polyrepo in large enterprises. Proceedings of the Conference Companion of the 3rd International Conference on Art, Science, and Engineering of Programming. ACM Digital Library. 2019: 1–4 [7 September 2019]. ISBN 9781450362573. S2CID 201670751. doi:10.1145/3328433.3328435. 
  12. ^ Santacroce, Ferdinando; Olsson, Aske; Voss, Rasmus; Narebski, Jakub. Git: Mastering Version Control. Packt Publishing Ltd. 2016: 756 [2023-04-11]. ISBN 9781787122796. (原始内容存档于2023-05-26) (英语). 
  13. ^ 13.0 13.1 Farina, Matt. Dangers of Monorepo Projects - DZone DevOps. DZone. [20 July 2018]. (原始内容存档于2023-05-07) (英语). 
  14. ^ 14.0 14.1 点融黑帮. 浅谈monorepo [Talking about monorepo]. Sohu. 16 August 2017 [20 July 2018]. (原始内容存档于2023-04-16) (Chinese). 
  15. ^ Svn Book: Sparse Directories. [2023-04-11]. (原始内容存档于2023-04-16). 
  16. ^ Perforce: Clone. [2023-04-11]. (原始内容存档于2023-04-19). 
  17. ^ Metz, Cade. Google Is 2 Billion Lines of Code—And It's All in One Place. WIRED. 16 September 2015 [20 July 2018]. (原始内容存档于2016-10-23). 
  18. ^ Bloch, Dan. Still All on One Server: Perforce at Scale (PDF). [23 July 2018]. (原始内容存档 (PDF)于2021-05-13). 
  19. ^ Claburn, Thomas. Facebook is writing a Mercurial server in Rust. This is not a drill. The Register. [20 July 2018]. (原始内容存档于2019-05-03) (英语). 
  20. ^ Blewitt, Alex. Facebook makes Mercurial faster than Git. InfoQ. 9 Jan 2014 [24 July 2018]. (原始内容存档于2023-04-16). 
  21. ^ Bright, Peter. Windows switch to Git almost complete: 8,500 commits and 1,760 builds each day. Ars Technica. 24 May 2017 [20 July 2018]. (原始内容存档于2017-05-24) (美国英语). 
  22. ^ Hammant, Paul; Smith, Steve. Trunk Based Development. trunkbaseddevelopment. [24 July 2018]. (原始内容存档于2020-04-14). 
  23. ^ Mohilo, Dominik. 8 Build-Tools im Vergleich: Ant – Buildr – Maven – Bazel – Buck – Gradle – Pants – sbt - JAXenter [8 build tools compared: Ant - Buildr - Maven - Bazel - Buck - Gradle - Pants - sbt]. JAXenter. 10 June 2016 [20 July 2018]. (原始内容存档于2020-08-11) (de-DE). 
  24. ^ Moore, Madison. GitLab releases security fixes, Pants 1.0, and Sauce Labs integration for JIRA—SD Times news digest: May 3, 2016 - SD Times. SD Times. 3 May 2016 [20 July 2018]. (原始内容存档于2020-05-11). 
  25. ^ Ebden, Peter. Please - the Thought Machine Build System. Blog. Thought Machine. December 2017. (原始内容存档于2019-12-28).