Ghostty 提交信息规范详解:subsystem 前缀、参考引用与长描述的完整实践
【免费下载链接】ghostty👻 Ghostty is a fast, feature-rich, and cross-platform terminal emulator that uses platform-native UI and GPU acceleration.项目地址: https://gitcode.com/GitHub_Trending/gh/ghostty
本文以 Ghostty 仓库中为 AI Agent 编写的提交信息技能文档 SKILL.md 为主体,完整拆解其提交信息格式模板、主题行/引用/长描述三段式规则与落地工作流,并结合仓库真实提交历史验证这些约定在 Ghostty 中的实际执行情况。读完本篇后,你可以按照与 Ghostty 维护者一致的风格撰写可审计、可检索的提交信息,并理解每一条规则背后的工程动机。
规范文档的定位
.agents/skills/writing-commit-messages/SKILL.md是 Ghostty 仓库内置的一份 Agent 技能(skill)文档,文档头部的 frontmatter 声明了触发条件:
name: writing-commit-messages description: >- Writes Git commit messages. Activates when the user asks to write a commit message, draft a commit message, or similar.也就是说,当用户要求“写一条提交信息 / 起草一条提交信息”时,执行环境会激活该技能,并要求产出的提交信息严格遵循本文所述的风格。它的核心目标用原文一句话概括:Write commit messages that follow commit style guidelines for the project——提交信息不是随手写的说明,而是带有项目专属约定(subsystem 前缀、行宽、语气)的结构化产物。
值得注意的是,这份规范是 VCS 无关的:它不假设仓库一定用 git,而是根据工作区中是否存在.jj目录(Jujutsu 版本控制的工作目录标记)来决定使用git还是jj执行命令,这一点在文末的工作流部分会完整展开。
提交信息的三段式格式模板
文档给出的标准格式由三部分按顺序组成,中间以空行分隔:
<subsystem>: <summary> <reference issues/PRs/etc.> <long form description>对应地,一条完整的 Ghostty 风格提交信息由:
- 主题行:
subsystem: summary形式,独占首行; - 引用区(可选):关联的 issue / PR / 讨论编号,每行一个;
- 长描述(可选):纯散文式的正文,解释改动内容、先前行为与新行为。
三个部分之间各用一个空行分隔;当引用区不存在时,空行也要一并省略(后文“引用区规则”中有明确说明)。
主题行规则:subsystem 前缀与 summary
subsystem 前缀的确定方式
主题行以小写的 subsystem 标识开头,后跟冒号和空格。文档明确给出的前缀示例包括terminal、vt、lib、config、font,并规定了三条特殊映射:
| 改动范围 | 使用的前缀 |
|---|---|
| 改动涉及 macOS 应用 | macos |
| 改动涉及 GTK 应用运行时 | gtk |
| 改动涉及构建系统 | build |
前缀的判定依据是diff 中变更的文件路径,而不是主观印象。当改动范围更聚焦时,允许使用/分隔的嵌套 subsystem,条件是“helpful and exclusive”(有帮助且独占),文档给出的例子是terminal/osc。
对照当前仓库的目录结构,这些前缀与实际代码位置的对应关系非常清晰:
| 前缀 | 对应的仓库路径 |
|---|---|
terminal | src/terminal/(如 Terminal.zig、Screen.zig) |
terminal/osc | src/terminal/osc/ |
terminal/kitty | src/terminal/kitty/ |
terminal/c | src/terminal/c/ |
libghostty | C API 层,如 include/ghostty.h 与 src/main_c.zig |
macos | macos/(Swift 应用源码位于 macos/Sources/) |
gtk | src/apprt/gtk/ |
build | build.zig、Makefile |
ci | .github/workflows/ 下的工作流文件 |
renderer | src/renderer/ |
font | src/font/ |
config | src/config/ |
i18n | po/ 下的翻译文件 |
从最近 400 条提交的主题行统计来看,前缀分布与仓库结构高度吻合:terminal:(56 次)、terminal/kitty:(45 次)、libghostty:(30 次)、macos/macOS(合计约 57 次)、i18n:(14 次)、renderer:(8 次)、gtk:(6 次)、ci:与build:(各 5 次)是最高频的前缀,此外还出现了example:、deps:、font:、input:、termio:等按目录划分的子系统。可以看到,前缀体系本质上就是把仓库的目录树压缩进提交历史,让git log --oneline本身就成了一份带作用域过滤功能的项目导航。
summary 的书写要求
文档对冒号后面的 summary 部分提出三条硬性约束:
- 首字母小写:不以大写开头;
- 祈使语气(imperative mood):如
fix ...、add ...、update ...; - 行尾不加句号。
此外要求整体简洁,整个主题行(含 subsystem 前缀)最好控制在 60 个字符以内。这条限制与git log --oneline的默认展示宽度一致,目的是保证在终端里单行完整可见。仓库历史中的实际提交普遍遵守了这一点,例如:
gtk: do not warn when gtk-xft-dpi is -1 font: update embedded Noto emoji fonts renderer: vsync unfocused surfaces while dirty引用区规则:何时写、怎么写
当改动与某个 GitHub issue、PR 或讨论相关时,引用区必须出现在主题行之后,格式要求是:
- 相关编号每行一个,例如
#1234; - 引用区与主题行之间、与长描述之间各有一个空行。
文档同时给出了一条容易忽视的反向规则:如果没有引用,就整个省略该段,连空行也不要留下——即不允许出现“主题行后连续两个空行再接正文”的形态。这一点保证了提交信息在git log中的紧凑性。
真实提交中引用区与长描述的组合形态可以参考这条修复RefCountedSet的提交(c2906398b):
terminal: fix living item over-count in RefCountedSet.addWithId (#14081) Reported in https://github.com/ghostty-org/ghostty/discussions/14064 I validated this myself manually. The zero-ref branch of `addWithIdContext` incremented `living` unconditionally ...主题行末尾内联了 PR 号(合并时的标准形态),正文首行补充了报告来源,随后直接进入技术描述。
长描述规则:散文、72 字符与 why/how
对长描述部分,文档给出了五条规则,每一条都针对提交信息中常见的坏味道:
- 说明三件事:什么变了(what changed)、之前的行为是什么(what the previous behavior was)、新行为如何工作(how the new behavior works),且都停留在高层描述;
- 用纯散文(plain prose),不用要点列表——提交正文不是 markdown 清单;
- 行宽约 72 字符换行,与
patch/邮件投递格式的传统保持一致; - 聚焦 why 与 how,而不是复述 diff——读者自己能看到 diff,正文的价值在于解释动机与机制;
- 语气直接、技术化、不带填充词,篇幅控制在“a handful of paragraphs; less is more”。
用上面那条RefCountedSet提交逐段对照,可以看到规则是如何落地的:
I validated this myself manually. The zero-ref branch of
addWithIdContextincrementedlivingunconditionally even ifupsertresolved the value to an item that was already alive under a different ID.
这一段回答的是“先前行为”——零引用分支无条件递增living;接下来一段解释新行为与下游影响(count()漂移、样式内存过量预留、未发现崩溃);段落全部为散文,行宽严格控制在 72 字符附近,没有 bullet,没有“本次提交修复了一个 bug”之类的填充语。另一条terminal/kitty: validate POSIX shared memory names的提交则在正文中说明改动是对新规格(new spec)的跟进,属于典型的“聚焦 why 而非复述 diff”。
工作流:从 diff 到提交落盘
文档末尾的 Workflow 一节规定了撰写提交信息的六步操作顺序:
- 检查
.jj目录:若存在,则所有命令使用jj代替git执行;当前仓库克隆中不含.jj目录,因此默认走git路径。这条规则使同一份规范可以同时服务 git 用户与 Jujutsu 用户; - 运行 diff:查看自上次提交以来的全部变更(如
git diff/jj diff); - 识别 subsystem:根据变更文件的路径确定前缀(对应前文的前缀映射表);
- 识别引用:从 diff 上下文或分支名中提取关联的 issue/PR 编号(例如分支
add-serbian-translation对应提交历史中的塞尔维亚语翻译系列提交); - 按格式起草:套用三段式模板写出完整提交信息;
- 应用提交,但不推送:
Don't push the commit; leave that to the user——推送与否的决定权始终留给用户。
这个流程刻意把“识别 subsystem”放在“识别引用”之前,与格式模板中主题行先于引用区的顺序保持一致;最后一步的“不推送”则与提交信息技能的定位相符:它负责把本次变更准确、规范地固化为一条提交,而不越权执行远端操作。
对照真实历史的验证
以下均取自当前仓库最近的实际提交,可直接用git log复核,覆盖规范中提到的大部分子系统:
| 实际提交主题行 | 覆盖的规范点 |
|---|---|
terminal: fix living item over-count in RefCountedSet.addWithId (#14081) | 嵌套修复语义 + 内联 PR 号 + 长描述 |
terminal/kitty: validate POSIX shared memory names (#14080) | 嵌套 subsystem(terminal/kitty) |
terminal/c: allow freeing a search and its terminal in any order | C API 子层前缀(terminal/c) |
libghostty: add terminal search API (#14097) | C API 门面层前缀(libghostty) |
gtk: do not warn when gtk-xft-dpi is -1 (#14085) | GTK 应用运行时前缀(gtk) |
renderer: vsync unfocused surfaces while dirty (#14068) | renderer前缀 |
build: update Sparkle to 2.9.6 and pin SPM (#14082) | 构建系统前缀(build) |
ci: require freestanding libghostty-vt builds | CI 工作流前缀(ci) |
i18n: adjust and extend Ukrainian translation (#13854) | 翻译资产前缀(i18n→po/) |
font: update embedded Noto emoji fonts (#14047) | font前缀 |
其中ci: require freestanding libghostty-vt builds只有主题行、没有正文,说明短小且自解释的变更可以合法地省略长描述——“less is more”并非要求每段都写满,而是写出来的部分要信息密度足够。
小结:一份可直接执行的检查清单
综合 SKILL.md 的完整内容与仓库实践,撰写一条 Ghostty 风格提交信息前可以逐项核对:
- 主题行是否形如
<subsystem>: <summary>,前缀取自 diff 涉及的路径(macos/gtk/build按约定映射,聚焦时可用terminal/osc式嵌套)? - summary 是否小写开头、祈使语气、行尾无句号,且主题行总长在 60 字符内?
- 有引用时编号是否每行一个且与前后各隔一空行;无引用时是否连同空行一起省略?
- 长描述是否用散文讲清“改了什么 / 之前什么样 / 现在如何工作”,约 72 字符换行,聚焦 why 与 how?
- 执行链路上是否先 diff、再定前缀、再找引用,提交后未推送、推送留给用户?
这套规范的价值在于它把“提交信息”从自由文本变成了与仓库目录结构一一对应的、可被git log按前缀过滤的索引层:前缀即作用域,引用区即变更溯源,长描述即行为说明。对贡献者而言,照此执行即可让自己的提交与 Ghostty 现有历史保持风格一致;对 Agent 而言,这份 skill 文档提供了无歧义的格式契约与操作顺序,使自动生成的提交信息在合入前就满足项目惯例。
【免费下载链接】ghostty👻 Ghostty is a fast, feature-rich, and cross-platform terminal emulator that uses platform-native UI and GPU acceleration.项目地址: https://gitcode.com/GitHub_Trending/gh/ghostty
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考