跳到正文
Hacker News· signa11·· 6 天前AI 评分22

GitHub 存在哪些问题:GNU 项目呼吁开发者避免在 GitHub 托管代码库

What's Wrong with GitHub

AI 导读

GNU 项目呼吁开发者避免在 GitHub 托管代码库,并列举其四大问题:推广含糊的许可证实践、要求访客运行非自由 JavaScript、部分服务实为 SaaSS 劣质服务、试图破坏 Git 的分布式架构。

正文 · AI 翻译

软件开发者们,GNU 工程敦促你们避免将代码仓库托管在 GitHub 上。这是为了避免成为有害做法的受害者,也避免让其他人同样受害。本文聚焦于 GitHub 最严重的几个问题,以及它们可能造成的错误与伤害: (1) GitHub 助长含糊且令人困惑的许可实践; (2) 它要求访问者为大多数操作运行非自由的 JavaScript; (3) 它提供的某些“服务”实际上是 SaaSS(以服务替代软件)劣质服务; (4) 它试图颠覆 Git 的分布式架构。

虽然 Git 是自由软件,但 GitHub 根本不是软件。它是一个网站,提供从简单的仓库托管服务到各种 SaaSS 劣质服务的一系列功能。GitHub 提供的功能种类繁多,使得对该网站进行公正的批评变得困难,因为每一项功能都需要从道德层面进行评估——既要评估它所做的工作,也要评估该工作的实现方式。

本文聚焦于 GitHub 最严重的几个问题,首先从 GitHub 多年来至少有所改进的一个领域谈起,接着提到该网站对于拒绝 JavaScript 陷阱 的用户几乎毫无用处,以及 SaaSS “AI” [1] 劣质服务,最后以 GitHub 作为分布式系统中中心枢纽的模式作结。

GitHub 似乎在尽可能像一座围墙花园那样运作,同时又不彻底破坏与 Git 的兼容性。因为 Git 是自由软件,GitHub 无法强行将 Git 拴 在自己身上,但它可以引诱用户采用那些仍将用户与 GitHub 绑定的工作流程。

有时最糟糕的镣铐不是铁制的,而是丝制的。GitHub 以集中化提供便利,这使得微小的摩擦变得阴险:一键合并只能从拉取请求进行,而拉取请求只能从托管在 GitHub 上的“复刻”发起;在网页界面中,指向 GitHub 账户的链接取代了电子邮件地址;持续集成默认在 GitHub 服务器上运行。渐渐地,Git 横跨互联网的广阔平原变成了 GitHub 的围墙花园。

将软件包托管在 GitHub 上所引发问题的完整解决方案,是把软件包托管在一个 没有这些问题 的站点上。但如果你无法立刻做到这一点,至少要在 README 中公布一个电子邮件地址,以便不使用 GitHub 的人能就你的程序与你沟通;将关于使用你的程序的网页托管在一个无需非自由软件即可阅读这些页面的网站上,并始终引用那里的网页。

助长含糊不清的许可实践

当 GitHub 在 2008 年初首次提供仓库托管时,它对正确为自由软件授予许可一事完全保持沉默,而这种沉默导致了大量未声明任何许可证的公共仓库涌现。2013 年,GitHub 建立了一个“选择许可证”网站,帮助用户为新软件选择自由许可证。

截至 2026 年撰写本文时,该网站就 GPL 的应用给出了不明智的建议,声称仅将许可证文本复制到仓库中的一个文件里就足够了。

FSF 的律师建议我们,我们也因此建议开发者,在每个实质性文件中加入许可证声明,以确保用户了解他们在 GPL 下的权利和义务。GitHub 仅将此列为“可选步骤”。

如果没有标准的 GPL 声明,就无法说明该程序是仅按 GPL 第 N 版授权,还是按 GPL 第 N 版或更高版本授权。GitHub 仅在关于 SPDX 许可证标识符的附带说明中提及这一点。

大量使用非自由 JavaScript

GitHub 的网站向浏览器发送大量 JavaScript 代码,其中许多代码是非自由的。由于该网站未能优雅降级,拒绝 JavaScript 陷阱的用户发现,除了单纯查看仓库之外,任何交互都无法进行,甚至许多文件查看链接也不再有效。

对此有一些变通方法。标准的自由 Git 命令行工具可以从 GitHub 克隆仓库,并且有一个公共 REST API 和免费命令行工具,至少可以处理与网站的部分交互。

然而,GitHub 为该 REST API 提供的命令行工具,虽然在技术上是在 Expat 许可证条款下的自由软件,但仍然无法推荐,因为 GitHub 决定以“遥测”的形式向其添加间谍软件功能。这极其荒谬,因为该工具的主要目的是使用基于网络的 API;GitHub 可以从他们自己的服务器日志中获取使用信息,而不是从用户的计算机上获取。

