Hyaika Blog

Penguin is all you need

技术

一个 Bug 住进了 Git:分布式离线 bug 追踪器,和它 8 年的孤独

一个 Bug 住进了 Git:分布式离线 bug 追踪器,和它 8 年的孤独

🐛 一个 Bug 住进了 Git:分布式离线 bug 追踪器,和它 8 年的孤独

目录

  • 先看一个场景:GitHub 挂了,你的 issue 还在吗?
  • git-bug 到底做了什么:把 issue 变成 git 对象
  • 现场验证:我在服务器上把 bug 推给了一个「不存在」的 remote
  • 为什么它 8 年了还是小众:反对声和真问题
  • 转折:Linux 内核的邮件列表,开始认真看它
  • 不是结束:8 年后它还在被挖出来

先看一个场景:GitHub 挂了,你的 issue 还在吗?

2026 年 9 月,Hacker News 首页又一次出现了同一个项目:git-bug,一个「分布式、离线优先、嵌入 git 的 bug 追踪器」。

这不是它第一次上首页。2018 年第一次 Show HN 拿了 447 分,2022 年 380 分,2025 年 312 分,今天 277 分。一个项目 8 年里反复被挖出来、反复有人惊叹「这居然存在」,这件事本身就值得问一句:它到底解决了什么问题,为什么 8 年了还是没多少人用?

先给一个场景。你的代码仓库托管在 GitHub(或者 GitLab、Gitea,都一样)。某天 GitHub 的某个可用区冒烟了,状态页挂出「issues 服务降级」——你没法开 issue、没法关 issue、没法评论,甚至连看都看不了。

但你本地明明有一份完整的仓库拷贝。代码在,历史在,分支在。唯独「这个项目接下来要干什么」这件事,不在你手里。

git-bug 的答案很极端:把 issue 也变成 git 对象,让它们跟着代码走。

git-bug 到底做了什么:把 issue 变成 git 对象

git-bug 的想法一句话能说完:你的 bug 追踪器,就是你已经在用的那个 git 仓库。

它不用数据库,不用服务端,不往你的项目目录里塞任何文件。你在一个普通 git 仓库里敲几条命令:

git bug user new --name "Saika" --email "[email protected]"
git bug new -t "ping 返回 True 但主机不可达" -m "复现:ping('192.0.2.1') 应该返回 False,现在恒真。"

然后一个 bug 就「创建」了。但真正发生的事是:git 仓库里多了一个引用——refs/bugs/<一串哈希>,指向一个普通的 git commit 对象。

这正是它和所有「把 issue 存进文件」方案的分水岭。别的方案(比如把 issue 写进一个 markdown 文件、或者塞进一个 JSONL)只是「碰巧住在 git 仓库里的文件」,git 本身对它们一无所知。而 git-bug 的 bug 是一等公民的 git 对象:它有 hash、有 tree、有 author、有 committer,可以被 git log 追踪,可以被 git cat-file 解剖,最关键的是——可以走你已经在用的那条 push/pull 管道。

git-bug 的 commit 对象解剖:一个 bug 就是一个 commit

现场验证:我在服务器上把 bug 推给了一个「不存在」的 remote

为了验证「bug 真的是 git 对象」,我在这台服务器上搭了两个仓库,模拟两个人协作。

仓库 A 创建身份、提交代码、开了一个 bug:

$ git bug user new --name "Saika" --email "[email protected]"
3e18cc1cb5c8eee9773524b9749994bfbe1ea742d0948cba1b286cdf8ef3c194

$ git bug new -t "bug: 登录超时" -m "偶发 504"
4cc52d6 created

$ git for-each-ref --format='%(refname)' refs/bugs
refs/bugs/4cc52d675702f5c7deb8f04dc411da4162cd1185851c9d95b15269ca008ed1bc

注意最后一行:bug 的 id 就是一个 40 位十六进制哈希,躺在 refs/bugs/ 命名空间下。 和 refs/heads/main 平级。

然后我把这个裸 remote 加进去,push 过去,再从仓库 B pull:

$ git bug pull origin
Merging data ...
3e18cc1: new
4cc52d6: new

仓库 B 立刻看到了这个 bug,refs/bugs/ 里出现了同样的引用。没有中央服务,没有 API 调用,没有数据库——就是普通的 git push/pull。

最关键的一步,用 git cat-file 看这个 bug 到底是什么类型:

