我最近在整理项目提交记录时,又遇到一个老问题:VSCode 里自动生成的 Git 提交信息挺方便,但结果不够稳定。

有时候是英文。

有时候是中文。

有时候格式像 Conventional Commits,有时候又只是随手一句说明。

单次看问题不大,但一个项目跑久了,提交历史就会变得很乱。尤其是多人协作时,featfixdocs 这些类型本来是为了方便检索,结果每个人生成出来都不一样,最后反而增加了维护成本。

工具可以自动化,但自动化结果必须可控。

这篇文章记录一下我现在的做法:在 VSCode 里配置 GitHub Copilot Chat,让它生成 Git commit message 时固定使用简体中文,并且严格遵守一套 emoji + type + 中文描述的格式。

为什么要专门配置提交信息

以前我对 commit message 没有太强迫。

只要大概能看懂,我就觉得差不多了。后来项目多了才发现,提交信息不是写给当下的自己看的,而是写给几个月后的自己、同事、排查问题时的 git log 看的。

我最怕看到这种提交历史:

update
fix bug
修改一下
change
优化

这些信息不能说完全没用,但价值很低。等线上出了问题,想通过提交历史快速定位变更意图时,这类记录基本帮不上忙。

提交信息的核心价值,不是描述改了哪些文件,而是描述这次改动的意图。

GitHub Copilot 在 VSCode 里可以根据 staged changes 自动生成 commit message,这个能力本身很好。问题是,如果不加约束,它生成的内容会受上下文、语言环境、模型判断影响。

所以我会把规则写进 VSCode 配置里。

说白了,就是不要每次都靠临场发挥。

核心配置

打开 VSCode 的 settings.json,加入下面这段配置:

{
  "github.copilot.chat.localeOverride": "zh-CN",
  "github.copilot.chat.commitMessageGeneration.instructions": [
    {
      "text": "Always generate git commit messages in Simplified Chinese."
    },
    {
      "text": "Follow this exact format: <emoji> <type>: <中文简短描述>."
    },
    {
      "text": "Use only these types and emojis: ✨ feat, 🐛 fix, 📝 docs, ♻️ refactor, ⚡ perf, 🧑‍💻 dx, 🔨 workflow, 🏷️ types, 🚧 wip, ✅ test, 🔨 build, 👷 ci, ❓ chore, ⬆️ deps, 🔖 release."
    },
    {
      "text": "Pick the single most appropriate type based on the main intent of the staged changes."
    },
    {
      "text": "Do not output English. Do not output explanations. Do not output bullet points. Output only the final commit message."
    },
    {
      "text": "Keep the subject concise, natural, and professional in Chinese."
    }
  ]
}

这段配置主要做了两件事。

一个是把 Copilot Chat 的语言偏好固定为 zh-CN。另一个是给 commit message generation 单独加 instructions。

我更看重第二部分。

因为语言偏好只能影响大方向,不能保证生成结果完全符合团队规范。真正起作用的是后面的几条指令,它们把格式、类型、语言、输出范围都卡住了。

这套格式解决了什么问题

我使用的格式是:

<emoji> <type>: <中文简短描述>

生成结果大概会长这样:

✨ feat: 支持文章标签筛选
🐛 fix: 修复搜索结果排序异常
📝 docs: 更新部署说明文档
♻️ refactor: 简化博客列表渲染逻辑

这个格式不复杂,但足够清晰。

emoji 负责让提交历史更容易扫读,type 负责表达改动类别,中文描述负责说明具体意图。三者放在一起,比单纯写 fix bugupdate docs 稳定很多。

好的提交信息应该一眼能看出主意图。

我不建议把 commit message 写得太长。提交详情可以放在 body 里,但自动生成的 subject 最好短一点。实际项目里,很多人看提交历史都是扫一眼列表,太长反而影响阅读。

类型列表不要太自由

配置里我限制了可用类型:

✨ feat
🐛 fix
📝 docs
♻️ refactor
⚡ perf
🧑‍💻 dx
🔨 workflow
🏷️ types
🚧 wip
✅ test
🔨 build
👷 ci
❓ chore
⬆️ deps
🔖 release

这里有个很容易被忽略的点:类型不是越多越好。

类型太多,模型会犹豫,人也会犹豫。最后就会出现同一类改动,有人用 chore,有人用 workflow,有人用 build。看起来都说得通,但历史记录会变乱。

我把类型控制在常见工程场景里:

  • feat 表示新增功能
  • fix 表示修复问题
  • docs 表示文档修改
  • refactor 表示不改变行为的重构
  • perf 表示性能优化
  • dx 表示开发体验改进
  • workflow 表示开发流程调整
  • types 表示类型定义修改
  • test 表示测试相关修改
  • build 表示构建配置
  • ci 表示持续集成
  • deps 表示依赖升级
  • release 表示版本发布
  • wip 表示尚未完成的阶段性提交
  • chore 留给不好归类的杂项

