
GitHub 并不是我开源软件的第一个归宿, SourceForge 才是。
在 GitHub 出现之前,我搭建了自己的 Trac 环境。我管理着 Subversion 版本库、工单、tar 包和文档,所有这些都运行在我掌控的基础设施上。后来我把项目迁移到了 Bitbucket,那时 Bitbucket 还被认为是开源项目一个值得信赖的替代方案,尤其适合那些还没有完全拥抱 Git 的人。
最终,GitHub 成了我的选择,我把所有内容都迁移到了那里。
GitHub 对我的生活影响之大,我很难用语言来形容。我的开源身份很大程度上是在 GitHub 上形成的。我参与的项目在那里找到了用户,人们在那里找到了我,我也在那里找到了其他人。许多职业关系和友谊都始于某个代码库、问题、拉取请求或评论串,正是这些让两个人彼此认识。
这就是为什么我对GitHub如今的遭遇感到如此难过和失望。我并不认为这仅仅是微软做出我不喜欢的产品决策。GitHub长期以来都是开源社会基础设施的重要组成部分。对我们许多人来说,它不仅仅是代码存放的地方,更是社区的重要组成部分。
所以,当我思考 GitHub 的衰落时,我也会思考它之前发生了什么,以及它之后可能会发生什么。这些年来,我曾多次撰写关于依赖项的文章,尤其是关于微依赖的问题。在我看来,GitHub 催生了这种现象。我当然并非完全支持它,但它也让开源变得更加包容。GitHub 改变了人们对开源的感受,后来 npm 和其他系统又改变了人们对依赖项的感受。将它们结合起来,就形成了一个代码发布几乎无摩擦、代码消费几乎无摩擦的世界,而世界上的项目数量也呈爆炸式增长。
这有很多好处。但值得注意的是,开源并非一直如此运作。
世界更小了
在 GitHub 出现之前,开源世界要小得多。这倒不一定是指关注开源的人数少,而是指我们大多数人能够真正依赖的项目数量少。
有些项目声名显赫,由相对较少的人长期维护。你熟知他们的名字,熟悉他们的邮件列表,知道哪些人已经活跃多年,哪些人赢得了信任。这种信任并非完美无缺,旧世界也存在诸多把关人,但声誉确实至关重要。当 Debian 的开发者指出我们的许可协议含糊不清或版权声明不达标时,我们既感到自豪又感到沮丧,因为他们会打包软件。
依赖项不仅仅是一个软件包名称。它是一个拥有历史、网站、维护者、发布流程、诸多摩擦的项目,而且通常隶属于一个更大的社区。你不会随意添加依赖项,因为依赖某物通常意味着你必须了解它的来源。
并非所有这一切都是有意为之,但由于这些项目规模相对较大,它们也需要自建基础设施。小型项目可能运行在大学服务器上,许多项目也托管在 SourceForge 上,但大型项目则各自独立运行。它们联合起来组成更大的团队,以确保项目顺利进行。
我们运营着自己的基础设施
我的第一个开源项目运行在我自己搭建的基础设施上。Trac 系统、Subversion 版本库、压缩包、文档和发布文件都托管在我自己或我控制的服务器上。这很正常。如果你想发布软件,通常也得兼任一个小型系统管理员。我和Georg为我们的开源项目创建了一个集体: Pocoo 。我们分摊服务器费用,以及维护 Subversion 和 Trac、邮件列表等等的负担。
Subversion 尤其让这种“运行自己的代码仓库”变得自然而然。它是集中式的:你需要一台服务器,也需要有人来运维。项目有了自己的“家”,而这个“家”通常非常具体:一个主机名、一个目录、一个 Trac 实例、一个邮件列表存档。
Mercurial 和 Git 的出现,在理念上与此截然相反。它们都是分布式版本控制系统。每个人都可以访问完整的代码库。每个人都可以拥有自己的副本、分支和历史记录。原则上,这些分布式版本控制系统应该会减少对单一中心的需求。但尽管如此,GitHub 最终还是成为了中心。
这就是现代开源的一大讽刺之处。分布式版本控制系统胜出,但世界却最终统一采用一个庞大的集中式服务来托管它。
GitHub 带给我们什么
现在很容易只谈论 GitHub 的失败之处(目前确实有很多失败之处),但这并不公平:GitHub 过去是,现在仍然是开源的巨大礼物。
它让创建项目变得轻松,也让发现项目变得轻而易举。它让那些从未订阅过开发邮件列表的人也能理解如何贡献代码。它为项目提供了问题跟踪器、拉取请求、发布页面、维基、组织页面、API 访问、Webhook,以及后来的持续集成 (CI)。它使开源的理念成为常态,让开源的历史记录和协作过程清晰可见。在过去的十年里,它一直是优秀且合理的默认选择。
但或许GitHub最被低估的贡献在于其归档功能:GitHub成为了一个软件库。它成为了庞大软件共享资源的索引,因为即使是废弃的项目也能被找到。你可以找到分支,旧的issue和讨论也都保留在网络上。尽管人们对中心化有很多抱怨,但这种中心化也创造了可发现的记忆。GitHub 的领导者们曾经非常重视即使在受美国制裁的国家也能保持GitHub的可用性。
我知道另一种选择是什么样子,因为我亲身经历过。我早期的一些开源项目技术上仍然保留在 PyPI 上,但实际的软件包已经不见了。元数据指向我以前的服务器,而那台服务器早已停止提供这些文件。
在大型平台出现之前,这种情况很正常。个人域名过期、VPS服务器关闭、开发者去世,他们付费的服务也随之消失。互联网曾经遍布小型软件社区,而其中许多已经不复存在¹ 。
npm 与依赖爆炸
微依赖问题不仅仅在于人们发布的软件包非常小。GitHub 和 npm 的托管基础设施让人感觉创建、发布、发现、安装和依赖这些软件包都是免费的。
在 GitHub 出现之前,信誉和长期性几乎是依赖项选择过程中必不可少的考量因素,而且通常需要进行 vendor 操作。我们早期的许多依赖项默认都集成到了我们自己的 Subversion 版本库中,部分原因是当时我们甚至无法保证其他服务在需要时能够正常运行,而且在 API 出现之前,维护用于获取这些依赖项的脚本非常繁琐。这种潜在的摩擦迫使我们进行反思,并最终导致了开发者行为的改变。而对于 npm 式的生态系统来说,包图的增长速度可能远远超过任何人对其进行分析的能力。
这种思维方式带来的问题也意味着必须不断寻找解决方案。GitHub 帮助弥补了问责机制方面的问题,并在许可方面提供了帮助。一度,大量涌入的开发者和合并的 pull request 导致许可状态的现状存在诸多疑问。GitHub 甚至试图通过其服务条款来解决这个问题。
多年来,人们一直认为,如果我要依赖某个小型软件包,至少应该查看它的仓库。我想看看维护者是否存在,是否存在问题,最近是否有更新,其他项目是否使用它,以及代码是否与软件包的描述相符。GitHub 已成为提供信任的系统的一部分,最近它甚至成为少数几个能够以可信发布方式将软件包发布到 npm 和其他注册表的系统之一。
这意味着,当人们对 GitHub 的信任度下降时,问题不仅仅局限于源代码托管,还会影响围绕它形成的整个供应链文化。
GitHub正在慢慢消亡
GitHub 目前正在失去一些当初让它显得势不可挡的特质。或许这就是大型中心化平台的宿命:它们最终总会让人失望。现在,人们已经厌倦了它的不稳定性、产品频繁更迭、Copilot AI 带来的种种干扰、领导层不明朗,以及平台不再以社区为中心而运作的感觉——正是社区赋予了它价值。
显然,GitHub 也身处这场智能编码革命的浪潮之中,这给他们带来了巨大的压力。但该网站竟然没有领导层!如今一切运转良好简直是个奇迹。
一段时间以来,离开 GitHub 似乎只是一种象征性的举动,主要发生在规模较小的项目或对软件自由有着强烈信念的人身上。Zig 迁移到 Codeberg 时,我简直感到尴尬!但现在我看到一些真正有影响力的人开始谈论离开 GitHub。最明显的例子是 Mitchell Hashimoto,他宣布 Ghostty 将迁移。虽然具体迁移到哪里还不清楚,但这无疑是一个强烈的信号。此外还有其他一些项目也选择了离开 GitHub。Strudel 和Tenacity都迁移到了 Codeberg 。他们的举动会引发足够的变革吗?可能不会,但与一年前相比,我发现自己访问非 GitHub 平台的频率又增加了。
有人可能会说这是好事:开源社区不应该再假装所有东西都应该由一家公司默认管理,这对开源健康大有裨益。Git 本身的设计初衷就是为了适应一个拥有多个管理机构的世界。
分散是有代价的
回归到众多代码仓库、众多服务器、众多小型项目和众多独立社区的模式,将增强去中心化,并在许多方面迫使系统进行调整。这可以恢复自主性,使项目减少对微软领导层一时兴起的依赖。它还可以允许不同的社区选择不同的工作流程。Pi 的问题跟踪系统目前的情况,很大程度上是由于GitHub的产品选择不适用于当今的开源世界。它的设计初衷是为了提高用户参与度,而不是为了维护者的便利。
它还能让网络再次遗忘。我挺喜欢这种会遗忘的软件,因为它有清理机制。或许真正的丢失风险会让我们更认真地思考如何充分利用分布式版本控制系统。
但如果项目迁移到更类似于自托管的仓库,例如自建的 Mercurial 或 cgit 服务器,我们就有可能丢失一些我们不想丢失的东西。代码理论上可能是分布式的,但其背后的社会环境往往并非如此。问题、代码审查、设计讨论、发布说明、安全公告以及旧的 tar 包都非常脆弱,它们比我们愿意承认的更容易消失。邮件列表曾经承载着很多这类信息,但如今已无法满足需求,用户体验也极其糟糕。
我们需要一个档案库
虽然我很喜欢事物逐渐消失的想法,但我们绝对需要图书馆和档案馆。
无论 GitHub 是否会继续存在,或者项目是否会找到新的归宿,我真正希望看到的是一个公开的、略显枯燥但资金充足的开源软件存档库。它需要有捐赠基金或公共资金的支持才能维持运营。它的使命不是赢得开发者生产力市场,而是确保我们创造的最重要的东西不会消失。
花里胡哨的东西可能是别人的问题,但源代码存档、发布工件、元数据以及足够的项目背景信息(以便了解发生了什么)应该保存在与单个公司的商业模式或领导情绪无关的地方。
GitHub 之所以意外地成为代码归档库,是因为它成为了开源活动的中心。一旦这种中心地位不再稳固,我们就不应该指望会出现某种神奇的归档功能,或者 GitHub 会继续扮演这样的角色。我们已经目睹了当项目托管地仅仅是个人服务器和美好的愿望时会发生什么,也看到了 Google Code 和 Bitbucket 的遭遇。
我真心希望GitHub能够复苏,部分原因是它承载着许多历史,也因为那些仍在维护它的人们继承了一些真正重要的东西。但我认为,让开源精神的延续依赖于GitHub的健康发展是不负责任的。
GitHub 出现之前的世界拥有更大的自主权,但也伴随着更多的损失。在某些方面,我们或许会回到那种状态,至少在一段时间内是这样。人们接下来想要构建的东西应该力求保留原有的记忆,同时摆脱对其他平台的依赖。项目迁移应该会更容易,更容易反映其社会背景,更容易保存版本,而且一家公司的转型也更难演变成一场波及其他公司的文化危机。
我不想回到过去那种到处都是损坏的tar包链接和废弃的Trac实例的时代。我也不希望开源社区假装过去二十年的一切都是正常或永恒的。GitHub书写了开源史上辉煌的一章,如果这一章即将结束,那么下一篇章应该从中汲取经验,也要从前人的经历中学习。
-
这也提醒我们,我们当时的许多项目都非常依赖互联网档案馆。↩