用 Commit Message Storyteller 写出有故事的提交信息:awesome-copilot 的叙事式 Conventional Commits 技能实战
2026/9/12 12:08:13 网站建设 项目流程

用 Commit Message Storyteller 写出有故事的提交信息:awesome-copilot 的叙事式 Conventional Commits 技能实战

【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot

导读

本篇文章聚焦 awesome-copilot 仓库中的commit-message-storyteller技能:它能把原始的git diff或口头变更描述,转化为遵循 Conventional Commits 规范、强调"为什么改"而非"改了什么"的叙事式提交信息。读完本文,你将掌握该技能的完整调用流程、提交类型判定表、三部分提交结构(主题行/正文/脚注)、多提交拆分启发式与边界情况处理,并了解它与仓库中gitmojiconventional-commit等兄弟技能的分工差异。

技能定位:从"改了文件"到"讲了故事"

commit-message-storyteller的核心主张在 skills/commit-message-storyteller/SKILL.md 开头就说得非常直白:它"将原始 git diff 和变更描述转化为清晰、故事驱动的提交信息",目标不是产出update file.js这类流水账,而是让每条提交信息传达意图(intent)、上下文(context)与影响(impact)

这份技能文件遵循 Agent Skills 规范(docs/README.skills.md 说明每个技能是包含SKILL.md指令文件与配套资源的独立文件夹,按需渐进式加载),配套资源为references/conventional-commits-guide.md——一份可随时查证的 Conventional Commits 速查手册,供模型在生成信息时参考完整类型示例与 scope 规范。

何时启用该技能

SKILL.md的 frontmatter 中定义了技能的触发条件与描述,明确列出以下典型场景:

  • 用户说 "write a commit message"、"help me commit" 或 "generate a commit"
  • 用户直接粘贴一段git diff或口头描述代码变更
  • 用户问 "what should I commit this as?" 或 "summarize my diff"
  • 用户希望为团队或开源项目维护更高质量的提交历史
  • 用户正准备提交 Pull Request,需要有意义的提交信息

该技能可从三种输入工作:git diffgit diff --staged的输出、对"改了什么以及为什么改"的描述、以及修改文件列表。

前置准备:获取变更上下文

使用前至少准备以下其中一种输入:

  • git diffgit diff --staged的输出
  • 一段对变更内容及原因的说明
  • 一份修改文件清单

技能在Quick Reference中给出了获取 diff 的标准命令(这是本仓库其他提交类技能,如 skills/gitmoji/SKILL.md 与 skills/git-commit/SKILL.md,也共同采用的习惯):

# 获取已暂存(staged)的变更,粘贴给 Copilot git diff --staged # 或获取工作区中尚未提交的变更 git diff

四步生成流程

第一步:收集变更上下文

技能要求先明确三件事,可由用户提供,也可从 diff 中自动推断:

  1. 改了什么—— 受影响的文件、函数与逻辑
  2. 为什么改—— bug 修复、新功能、重构、性能优化等
  3. 谁/什么触发了这次改动—— issue 编号、用户请求、技术债等

如果用户只提供原始git diff,则应从 diff 中自动提取这些上下文,而非反复追问。

第二步:判定提交类型

将变更映射到 Conventional Commits 的类型,SKILL.md给出完整判定表:

TypeUse When
featA new feature or capability is added
fixA bug or incorrect behavior is corrected
refactorCode restructured without changing behavior
perfA change that improves performance
docsDocumentation only changes
styleFormatting, whitespace, missing semicolons (no logic change)
testAdding or updating tests
choreBuild process, dependency updates, config changes
ciCI/CD pipeline changes
revertReverting a previous commit

详细示例见 references/conventional-commits-guide.md。需要注意的是,该类型表与仓库中 skills/git-commit/SKILL.md 的类型表大体一致,但后者额外列出了build类型(构建系统/依赖变更),这提醒使用者:团队约定决定了类型集合,引用速查手册时以项目实际采用的规范为准。

第三步:按三部分结构撰写提交信息

生成的信息遵循如下结构:

<type>(<optional scope>): <short imperative summary> <body — the story: why this change was made, what problem it solves> <footer — issue refs, breaking change notices>

主题行(第一行)规则:

  • 使用祈使语气:addfixremove,而不是addedfixes
  • 最多 72 个字符
  • 末尾不加句号
  • 冒号后小写开头

正文(故事部分)规则:

  • 解释为什么(why),而不是什么(what)——diff 已经展示了"改了什么"
  • 描述变更前存在的问题
  • 如相关可提及考虑过的备选方案
  • 每行控制在 100 字符以内
  • 与主题行之间用空行分隔

脚注规则:

  • 引用 issue:Closes #123Fixes #456Refs #789
  • 标记破坏性变更:BREAKING CHANGE: <description>

关于破坏性变更,references/conventional-commits-guide.md 补充了两种等价写法——在类型后用!(如feat(api)!: remove v1 endpoints),或在脚注中写BREAKING CHANGE:段落,二者可并用。

第四步:生成输出

在可复制的代码块中产出提交信息,随后用一行通俗英语说明你讲述的故事。SKILL.md给出的示例输出:

fix(auth): prevent token refresh loop on expired sessions When a user's session expired mid-request, the auth middleware was triggering a token refresh, which itself failed validation and triggered another refresh — causing an infinite retry loop that crashed the app. This adds a recursion guard flag that aborts the refresh cycle if a refresh is already in progress, returning a clean 401 instead. Closes #312

Story told:A silent infinite loop on session expiry was crashing the app; this stops the cycle early and returns a clean error.

