Flirt: GitHub and Mailing List backends
Flirt: GitHub and Mailing List backends
Flirt: GitHub and Mailing List backends 2026-08-15 Flirt:GitHub 和邮件列表后端 2026-08-15
This is an update on the development of Flirt. Previous posts: Announcing Development on Flirt, Flirt: The Native Backend. 这是关于 Flirt 开发进度的更新。之前的文章:宣布开发 Flirt、Flirt:原生后端。
It’s been a while since the last post. I was focused on my thesis, which I handed in on August 1st 🥳 I managed to get comment threads basically working and implemented backends for GitHub and mailing lists. These features are limited and buggy in several ways. But I think this can be overcome with some effort. 距离上一篇文章已经过去一段时间了。我一直在专注于我的论文,并已于 8 月 1 日提交 🥳。我成功实现了评论线程的基本功能,并完成了 GitHub 和邮件列表的后端开发。这些功能目前还很有限且存在不少 Bug,但我认为通过努力是可以克服的。
Next, I’m now going to clean things up a bit and prepare to make Flirt open-source. It won’t be ready for users, but for people who can relate to my ideas for code review and want to shape the development of Flirt from early on. I’m aiming to get that done within 1-2 months. Continue reading for some technical details about the GitHub and mailing list backends! 接下来,我将整理代码并准备将 Flirt 开源。它目前还不适合普通用户使用,但适合那些认同我的代码审查理念、并希望从早期阶段参与 Flirt 开发的人。我的目标是在 1-2 个月内完成这项工作。请继续阅读,了解关于 GitHub 和邮件列表后端的一些技术细节!
Local storage
本地存储
The native backend stored everything locally by necessity, that’s how Git works. You fetch Spirits from the remote, do stuff with them, and push them again. For now, I ended up using the same custom ref mechanism for the other backends as well. It would be annoying if every time you want to do something, Flirt would hit the GitHub API or download an email thread. The custom refs stay local for those backends and are converted to API calls or emails when the user requests to sync with the backend. 原生后端出于必要将所有内容存储在本地,这就是 Git 的工作方式。你从远程获取 Spirits,对它们进行操作,然后再推送回去。目前,我决定在其他后端也使用相同的自定义引用(custom ref)机制。如果每次你想做点什么,Flirt 都要去请求 GitHub API 或下载邮件线程,那会非常烦人。对于这些后端,自定义引用保留在本地,只有当用户请求与后端同步时,它们才会被转换为 API 调用或邮件。
Past submissions of GitHub PRs
GitHub PR 的历史提交
The biggest issue with GitHub is that you don’t get information about past force-pushes to a PR. That means, Flirt can’t show you the interdiff between all PR submissions in principle. In practice, it’s not so bad. You probably only care about submissions you previously observed. The standard use case is: interdiff between last-reviewed and current submission. That works mostly fine, because the last-reviewed submission can be remembered locally. GitHub 最大的问题在于,你无法获取 PR 历史强制推送(force-push)的信息。这意味着原则上 Flirt 无法向你展示所有 PR 提交之间的差异(interdiff)。但在实践中,情况并没有那么糟。你通常只关心你之前观察过的提交。标准的用例是:对比上次审查的提交与当前提交之间的差异。这通常运行良好,因为上次审查的提交可以在本地记录。
Some caveats: Switching between workstations can break that. If workstation has never observed your last-reviewed submission, it can’t easily get it from the GitHub API. The API tells you which exact commit hash any review comment was made on. That could be used to reconstruct past submissions. But then you’d get a weird edge case where, if there’s a comment on a “middle” commit, but no comment on the commit at the tip of the PR branch, the submission would only be partially reconstructed. Implementing that would be difficult without introducing more weirdness. 一些注意事项:在不同工作站之间切换可能会破坏这一点。如果工作站从未观察过你上次审查的提交,它就无法轻易从 GitHub API 获取该信息。API 会告诉你每条审查评论是在哪个具体的提交哈希(commit hash)上做出的。这可以用来重构过去的提交。但这样会产生一个奇怪的边缘情况:如果评论是在“中间”提交上,而 PR 分支末端的提交没有评论,那么提交记录就只能被部分重构。在不引入更多复杂性的情况下实现这一点非常困难。
Comments on the left side of the diff
Diff 左侧的评论
GitHub’s review UI shows you the diff of a PR or commit to comment on. Flirt on the other hand adds comments on a specific state of the code base and assumes you look at the diff via regular VCS tooling. The problem with that is, Flirt can’t add comments to the left side of the diff. That raises the question: Where to put them? Adding them to the right side of the diff in a “similar” location is no good, because the context might be completely different. GitHub 的审查界面会展示 PR 或提交的差异供你评论。而 Flirt 则是在代码库的特定状态下添加评论,并假设你通过常规的 VCS 工具查看差异。问题在于,Flirt 无法在差异的左侧(即删除行)添加评论。这就引出了一个问题:把它们放在哪里?将它们放在差异右侧的“相似”位置并不好,因为上下文可能完全不同。
The best short-to-medium term solution I can come up with is adding the context of the deleted lines as a “header” to the comment block containing the thread. That way, the context is always where the thread is. The thread could either be put in a “similar” location to where the lines were deleted, or, if that doesn’t work, in a separate special file that’s created only as part of the review workflow. But, I don’t think that’s quite ideal either. 我能想到的中短期内最好的解决方案是,将已删除行的上下文作为“标题”添加到包含该线程的评论块中。这样,上下文始终与线程在一起。线程可以放在删除行“相似”的位置,或者如果那样不行,就放在一个仅作为审查工作流一部分而创建的特殊文件中。但我认为这也不是很理想。
Thinking about this problem has started to convince me that only looking at one state of the code and representing the previous state as the Git HEAD is not enough. Being able to type comments inside an actual diff file is starting to feel like a valid and important use case to me. That might be a second “mode” supported by Flirt, or maybe there is even a hybrid workflow that combines the best of both worlds. Either way, it’ll probably take some time for this to be implemented in Flirt. 思考这个问题让我开始相信,仅查看代码的一种状态并将先前状态表示为 Git HEAD 是不够的。能够在实际的 diff 文件中输入评论,对我来说开始感觉是一个有效且重要的用例。这可能是 Flirt 支持的第二种“模式”,或者可能存在一种结合两者优点的混合工作流。无论如何,在 Flirt 中实现这一点可能需要一些时间。
public-inbox, the open-source mailing list archive
public-inbox,开源邮件列表存档
A mailing list is kind of an abstract concept. Supporting it as such is not possible. In practice, the open-source projects I know use a project called public-inbox to host their mailing list archives. Specifically, that includes the Linux kernel and Git. For now, I have opted to only support projects using public-inbox. Please let me know if there are other important projects using something else! I would be interested to at least explore how much effort it would take to support them. 邮件列表是一个抽象概念,直接支持它是不可能的。实际上,我所知的开源项目都使用一个名为 public-inbox 的项目来托管其邮件列表存档。具体来说,包括 Linux 内核和 Git。目前,我选择仅支持使用 public-inbox 的项目。如果有其他使用不同系统的关键项目,请告诉我!我很乐意去探索支持它们需要付出多大的努力。
Missing information in git format-patch output
git format-patch 输出中缺失的信息
The best “standard” a review tool built on top of mailing lists is the output of git format-patch. Sadly, it leaves a few things to be desired for Flirt’s use case. 构建在邮件列表之上的审查工具,其最好的“标准”就是 git format-patch 的输出。遗憾的是,对于 Flirt 的用例来说,它还有一些不足之处。
Base commit 基础提交(Base commit) git format-patch can add the base commit information automatically, but doesn’t do so by default. Users have to request it with the —base flag. If the base commit information is missing, what should Flirt do? Apply the patches to HEAD, or to master? Either way, it’s going to be wrong and lead to conflicts in some cases. We could let the reviewer specify the base manually, but that’s pretty bad UX in my opinion. Ideally, the reviewer would just ask the patch series author to resubmit with —base. git format-patch 可以自动添加基础提交信息,但默认情况下不会这样做。用户必须使用 —base 标志来请求它。如果缺少基础提交信息,Flirt 该怎么办?是将补丁应用到 HEAD 还是 master?无论哪种方式,都可能是错误的,并在某些情况下导致冲突。我们可以让审查者手动指定基础,但在我看来,这是一种非常糟糕的用户体验。理想情况下,审查者只需要求补丁作者使用 —base 重新提交即可。
Jujutsu change-id header Jujutsu change-id 头部 Jujutsu stores its change-id in a custom commit header. git format-patch doesn’t preserve them. There was a proposal a while back on the Git mailing list to change that. Unfortunately, I don’t think that effort was continued. Without the change-id header, the most important feature of Flirt doesn’t work reliably. Flirt can implement heuristics like matching subject line, author and so on. git range-diff basically tries to solve this problem simply based on the similarity of the patches. Whatever Flirt ends up doing, it will have to be a heuristic given the current constraints. Jujutsu 将其 change-id 存储在自定义提交头部中。git format-patch 不会保留它们。之前在 Git 邮件列表上曾有一个关于改变这一点的提议。遗憾的是,我认为该工作并没有持续下去。没有 change-id 头部,Flirt 最重要的功能就无法可靠地工作。Flirt 可以实现启发式算法,例如匹配主题行、作者等。git range-diff 基本上只是简单地基于补丁的相似性来解决这个问题。无论 Flirt 最终采取什么方案,鉴于目前的限制,它都必须是启发式的。
Detecting related patch series versions 检测相关的补丁系列版本 Flirt has a relatively strict model of Spirits and their submissions. That doesn’t perfectly map onto mailing lists. git format-patch can add a version tag to the subject line. Well-behaved patch series submissions will have sub… Flirt 对 Spirits 及其提交有一个相对严格的模型。这并不能完美地映射到邮件列表上。git format-patch 可以在主题行中添加版本标签。表现良好的补丁系列提交会有 sub…