关于 comprehende
Comprehende 是一套命令行与本地界面工作流,用于按审查关注点整理 Git diff。它根据差异和相关来源编写说明文档,验证覆盖范围,并提供本地查看或导出。
主要功能
- 01按审查关注点归组差异块
- 02生成文件与差异块摘要
- 03将分组关联到来源和变更故事
- 04对照 Git 验证文档覆盖范围
- 05提供本地审查界面
- 06导出静态审查站点
适用场景
- 01整理分支或合并请求的审查
- 02拆分相互独立的变更故事
- 03核对审查分组是否覆盖实际差异
- 04以本地界面或静态站点分享已验证的审查
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matemolnar8/ comprehende --skill comprehende安装后在 Claude Code 中输入/comprehende确认已加载。
附带文件references/example.mdreferences/review.schema.json
详细介绍
Comprehende
将 git 差异归纳为审查关注点,并提供本地 UI。目标是减轻认知负担,而不是放弃思考:让人能够拿着变更的缘由和内容,对照实时差异进行判断,而不是盲目接受变更。
在被审查的仓库内运行每条命令。当前工作目录就是仓库。使用固定版本的 CLI:
npx [email protected] <command>
审查文档仅用于阐释,其中包含标题、分组、摘要和代码块指针。serve 会从 git 读取差异。
根据摘要开展工作,而非直接查看差异。每个文件占摘要一行:类型、代码块、符号、配对和复制提示。在步骤 3 中通过一次 show 调用获取补丁。
工作流
如果此变更已有审查文档,请改用 Refresh。
每个步骤按要求执行一次工具调用。按原样批量执行命令;每多一次往返,就要重新发送整个上下文。每个阶段只用一次工具调用:步骤 2 的批处理及其来源、一次 show 批处理,以及一次以 validate 结束的写入。后续调用仅用于修复 validate 指出的问题。
-
指定 base 和 head。使用用户指定的引用;三点语法(
base...head)表示合并请求或分支差异。如果变更已合入默认分支,请使用请求中记录的 base 和 head SHA;会移动的默认分支HEAD包含之后的合并。如果只知道 head SHA,base 就是该 head 与指定 base 分支的合并基点。如果用户指定的引用不在克隆仓库中,请在步骤 2 的调用中先执行git fetch <remote> <ref>。完成条件:已选定两个引用名称。 -
一次 shell 调用:验证引用、写入草稿、打印摘要、草稿、日志和来源。
$REVIEW_DIR应在该调用中通过mktemp -d创建,且位于仓库之外。&&会在引用无法解析时阻止执行pregroup;请告知用户哪个引用解析失败。REVIEW_DIR=$(mktemp -d) && git rev-parse --verify --end-of-options "<base>^{commit}" && git rev-parse --verify --end-of-options "<head>^{commit}" && { npm view comprehende version || true npx [email protected] pregroup --base <base> --head <head> --data "$REVIEW_DIR/review.json" npx [email protected] digest --base <base> --head <head> cat "$REVIEW_DIR/review.json" git log --format='%s' --end-of-options <base>..<head> for f in "<sourcesDir>"/*; do echo "=== $f"; head -c 10000 "$f"; done }来源包括请求或工单正文、每条审查评论(注明其讨论串是否已解决、评论是否过时,以及当前行号)和提交主题。磁盘上的文件使用上述循环处理;主机 CLI 获取的内容通过相同的
head -c 10000并入此次调用。只有 MCP 能访问的来源,应在此次调用后通过一个并行代码块获取,每项来源调用一次。如果请求、分支名称或提交主题中出现工单编号,就应在此处读取对应工单。如果用户指定了本地可执行文件,请按原样使用该命令代替
npx [email protected],并在同一次 shell 调用中运行<executable> --version代替npm view。打印出的行就是 CLI 版本。如果该版本高于此处固定的版本(npx [email protected]),请停止并告知用户。可以建议他们运行npx skills update。不要运行该命令。等待他们选择继续使用此固定版本,或更新后重新启动此技能。如果版本相同或查询失败,则继续。pregroup会写入草稿:将收到相同变更的文件归入mirrors-<n>组;将重命名、复制、移动和生成的输出归入一个mechanical组;其余文件归入一个change组,并附上占位说明文字。cat会打印草稿。请相信same change as、pairs with和replaces提示;某个文件若replaces一个已删除文件,那么它与被替代文件属于新版本,而非移动,应结合其变更记录一起阅读。完成条件:摘要、草稿、日志和来源均已纳入上下文。 -
按评审关注点对代码块分组,从草稿开始,并获取决策所需的补丁。若草稿组已经只包含一个关注点,则接受该分组。在读者会停下来单独评审第一部分的位置拆分
change组。合并服务于同一关注点的草稿组。为每个本可独立成 PR 的故事命名:被请求的故事,以及每项依赖策略变更(将精确版本放宽为范围,或反过来)、独立文档、被请求的故事不需要的文件重构,或测试相关 PR 中的生产代码。每个故事在其分组上都是一个part;若只有一个故事,则不需要part。摘要中最多包含六个文件:获取每个非机械性、非副本文件。超过六个时,只获取决定是否拆分或值得列入 lookFor 条目的代码块,最多获取八次,并先说明每次的原因(“login.ts代码块可能应单独分组”)。草稿中的mirrors-<n>和mechanical组无需获取。一次 show 调用:npx [email protected] show --base <base> --head <head> --hunk "<ref>"; npx [email protected] show --base <base> --head <head> --file "<path>"当每个故事都有
part名称,或只有一个故事,且 show 输出已在上下文中,或无需获取任何内容时,即视为完成。 -
编写文档。始终填写文档
title和文档summary;仅当某个来源说明了动机时,才填写文档why。对照摘要和获取的代码块检查每个来源条目;每处不一致都作为文档的lookFor条目(见 lookFor)。摘要依据摘要中的符号和类型,以及获取的代码块编写。每个组都必须有why和summary。组的summary用一句话说明其代码块之间的一种关联,而不是列出文件。每次引用前,先在来源中找到陈述该主张的句子,并且仅为该句子引用该来源(见 The what 和 The why)。如果组中获取的代码块隐藏了行为变更,则添加一条lookFor,写明预测的执行轨迹(见 lookFor)。将草稿中的每个 ref 原样复制到包含它的组中;草稿中的 ref 已与当前 git 内容匹配。一个路径涵盖其文件的所有代码块;仅当文件拆分到多个组时,才写代码块 ref(path@oldStart+newStart,见 Grouping rules)。保留草稿中的version和source。通过一次 shell 调用,按下方字段结构完整写入review.json:使用带引号的 heredoc,然后运行validate。cat > "$REVIEW_DIR/review.json" <<'EOF' <the document> EOF npx [email protected] validate --data "$REVIEW_DIR/review.json"当每个来源条目都有判定、每处不一致都作为文档的
lookFor条目、获取的代码块显示的每项行为变更都有组级lookFor条目、草稿中的每个 ref 至少出现在一个组中、每个拆分文件的所有当前代码块都已命名、占位文本已删除、每个命名的part都有文档parts[]条目、每个dependsOnID 都指向同一part中的一个组、每条引用都有来源句子支持时,即视为完成。此外,只有当每个单元测试都放在其所测试代码所在的组中、多个组共用的每个辅助函数都放在它们共用的基础组中、每个新测试框架都与运行它的构建或 CI 放在一起、每份功能规格都与其种子和辅助函数放在一起、每个单行调用点或声明都与其服务的代码放在一起、本可独立成 PR 的未请求工作都有自己的part、相关的启用工作保留在同一个 part 中,并且每条机械性摘要都说明读者可以跳过什么时,才视为完成。当一个故事依赖另一个 part 时,suggestedOrder应将该 part 排在前面。字段结构。以下文字均为占位符。此结构足以编写有效文档。
{ "version": 1, "source": <the draft's source object, unchanged>, "size": "small", "title": "Short name", "summary": "What the change is.", "groups": [ { "id": "helper", "title": "Group title", "why": "Why this group exists.", "summary": "What this group is.", "suggestedOrder": 0, "hunkRefs": ["src/file.ts"] } ] }当定义某字段的章节要求填写时,添加该字段:文档
why、lookFor和parts(name、summary);sources(id、kind,值为ticket、pr、pr-comment、commit或transcript,label,以及可用时的url、title、gist和part)。对于组:part、sources(这些 ID)、lookFor、dependsOn(组 ID)。pr-comment来源还应包含author和body;如果 The why 中关于 PR 评论的说明有要求,还应包含固定位置(path、side、line)。size的取值为trivial、small、medium、large或very-large。 -
validate用于结束步骤 4 的调用;修复问题或通过 Refresh 编辑后,使用绝对路径运行npx [email protected] validate --data "$REVIEW_DIR/review.json"。它会检查:每个有效代码块都属于某个分组,每个引用都与当前 git 状态匹配,每个source:ID 都存在于sources中,每个目录引用都只包含机械生成的文件,每个分组的part都有对应的parts[]条目,每个dependsOn都指向同一part中的某个分组,每个 PR 评论锚点(path、side、line)都与有效行匹配,且文档不含未知字段。如果失败,请修复错误消息指出的问题;diff 属于 git,请勿修改。validate 以状态码 0 退出即表示完成。 -
用户要求上传报告时,请遵循 Export。否则,运行
npx [email protected] serve --data "$REVIEW_DIR/review.json" --open,并向用户提供本地 URL(仅限127.0.0.1)。
references/example.md 是一份可选的已填写示例,展示了字段结构。
Export
生成静态网站,并将该文件夹放到用户指定的位置。
npx [email protected] export --data "$REVIEW_DIR/review.json" --out "$EXPORT_DIR"
$EXPORT_DIR 是工作树外的一个全新目录,不是 git 仓库。该文件夹包含 UI 和冻结的 git 载荷,不包含 git。用户获得指定的 URL 或路径即表示完成。如果 review.json 仍是草稿,请先完成 Workflow 中的步骤,直到 validate 通过,然后再导出。
刷新
将现有评审延续到新的提交或变基后的提交。未变更代码块的说明保持不变;只有报告点名的分组需要更新措辞。
之前的文档是用户指定的 review.json,或托管导出的 api/review.json 中的 document 字段。先将它复制到一个新目录:
REVIEW_DIR=$(mktemp -d) && curl -fsSL "<site-url>/api/review.json" | jq .document > "$REVIEW_DIR/review.json"
-
一次 Shell 调用:获取 refs、刷新并打印文档。refs 默认取文档自身的
baseRef和headRef,并重新解析;用户指定其他 ref 时,传入--head或--base。git fetch --quiet <remote> && { npx [email protected] refresh --data "$REVIEW_DIR/review.json" cat "$REVIEW_DIR/review.json" }refresh会保留路径和变更行相同的代码块,无论它现在从哪里开始,并重新指向其 ref。原地编辑的代码块(同一文件、同一区域,但行内容不同)标记为changed,并保留其分组;如果只是空白字符发生变动,则标记为reformat。代码块已不在差异中的 ref 会被移除。未被任何分组覆盖的代码块会归入带有占位说明的草稿update分组;目录 ref 下的每个新代码块也会如此处理。报告会打印新的提交主题、每个代码块有变动的文件各占一行(包括new、changed、reformat、same、gone及其所属分组),以及每个分组有哪些变动。“nothing to refresh”表示 refs 仍解析为文档记录的提交:请获取正确的远程分支或指定 head,然后重新运行。报告和文档都已纳入上下文后,此步骤即完成。 -
按照工作流第 2 步提供来源,并将其追加到第 1 步的 Shell 调用中。会再次读取请求正文,因为文档的
lookFor条目会引用它。若评论的url已在sources中,则保留其条目;只需将评论当前的行和已解析状态复制到固定点。完整读取每条新评论。报告中包含提交主题。每条新评论和提交主题都已纳入上下文后,此步骤即完成。 -
执行一次
show批次,并将--base和--head设为新的范围,针对报告标记为new或changed的代码块。最多列出 6 个文件:获取每个包含new或changed代码块的文件。超过 6 个时,按第 3 步的预算处理报告列出的文件。仅当保留的lookFor条目依赖于某个same或reformat代码块时,才获取该代码块。 -
使用编辑工具原地修改
review.json;未触及的分组保持原样。将每个updateref 移入关注点所属的分组,或移入新分组,然后删除update。对于报告点名的分组:如果新的或变更的代码块改变了分组所代表的内容,就重写summary;移除每个代码块已gone的lookFor条目;对照获取的代码块,重新检查每个依赖于changed代码块的条目。若点名分组中的代码块含义未变,例如仅包含reformat代码块,则保留其说明原样。删除已“变为空”的分组,以及所有指向该分组的dependsOn。若新的提交已解决某条文档lookFor条目所述的问题,则将其移除;若新评论要求的工作并未由此次变更完成,则添加一条新条目。size随新的工作量调整;只有来源发生变化时才修改title和why。update已删除、没有空分组、没有占位说明,且每个点名分组的说明均与 head 上的代码相符后,此步骤即完成。 -
按照工作流第 5 步和第 6 步进行验证,然后在原位置提供服务或导出。将末尾带有
#changes的 URL 提供给用户:该页面会将本次评审与refresh保存在其旁边的评审进行比较。
标题
文档的 title 是对整个变更的简短命名。务必填写。
若人工撰写的标题能指代此次变更,则优先使用:拉取请求标题、工单标题,或用户在记录中使用的名称。只要措辞准确且能代表评审的变更,就保留原文。
如果这些来源缺失、含糊不清或指代其他内容,则自行拟定标题。分支名称、“WIP”或“fix”都不算标题。只有在来源标题适用时才保留。
原因
文档级 why 用一两句话说明这项工作的存在原因,只能根据以下来源推断。这是来源所述的问题或目标。编写之前,先找到说明该问题或目标的来源句子:“支持 SSO 登录”“以便管理员导出审计日志”“重试导致 API 请求激增”。仅说明变更内容的句子(“设置页面变成了模态框”“上传内容迁移到 S3”)应放在摘要中。如果没有来源句子说明问题或目标,或者来源内容不一致,则省略 why。使用来源本身的措辞,不得添加来源未提及的原因、好处或读者需求。若请求提及两个互不相关的产品事项,且没有统一的来源,也不写文档级 why;每个事项组保留各自的组级 why。
每个组都有 why:说明该组存在的原因。引用内容只能涵盖对应来源所述内容,且只有在来源明确说明某个选择的理由时,才能把该来源作为该选择的理由。最好使用明确提及相关顾虑的来源。没有自身来源的基础组应说明它为依赖它的组提供支持;这就是完整的 why。独立的附带工作若位于单独的部分中(仅文档、仅测试),应有自己的组级 why,而文档级 why 保留给明确说明的动机。
只阅读来源,切勿将其内容复制到评审文档中;PR 评论除外:复制 author 和 body,以便 UI 显示引文。不要将工单正文、请求描述、提交文本和转录文本写入 review.json。若某句表述依据某来源,在文中使用 [text](source:s1) 引用。
- 工单和 Issue。输出一个
sources条目:简短的id(s1)、kindticket、label(#24),以及可用的url、title、gist和part。如果某事项的各个组带有相同的part,则将part填在该事项的工单上。 - 拉取请求。用户提到拉取请求或合并请求时,输出
kindpr,使用类似PR #32的label,并根据描述填写gist。 - PR 评论。为文中引用的每条评论,以及每条置顶评论,分别输出一个
pr-comment来源。使用类似alice on PR #32的label。复制author和body。展平评论串:每条评论对应一个来源。若评论串尚未解决、Forge 报告了当前行,且评论未过期,则置顶该评论。置顶信息包括path、side和line。side对应基础文件中的行时为old,对应头部文件中的行时为new。在 GitHub 中,LEFT对应old,RIGHT对应new,当前行是line(original_line是较早提交中的行),未解决的评论串其isResolved为 false,过期评论的isOutdated为 true 或当前行为空。对话评论没有行,因此不置顶。 - 提交消息。运行
git log --format='%s' --end-of-options <base>..<head>。提交说明动机时,输出kindcommit。label使用提交主题行,或使用同一日志中的 SHA。提交可以帮助说明组级why;文档级why则需要上述更有力的来源之一。 - 转录。已有的编码 Agent 转录(本次会话或历史会话)可以提供人类陈述的理由。输出
kindtranscript,使用类似Cursor session · Aug 12的label,并填写gist。省略url。
将这些 id 放入使用相应来源的组的 sources 数组中,即使文中没有行内引用也一样。若 source: 链接的 id 不在 sources 中,validate 会失败。
是什么
文档中的 summary 用一两句话说明这项更改是什么;如果 PR 包含多个独立故事,则要逐一说明。每次审查都必须有 summary,即使没有 why 也一样。它描述的是更改内容,而不是动机。
当组使用 part 时,为每个独立故事在文档的 parts[] 中添加一个条目。name 的值就是该 part 字符串。summary 用一句话说明该故事是什么,语气与组的 summary 一致。文档的 summary 仍需说明这些故事;part 的 summary 则是在彩色「概览」列中按故事说明内容。如果没有任何组使用 part,则省略 parts。
组的 summary 用一句话说明该组的内容,并描述其代码块之间的关联方式:「routes.ts 中的路由会调用 core.ts 中新增的验证器」,而不是逐个文件回顾或罗列路径。对于保持原样的草稿 mirrors-<n> 和 mechanical 组,summary 要说明读者可以跳过哪些内容,以及为什么这样做是安全的:重复的相同更改、纯粹的移动,或含义相同的重新生成输出。
分组规则
- 按审查关注点分组:说明为什么这些代码块需要一起阅读。只有当目录本身就是关注点时,才将整个目录作为一个组。
- 一个组对应审查者会用短语描述的一个关注点。该组一起包含相关代码、检查它的单元测试,以及服务于它的单行调用点、声明和重新导出;摘要中的
pairs with提示会指出测试所属的模块。新增集成测试框架本身就是一个关注点:该框架及运行它的构建或 CI 文件属于同一组,而不是它所测试的生产代码组。新功能的代码、测试夹具、种子数据、辅助程序及运行它们的规范属于同一组。基础拆分用于支撑多个后续组共享的契约;多个组都会调用的辅助程序应归入该基础组,并与定义它的文件放在一起。只有当读者会停下来单独审查第一部分时,才拆分关注点。 - 一个代码块在多个故事中都很重要时,可以出现在多个组中。如果一个代码块包含两个关注点,包含它的组应同时点明这两个关注点。
dependsOn表示同一故事中的真实依赖:读者需要先了解前面的组,才能理解当前组。它必须位于同一部分内。一个故事内的阅读顺序为:契约和基础,然后是调用点,最后是机械性工作。独立工作应单独成部分,拥有自己的part和空的dependsOn。第二个功能、额外的产品事件、依赖策略变更,或本可以单独提交为 PR 的独立文档,都是独立工作。仅为支持所请求故事而进行、且未被请求的工作(路径重命名、测试夹具布局、本地启动)应与该故事放在同一部分,或单独放入一个测试框架部分。如果所请求的故事需要两个关注点,它们应共用一个part;否则应分成不同的部分。part是表示一个独立故事的简短名称(几个词),该故事中的每个组都使用相同名称;UI 会将共用部分归为一组。文档的parts[]中每个名称对应一个条目。- 机械性工作(导入排序、仅标识符重命名、生成代码、格式调整、纯移动)应单独成组,并附上其草稿引用,以便清楚呈现风险。草稿中的
mechanical组已包含 CLI 标记的文件;请检查每行是否仍属于该组(含有实际行为变更的已标记文件,应按其路径移出并归入对应故事),并填写说明读者可以跳过哪些内容。草稿中mirrors-<n>组内的文件与其源文件做了相同变更;该组的摘要应说明此变更是重复的。如果机械性组只是因某个故事而存在,它应是该部分的最后一组,且没有任何组依赖它。如果它本可以单独提交为 PR,则应作为独立部分。 suggestedOrder按顺序涵盖整个审查,包括独立部分。机械性部分、独立文档和仅涉及测试的清理应放在最后。- 文档的
size表示人工审查负担,取值为trivial、small、medium、large、very-large。一个组中有 40 个文件都只更改了一处导入,属于small。新增一个组件并对现有屏幕进行后续修改,属于medium。新增一个后续组依赖的契约,属于large。这些组在合并后仍保留该size。 - 覆盖范围:每个有效代码块至少属于一个组。一个路径会覆盖该文件中的所有有效代码块。允许多个组使用相同的引用。未被引用的代码块会导致
validate失败,并在 UI 中显示为 Unassigned。草稿中的每个引用都已覆盖其对应代码块;将一个文件拆分到多个组时需要使用代码块引用,其他情况均保留草稿中的路径。 - 锁文件没有代码块引用;CLI 不会将其放入草稿,UI 会为其单独设置一个默认关闭的分组。代码块引用只适用于草稿列出的代码块。
- 如果变基只调整了行号,路径仍然有效。
path@oldStart+newStart会在起始行发生变化时失效,并导致validate失败;refresh会重新定位该引用(参见 Refresh)。 当分组包含某个文件的所有有效代码块时,hunkRefs条目是路径字符串。请从草稿中复制路径。以/结尾的路径包含该目录下所有未被其他引用指定的有效代码块:最具体的引用优先。对于一组机械性文件(其中至少一半是纯重命名),摘要会为该目录打印一行;草稿会将其作为一个引用收录,而该行下方列出的文件已包含在其中。若要将其中某个文件移到对应的说明分组,请将其路径放入该分组;目录引用会因此放开该文件。若目录引用仍包含非机械性文件,validate会失败。当一个文件被拆分到多个分组时,请将每个代码块命名为path@oldStart+newStart;如果该代码块是重命名,则命名为old/path -> new/path@oldStart+newStart。请从摘要行(hunks: path@oldStart+newStart)或show输出的@@ -oldStart,oldLines +newStart,newLines @@标头中复制oldStart和newStart。标识由(path, oldStart, newStart)构成;若为重命名,还包括oldPath。图片文件使用路径。
lookFor
lookFor 用于记录细心的工程师初次阅读当前差异时容易遗漏的内容。默认将 lookFor 留空,每条要点都必须通过一次抓取来佐证:只有在你对其代码块运行了 show,或摘要与来源已能证明时,才能添加要点。每条要点只陈述一个发现,并以事实陈述,且在当前 head 上为真:可选地添加简短的风险标签(Subtle、Breaking、Race、Perf),然后用一句话说明当前 head 上的代码会做什么,以及读者会观察到什么。人工审核者会对照当前差异检查并保留结论。不得写伪代码、图示、折叠差异、提交列表、代码块数量或通过/失败标记。
分组中的 lookFor 用于记录这些代码块中的行为。若代码块隐藏了行为变化,请抓取该代码块并写出预测到的执行轨迹:给出一个小型的实际输入,说明新旧路径从何处分歧,以及可观察到的结果。以下情况值得添加要点:
- 相等性或标识的变化(对象字段与原始类型字段、指针与内容):两个看似相同的输入如今会得到不同的比较结果。
- 为适配应用行为而加入的代码块(休眠、强制写入、重试):说明没有该变通措施时应用会如何表现。
- PR 的来源材料与测试、CI 或工具相关,但代码块位于应用源码下:这是测试 PR 中的生产代码;请指出其行为变化。
- 设置或清理脚本会删除或覆盖非测试输出文件:说明路径、发生时机,以及开发者会丢失什么。
- 来源材料未提及的行为变化。
- 以代码块本身不明显的方式解决评审意见的代码块:说明修复的作用。
重命名、格式调整或仅措辞变更的文档分组,留空才是正确做法。草稿中的 mirrors-<n> 和 mechanical 分组应保持为空,除非抓取结果证明并非如此。
文档级 lookFor 用于记录关于整体变更及来源材料与当前 head 代码之间差异的主张。来源条目包括:工单中的每项需求和验收项、拉取请求说明和提交消息中的每项行为主张,以及评审意见中的每项请求。测试计划、手动 QA 备注和范围外事项属于上下文,不算条目。请阅读每项来源并给出判定:按要求完成、以不同方式完成、未完成或在当前 head 上不成立。除“按要求完成”之外,每种判定都要作为一条要点:说明来源的要求或主张、摘要或已抓取的代码块所显示的内容,以及来源或代码给出的原因;如果两者都未给出原因,也请说明。当较晚的来源改变了较早来源的要求(例如评审意见覆盖工单要求),工单条目应判定为“以不同方式完成”,且要点需同时指出两个来源。来源指出变更所需的手动步骤(例如启用设置、运行迁移)时,也应作为一条要点。使用 [text](source:s1) 引用;该 ID 必须列在 sources 中,且 validate 会在 ID 未知时失败。若无需添加要点,则省略该字段。
撰写说明文案
文档的 title、文档的 why、分组的 why、summary 和 lookFor,都是为初次阅读的疲惫工程师准备的。
- 每句话只表达一个想法;超过 25 个词左右就拆开。
- 使用现在时。明确说明谁做什么。
- 使用真实的符号、路径、标志或命令。
- 删掉所有无用的词。不要写成更新日志的口吻,不要自我吹嘘,也不要写「不只是 X,而是 Y」。
- 简单明了的分组只需标题、
why和summary;实时差异会说明其余内容。