GitHub Copilot 是 SaaSS

GitHub 因推出“GitHub Copilot”而引发争议,随着该工具能力的增强,争议只增不减。GitHub Copilot 最初是一个“AI”[1] 代码补全工具,早期演示了仅根据函数头注释生成函数体的能力,如今已发展成为一个据称能够充当开发团队成员的“AI”“代理”。

Copilot 一直备受争议。最初的代码补全工具使用的模型是在各种许可证下的各种代码上训练的,很快就被发现能够逐字复制知名文本的长段落,包括 GNU 通用公共许可证的序言和 Python 之禅。这种 regurgitate 其训练材料的能力引发了人们对 Copilot 建议代码法律地位的怀疑。GitHub 为更高层级的 Copilot 订阅者提供赔偿,尽管如果要求的是 GPL 合规而非金钱,赔偿将如何运作仍不清楚。

Copilot 能力的后续扩展带来了更多争议。GitHub 添加了一个“功能”,允许用户让 Copilot 撰写错误报告,然后将其作为 issue 提交,而几乎没有表明使用了 Copilot 生成。当用户未能校对他们的 issue 并纠正 Copilot 的错误时,这些 Copilot 协助的 issue 让 GitHub 上的项目维护者淹没在垃圾内容中。当然,GitHub 拒绝允许维护者阻止 Copilot 生成的 issue 被提交。

使用 LLM 代码建议的法律风险,以及用垃圾信息淹没维护者所带来的社会危害,是普遍存在的,甚至适用于本地运行的免费模型,但 GitHub 的做法在另一方面也很糟糕:Copilot 是 SaaSS,其模型运行在用户无法控制的远程服务器上。这导致了一些常见的 SaaSS 滥用行为:强制“升级”被用户认为不如之前的版本,以及供应商随意涨价。

Copilot 订阅最初提供对基本功能(主要是代码建议)以及每月一定数量的“高级请求”(其他交互和更复杂的代理任务)的访问权限。2026 年初,GitHub 宣布了一项政策变更:所有订阅都将被迫转向基于令牌的计费模式,该模式根据实际使用的计算资源收费,而用户对此仅有松散的控制权。GitHub 能够将这一变更强加给用户,正是因为 Copilot 是 SaaSS。

集中化 Git

上述做法直接危害软件自由,但 GitHub 还以更深层、更长期且不那么显而易见的方式破坏社区。

Git 被设计为一个分布式版本控制系统,其架构中没有任何中心故障点。这一决定部分是为了让 Git 尽可能与 CVS 不同,部分反映了围绕 Linux 内核的集市式开发过程,也可能部分是从 BitKeeper 惨败 [2] 中吸取的教训。GitHub 试图重新引入 Torvalds 在设计 Git 时明确拒绝的集中化元素,然后鼓励用户围绕这种集中化构建工作流程。

GitHub“成就”

GitHub 有一套个人资料徽章系统,可以通过网站上的各种活动获得,类似于较新电子游戏中的成就。事实上,文档中它们就被称为“成就”。这个系统是游戏化的另一个例子,软件(或“服务”)试图借此让用户上瘾。

当然,GitHub 的大多数“成就”只认可与该网站相关的活动,这是一种促使用户更加依赖 GitHub 的推动。

用户/组织混合模型

GitHub 最初以提供 Git 仓库托管这一简单前提起步。与此一致,GitHub 将仓库组织在用户账户下,并允许所有用户创建仓库。这是一种简单的公告板模型,用户可以自由发布自己版本的自由软件包,并通过请求包维护者从自己的副本中拉取来向上游提交更改。这就是 Git 被设计的工作方式,而这种早期形式的 GitHub 使那些缺乏技能或资源来搭建自己的 Git 服务器的用户也能使用这种工作流程。

公告板模型的问题在于,它可能使定位软件包的规范版本变得不必要地困难,这与围绕具有指定维护者的项目组织的传统协作平台形成对比。在协作平台上指定维护者可以像“谁先注册就是谁”那样无政府主义,也可以像 GNU 项目那样精心管理,或者介于两者之间。

这对 Linux 来说不是问题,因为 Linus 的仓库在该项目中被广泛认为是核心的规范参考。请记住,Git 最初是专门为支持 Linux 内核开发而设计的。它在其他地方的实用性只是额外收获。

Git 的分布式模型本身也存在一个问题,而 GitHub 使其更加严重:公告板模式导致 fork 泛滥,因为即使是最简单的补丁也必须先克隆仓库来准备,从而创建了软件包的一个 fork。这些 fork 往往无人维护,甚至在完成其最初目的后就被废弃。