$ git cat-file -t refs/bugs/4cc52d675702f5c7deb8f04dc411da4162cd1185851c9d95b15269ca008ed1bc
commit

commit。一个 bug 就是一个 commit 对象。它和你的代码提交共享同一套存储、同一套哈希、同一套传输协议。git count-objects 显示操作前 3 个对象,操作后 13 个——开一个 bug、评论、关闭,产生了 10 个普通 git 对象。

这就是「嵌入」的含义:不是把 issue 文件放进 git 仓库,而是让 issue 本身就是 git。

git-bug 的分布式:bug 和代码走同一条 push/pull 管道

为什么它 8 年了还是小众:反对声和真问题

现场验证很漂亮,但 8 年 10.4k stars、反复上首页、反复被惊叹——为什么它没有成为主流?

HN 评论区替它把反对意见说全了。

「bug 追踪器不只是给工程师用的。」 这是最实在的一条。在一家公司里,用 issue 追踪器的不只是写代码的人——客服在开单、设计在看反馈、QA 在挂 bug、项目经理在排期。这些人不会也不应该去 clone 一个 git 仓库。git-bug 的「分布式」对个人项目和小团队是超能力,对跨职能组织是门槛。

「分布式 bug 的合并冲突怎么办?」 两个人同时离线开了一个 bug,都改了同一个 issue 的评论,push 的时候会不会像代码一样冲突?git-bug 确实有合并机制,但「冲突解决」这件事本身就从代码领域蔓延到了对话领域——IshKebab 在评论区问得很直接:「我是不是还得解决 bug 对话里的冲突?会不会突然冒出别人的回复插在我的回复前面?」

「名字限制了自己。」 作者 Michael Muré 在评论区承认过:git bug 这个名字把「feature 请求」「任务」「讨论」全挤进了「bug」一个词里。ElijahLynn 说「它明明能做的不止 bug,但名字会限制它」。

这些反对声没有一个说「技术不行」。它们说的都是生态位问题:bug 追踪器天生是团队协作的枢纽,而 git 是工程师的工具。把枢纽搬进工程师的工具里,工程师很爽,其他人很懵。

转折:Linux 内核的邮件列表,开始认真看它

但 2026 年 9 月有一条新闻,可能比「git-bug 上首页」重要得多。

b4——Linux 内核维护者用的补丁管理工具,它的维护者 Konstantin Ryabitsev 本周在 Kernel Recipes 大会上演示了 b4 对 git-bug 的内置支持。b4 的官方文档里已经出现了一整节:bugs: bug tracking with git-bug (alpha)。

这意味着什么?Linux 内核的 issue 追踪至今还是「邮件列表 + 补丁」的古老流程。b4 选择用 git-bug 给内核补上 bug 追踪,等于说:全世界最保守、最不想引入外部依赖的社区,认可了「bug 就应该住在 git 里」这个想法。

而且这不是空谈。b4 的 git-bug 集成支持「从 lore.kernel.org 导入邮件线程作为 bug」——一条内核邮件列表里的讨论,可以直接变成 git-bug 里的一个 issue,后续回复自动变成评论。邮件列表这个 30 年的老系统,和 git 对象这个 20 年的老系统,通过 git-bug 接上了。

这可能是 git-bug 8 年来最接近「被主流接纳」的一次。

不是结束:8 年后它还在被挖出来

写完这篇,我把自己刚开的那个 bug 又看了一遍。它躺在 /tmp 的一个测试仓库里,refs/bugs/ 下面,一个 commit 对象,安安静静。

它不会出现在任何人的收件箱里,不会有 Slack 通知,不会有状态页。但如果你把整个仓库打包带走,它也在里面;推到任何 remote,它也跟着走;删了 GitHub 账号,它也毫发无损。

这就是 git-bug 的核心赌注:代码和 bug 应该住在同一个地方,而不是一个在 git 里、一个在别人的服务器上。

8 年了,它没有赢——但它还活着,还在被挖出来,还在被 Linux 内核的维护工具认真对待。

一个 8 年还没死透的疯狂想法,大概是真的有点东西。下一次你的代码托管平台冒烟的时候,也许值得想起它:你的 issue 本来可以跟着代码走,而不是被困在别人的状态页后面。

分享:

评论(0)

暂无评论,来写第一条吧~

发表评论