注意这个示例的精妙之处:主题行fix(auth): prevent token refresh loop on expired sessions是一句完整的祈使句;正文讲述"之前为什么崩溃、这次如何修复";脚注Closes #312关联 issue。这正是"讲故事"与"流水账"的分水岭。

一个 diff 拆成多个提交

当 diff 包含逻辑上彼此独立的变更时,技能要求拆分成多条提交信息并明确告知用户。启发式判断如下:

  • 用途无关的不同文件 → 很可能应拆成多个提交
  • 同一文件但关注点不同(例如 bug 修复 + 重构)→ 建议拆分
  • 各部分紧密耦合 → 一个提交即可

这一原则与 skills/git-commit/SKILL.md 的 Best Practices("One logical change per commit",一次提交只包含一个逻辑变更)相互印证,也与 references/conventional-commits-guide.md 反模式表里"misc changes应拆分成独立有意义的提交"的建议一致。

边界情况处理表

SituationHow to Handle
用户只给了 diff、无其他上下文从文件名和变更符号推断类型与 scope
变更横跨大量文件且主题不明询问:"这是一个逻辑变更,还是多个?"
检测到破坏性变更自动添加BREAKING CHANGE:脚注
用户说 "keep it short"省略正文,只写一个有力的主题行
没有 issue 编号完全省略脚注

配套速查手册:Conventional Commits 参考指南

references/conventional-commits-guide.md是技能自带的验证与扩充实操素材,核心内容包括:

格式定义:

<type>(<scope>): <description> [optional body] [optional footer(s)]

完整类型示例(含 scope、正文与脚注):速查手册为每个类型都配了带故事正文的完整示例,包括feat(payments)(Apple Pay 支持)、fix(api)(分页偏移 off-by-one 错误)、refactor(user-service)(抽取共享校验工具)、perf(dashboard)(图表懒加载)、docs(readme)test(auth)chore(deps)(eslint 升级)、ci(GitHub Actions 缓存)、revert等。

Scope 指南:scope 可选但强烈推荐,应是标识代码库区域的短名词(authapidashboardpayments),在项目内保持一致(不要混用userusers),当改动真正全局性时可省略。

正文写作技巧:写正文前自问三个问题——"这次改动前什么坏了/缺失了?"、"为什么选择这个方案而非其他?"、"对用户或开发者来说改动后有何不同?";同时避免复述 diff 已展示的内容(如"改了个变量名")、避免模糊语言("various improvements")以及避免将来时("this will fix...",应使用现在/过去时)。

提交信息反模式对照表:

❌ Bad✅ Better
fix bugfix(cart): prevent duplicate items on rapid add-to-cart clicks
updatesfeat(profile): allow users to update display name
WIPDon't commit WIP — stash it
misc changesSplit into separate, meaningful commits
John's changesDescribe what changed, not who changed it

与仓库内其他提交类技能的协同

在 awesome-copilot 仓库中,围绕"提交信息"存在多个互补技能,理解分工有助于按场景选择:

  • skills/gitmoji/SKILL.md:按 gitmoji 约定生成带 emoji 的提交信息,仅生成消息不执行 git 命令。其文档明确写道:如果项目遵循纯 Conventional Commits(feat:fix:...)而无 emoji,应使用conventional-commitcommit-message-storyteller技能;不确定时先让用户提供git log --oneline -10
  • skills/conventional-commit/SKILL.md:面向"一键执行提交"的场景,用结构化 XML 模板构造提交信息,并由 Copilot 直接在集成终端运行git commit -m "type(scope): description"
  • skills/git-commit/SKILL.md:可执行git commit的完整工作流技能,包含 diff 分析、智能暂存与 Git 安全协议(不更新 git config、不做破坏性操作、不跳过 hooks、不强制推送主干等)。

commit-message-storyteller的独特价值在于叙事深度:它默认不执行 git 命令,产出可复制的消息 + 一行故事说明,专精于把 diff 背后的"为什么"讲清楚——是四者中最适合提升开源项目与团队提交历史可读性的选择。

如何安装与使用该技能

依据 docs/README.skills.md 的说明,该技能可通过 GitHub CLI 安装:

gh skills install github/awesome-copilot commit-message-storyteller

(需 GitHub CLI v2.90.0 及以上版本);或将skills/commit-message-storyteller文件夹手动复制到本地技能目录。安装后在提示中引用技能名,或让 Agent 根据上述触发场景自动发现即可。

技能的结构本身也经受仓库工程化校验:eng/validate-skills.mjs会检查每个技能目录的SKILL.md存在性、frontmatter 中name/description的合法性、文件夹名与技能名一致,以及捆绑资源大小上限(5MB)。commit-message-storyteller的 frontmatter 与配套资源references/conventional-commits-guide.md正符合该校验标准,可直接作为自定义技能的编写范本。

实践要点速览

  1. 输入即素材:优先让用户粘贴git diff --staged,模型自动提取"改了什么、为什么、谁触发的"。
  2. 类型先于措辞:先用上文的 10 类型判定表定基调,再动笔写句子。
  3. 主题行是一句话的承诺:祈使语气 + ≤72 字符 + 不带句号,如perf(dashboard): lazy-load chart components
  4. 正文只讲 why:diff 已经给出 what,正文聚焦"之前的问题 + 修复思路 + 备选方案"。
  5. 脚注承载可追溯性Closes #xxx关 issue,BREAKING CHANGE:标记破坏性变更。
  6. 宁可拆分不可杂糅:逻辑独立的变更拆成多条提交并告知用户。
  7. 尊重团队约定:项目若用 gitmoji 走 skills/gitmoji/SKILL.md,若需一键执行走 skills/conventional-commit/SKILL.md,讲故事则用本技能。

【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询