这种混乱的可能性导致人们倾向于在 GitHub 上创建“组织”账户,这种做法现在得到了明确支持。然而,由于历史原因,组织和用户在 GitHub 上共享同一命名空间,这留下了相当大的混淆空间,而……使其更加严重。

GitHub 的集中式 Fork/拉取请求工作流

虽然 Git 最初设计是为了支持这种分布式开发模式,但 GitHub 阴险地插入了自己。Git 允许拉取的镜像位于互联网上的任何位置,但 GitHub 只支持从……GitHub 拉取。虽然确实可以使用 Git 从其他地方拉取、在本地合并,然后推送到 GitHub,但 GitHub 精心打造了一条完全依赖 GitHub 的最小阻力路径。

GitHub 没有技术上的理由不允许拉取请求引用远程 Git 服务器,甚至可以通过电子邮件接受引用远程服务器的拉取请求,这是处理它们的传统“Git 方式”。GitHub 选择将 GitHub 拉取请求专门绑定到自身。

GitHub 通过其“fork”概念进一步加剧了这些问题,这与 Git 克隆仓库的基本功能不同。GitHub 将仓库的 fork 数量显示为一种人气竞赛徽章,并且其实现 fork 的方式使 GitHub 上的仓库可信度存疑,因为仅出现在 fork 中的材料仍然可以使用父仓库的 URL 检索到,使恶意方能够迷惑用户。

GitHub Actions

GitHub 提供了一个名为 GitHub Actions 的模块化自动化工作流系统,这是另一种让你的软件包依赖 GitHub 的方式。GitHub Actions 可用于响应提交或拉取请求运行任意脚本。这些脚本默认在 GitHub 的虚拟服务器上运行,不过仓库所有者可以指定在自己的服务器上运行脚本。

虽然仓库所有者可以为自己的 action 自托管运行器,但标准运行器尽管是自由软件,却包含一个以自动更新功能形式存在的通用后门,并依赖 GitHub 控制的 SaaSS 基础设施来告诉它运行什么。

GitHub 的 action 调度基础设施试图通过拒绝向其认为运行过时软件的运行器调度 action 来强制执行这个通用后门。

虽然协调运行 action 的调度基础设施是 SaaSS,但 action 本身不是 SaaSS,因为用户控制运行哪些 action。尽管有些 action 是非自由的,仓库所有者可以直接拒绝将非自由 action 附加到他们的仓库。

GitHub Actions 可用于构建非常复杂的自动化工作流,将用户更深地诱入 GitHub 的网中,但有一个自由工具可以帮助用户摆脱这个陷阱。发布在 nektosact.com 的 act 程序是自由软件,可以按需在本地使用 GitHub Actions 运行工作流,而不依赖 GitHub 的基础设施。

GitHub 的通信真空

GitHub 试图吸引并集中尽可能多的围绕某个包的社区。虽然任何软件协作平台都可以预期会提供 bug、issue、补丁等的跟踪器,并要求在网站上拥有账户才能参与这些基于网络的讨论,但此前的平台如 SourceForge 和 GNU Savannah 还提供邮件列表,以便通过电子邮件进行协作,与平台本身的交互最少。

Git 被设计用来支持维护 Linux 内核这一跨越互联网的开发项目。因此,Git 需要一个同样跨越互联网的用户身份概念,Git 的开发者找到了一个简单的解决方案:电子邮件地址,包括一个可选的名字。

出于另一个原因,这也是一个显而易见的选择:Linux 内核的开发主要通过邮件列表进行协调。该项目有自己的邮件列表基础设施,而 Git 最初也被设计用来方便处理通过电子邮件交换的补丁。

GitHub 显然不同意这些设计决策,因为它不仅不提供邮件列表,而且在其主要的 Web UI 中绝对拒绝显示电子邮件地址。如果某个提交有一个与 GitHub 账户关联的电子邮件地址,则会显示指向该账户的链接,否则只显示一个名字,完全没有链接。

自由软件运动的一项道德原则是,用户成为开发者自身的障碍应该最小化,并且只是技术性的(这些障碍之所以可接受,仅仅是因为诸如要求编程知识这样的障碍从根本上无法消除)。像 GitHub 那样隐藏电子邮件地址,其效果是将用户与现有开发者隔离开来。要求在 GitHub 上创建账户才能参与讨论,对于尚未将自己视为开发者的用户来说,也是一个微妙的社会障碍。

脚注

  1. “AI”一词被加上引号,因为它已成为使用 LLM 的“人工智能”的营销术语,虽然这些系统确实是人造的,但它们远非智能。
  2. BitKeeper 是一种非自由版本控制系统,从 2002 年到 2005 年用于开发内核 Linux,该内核用于 GNU/Linux 操作系统。

来源:Hacker News · gnu.org