三分之一的 GitHub 高星项目,已经两年没人动了
我们持续追踪 6.7 万个 star 数超过一千的 GitHub 仓库,每天记录它们的状态。按"距离最后一次 push 有多久"排一下,会得到一个不太舒服的数字。
| 最后一次 push | 仓库数 | 占比 | star 中位数 | 每千 star 的未关 issue |
|---|---|---|---|---|
| 3 个月内 | 27,191 | 42.9% | 2,429 | 11.5 |
| 3–12 个月 | 9,224 | 14.5% | 1,983 | 9.1 |
| 1–2 年 | 6,575 | 10.4% | 1,974 | 10.1 |
| 超过 2 年 | 20,439 | 32.2% | 1,772 | 9.0 |
大约三分之一的仓库超过两年没有收到任何一次 push。而三个月内有更新的,不到一半。
这个数字会立刻引来两个质疑。两个都很合理。但都没能在数据面前完整站住。
质疑一:"那些不都是 awesome-list 吗"
直觉是:清单、书单、面试题库这类仓库能囤积大量 star 却永远不需要提交代码。它们撑大了停更那一栏,但和软件无关。
这个效应真实存在。没有检测到编程语言的仓库在活跃组占 5.0%,在两年停更组占 10.8%——正好是两倍。再算上文档型语言(Markdown、HTML、TeX、Jupyter),规律一致:3.4% 对 6.0%。
但两者加起来,只能解释停更组的约六分之一。剩下六分之五是带着真实编程语言的仓库——是真软件,顶着几千个 star,两年无人触碰。
其中体量最大的这些:
- jlevy/the-art-of-command-line161.8k ★126 issue沉寂 2.1 年
- justjavac/free-programming-books-zh_CN117.7k ★0 issue沉寂 2.0 年
- nvbn/thefuck97.6k ★305 issue沉寂 2.0 年
- fighting41love/funNLP81.9k ★44 issue沉寂 2.2 年
- CompVis/stable-diffusion73.2k ★540 issue沉寂 2.1 年
- prakhar1989/awesome-courses69.9k ★45 issue沉寂 3.2 年
- resume/resume.github.com62.9k ★64 issue沉寂 3.4 年
- xingshaocheng/architect-awesome60.8k ★48 issue沉寂 2.3 年
- atom/atom60.8k ★963 issue沉寂 3.5 年
- angular/angular.js58.6k ★389 issue沉寂 2.3 年
有些确实是参考资料。但也有不少是人们今天仍在安装使用的软件。
质疑二:"停更不等于废弃,好软件是会写完的"
这个质疑更有力。一个把问题解决干净的小而专的库,本来就不需要再提交。频繁改动不代表健康,安静的仓库可能只是做完了。
但如果这就是全部真相,issue 列表里应该留下痕迹:有真实用户的废弃项目会攒下没人处理的 issue;而真正完工的项目根本不会招来多少 issue。所以按受众规模归一化之后,两组的积压程度应该差别明显。
结果并没有。看上面表格的最后一列:每千 star 的未关闭 issue 数,在四个分桶里都落在 9 到 11.5 之间。活跃维护的项目,归一化后的积压甚至比两年停更的略高。
这个结果出乎我们的预料——这一列本来就是为了区分两组而加的,而它拒绝把两组分开。
这条持平的线可能意味着什么
最合理的解读是:放弃是双向的。项目很少在用户还在猛敲 issue 的情况下沉默下去。注意力是从两端同时撤离的——维护者停止推送,而那些本来会提 issue 的人,早就换用别的东西了。
这个故事没有"成千上万个被冷落的项目和一群愤怒用户"那么戏剧化。但对于用 star 数挑依赖的人来说,它其实是更坏的消息:一个仓库可以同时做到 star 很高、明显停更,而且从外部看不出坏掉——因为本该抱怨的人,已经不声不响地离开了。
这个推论要克制。我们能看到的只是未关闭 issue 数的一个当前快照,而 GitHub 的这个数字把 PR 也算了进去。我们无法看到 issue 是否曾被批量关闭、维护者是否关掉了 issue 功能、以及积压量随时间如何变化。持平的线与双向放弃这个解释一致,但不能证明它。
落到实处
star 数记录的是"曾经有多少人觉得这个项目值得收藏"。它不说明今天是否还有人维护——而按 issue 的数据看,也不太说明今天是否还有人使用。
在因为 star 数高而引入一个依赖之前,先看最后一次 push 的时间。这只需要点一下,而它和 star 数的判断大约有三分之一的时候是矛盾的。
这份数据不能说明什么
- 样本是已经跨过 1000 star 的仓库,不是 GitHub 全量。这里的任何结论都不描述"典型仓库"。
pushedAt统计的是对任意分支的 push,包含自动化提交。它是存活信号,不是有效工作量的度量。- 未关闭 issue 数包含 PR,而且我们持有的是单个当前快照,不是历史曲线。
- 语言归类依据 GitHub 自己的检测,它按文件字节判定,可能给出意外的标签。
- 另有 4,123 个仓库没有可用的 push 时间记录,不在上面任何分桶内。
表格随每日抓取自动更新。你也可以在排行榜里自己排序这份语料。
文中所有数据均实时读取自本站数据库,随每日抓取自动更新。