chore 是兜底类型,不应该变成垃圾桶。

我的习惯是,能不用 chore 就不用。因为 chore 本身表达的信息很少,如果大量提交都叫 chore,那和 update 没有本质区别。

为什么要强调只选一个类型

配置里有一条很关键:

Pick the single most appropriate type based on the main intent of the staged changes.

这句话的意思是:只选一个最合适的类型。

实际开发中,经常会出现一次 staged changes 里既改了代码,又顺手改了文档,还顺手调了测试。Copilot 如果不受约束,可能会生成很复杂的描述,甚至想把所有变化都塞进 subject 里。

我不太喜欢这种做法。

一个 commit message 的 subject 只能承载一个主意图。如果一次提交里包含太多意图,更好的办法是拆提交,而不是写一个很长的标题去解释所有事情。

可以这样理解:

暂存区改动

判断主意图

选择一个 type

生成一句中文 subject

这个流程很朴素,但很实用。

如果一句话说不清这次提交,大概率应该先拆 commit。

输出约束一定要写死

我还加了这一条:

Do not output English. Do not output explanations. Do not output bullet points. Output only the final commit message.

这条看起来有点啰嗦,但很有必要。

我之前遇到过生成结果里带解释的情况,例如:

根据你的更改,建议的提交信息是:
✨ feat: 添加搜索页面

人眼看没问题,但如果你想直接复制、快捷提交,前面那句解释就是噪音。自动化工具最怕这种“多余的好心”。

所以我会明确要求它只输出最终提交信息。

这里不要含糊。

不要写“尽量简洁”就完事。要把不允许的东西写清楚:不要英文、不要解释、不要项目符号,只输出最终 commit message。

放在用户配置还是工作区配置

这段配置可以放在用户级 settings.json,也可以放在项目的 .vscode/settings.json

我一般这样分:

  • 个人习惯放用户配置
  • 团队统一规范放工作区配置
  • 开源项目谨慎放工作区配置

如果只是你自己想让所有项目都默认生成中文提交信息,放用户配置就行。

如果一个团队明确约定所有提交信息都用中文,并且要遵守统一格式,那放到项目的 .vscode/settings.json 更合适。这样新人拉下项目后,也能复用同一套规则。

不过这里要注意一点:.vscode/settings.json 属于编辑器配置,不是所有人都用 VSCode。团队规范最好还要写进 README 或贡献指南里。否则不用 VSCode 的同事看不到这套规则。

编辑器配置是辅助,不应该成为唯一规范来源。

我的实际使用流程

我的日常流程比较简单。

先正常改代码,然后只暂存和这次意图相关的文件:

git add src/content/blog/example/index.md

接着在 VSCode Source Control 面板里使用生成提交信息的能力,让 Copilot 根据 staged changes 生成 subject。

生成结果出来后,我会扫一眼三件事:

  • type 是否符合主意图
  • 中文描述是否自然
  • 是否只有一行最终提交信息

如果都没问题,就直接提交。

如果 type 不对,我会手动改。不要为了省几秒钟接受一个明显不准确的提交信息。提交历史是长期资产,越到后面越能体现价值。

常见问题

生成结果还是出现英文怎么办

先确认配置是否真的写到了当前生效的 settings.json。VSCode 有用户配置、远程配置、工作区配置,多层设置叠在一起时,偶尔会看错位置。

然后检查 instructions 里是否有冲突规则。比如其他地方又要求输出英文,模型就可能摇摆。

我的建议是,把 commit message 相关规则集中放在一起,不要分散到多个地方。

emoji 会不会太花

看团队习惯。

我个人觉得适量 emoji 可以提高扫读效率,尤其是在 VSCode、GitHub、终端里看日志时,视觉锚点很明显。

但如果团队不喜欢 emoji,也可以保留 type,去掉 emoji。核心不是 emoji,核心是格式稳定。

中文提交信息会不会影响工具链

正常不会。

Git 本身可以处理 UTF-8 提交信息。真正需要注意的是周边脚本,比如某些 changelog 生成工具、发布脚本、正则检查规则。如果这些工具默认假设英文 Conventional Commits,就要提前调整。

从工程角度看,提交信息语言不是最大问题。不统一才是最大问题。

总结

VSCode + GitHub Copilot 自动生成 commit message 很方便,但我不建议直接裸用。

我的经验是,至少要约束这几件事:

  • 固定使用简体中文
  • 固定提交信息格式
  • 限制可用 type 和 emoji
  • 只选择一个主意图
  • 禁止输出解释性文本
  • 保持 subject 简短自然

这套配置不复杂,但可以明显减少提交历史里的噪音。

自动化不是让工具随便发挥,而是把重复工作变成稳定输出。

commit message 看起来是小事,但项目维护久了,小事都会变成成本。把规则提前写进配置里,后面会省很多沟通和回头翻历史的时间。