解释这个 PR
读取一个 GitHub Pull Request,理解它改变了什么,然后写一段纯英文解释。将其作为 PR 评论发布,让审查者立刻了解上下文。
第 1 步:检查设置
确认 gh 已认证:
gh auth status
如果未认证:执行 gh auth login 并按照提示操作。
确认输入。用户必须提供以下之一:
- 一个 GitHub PR URL(例如
https://github.com/owner/repo/pull/123) - 当前仓库中的 PR 编号(例如
#123) - 关键词 "current",用于使用当前分支的 PR
如果没有输入,询问:“我应该解释哪个 PR?请分享 URL、PR 编号,或说 'current' 表示当前分支。”
第 2 步:获取 PR 上下文
获取 PR 元数据:
gh pr view PR_URL_OR_NUMBER --json number,url,title,body,author,baseRefName,headRefName,additions,deletions,changedFiles,commits,labels,state,isDraft
如果 isDraft 为 true,向用户说明:“此 PR 仍处于草稿状态。解释基于其当前状态。”
获取差异:
gh pr diff PR_URL_OR_NUMBER
如果差异超过 400 行,读取 --stat 摘要和差异的前 200 行:
gh pr view PR_URL_OR_NUMBER --json files
gh pr diff PR_URL_OR_NUMBER | head -200
获取现有评论(避免重复已有的内容):
gh pr view PR_URL_OR_NUMBER --json comments --jq '.comments[].body' 2>/dev/null | head -20
第 3 步:编写解释
写两段话。在写之前阅读每条规则。
第 1 段:它做了什么(技术方面)
- 每个主要更改用一个句子描述
- 指出发生更改的具体文件、函数或系统
- 如果差异中明确,说明变化前后的状态
- 如果差异中出现了具体数字,请包含这些数字(删除的行数、删除的表、添加的端点)
- 使用主动语态、现在时
示例:
将 auth.middleware.ts 中的内存会话缓存替换为基于 Redis 的缓存(src/cache/redis.ts)。向新的 Redis 模块添加 get、set 和 invalidate 方法,并为 UserService.getById() 包装了 5 分钟的 TTL。移除了仅限于单个进程并导致跨多个实例会话漂移的基于 Map 的缓存。
第 2 段:为什么重要(业务/产品影响)
- 谁受益,如何受益
- 解决了什么问题或降低了什么风险
- 如果提交消息中包含“为什么”,请使用该上下文
- 如果差异或提交中没有明确的“为什么”,请省略此段,而不是猜测
示例:
在负载下访问 /api/me 端点的用户会跨服务器实例获得不一致的会话数据,导致间歇性的 401 错误。此更改使会话状态在所有实例中保持一致,并通过消除每个身份验证请求的一个查询来减少数据库负载。
两段的规则:
- 不要使用破折号——改用逗号或句号
- 不要用填充词:“这个 PR”、“这个更改”、“可以看到”
- 不要编造结果。只陈述在差异或提交消息中能直接看到的影响
- 如果 PR 是纯重构且没有行为变化,则明确说明:“将 X 重构为 Y,观察到的行为没有变化。”
- 总字数少于 150 字
第 4 步:自我质量检查
在发布之前,请检查:
- 第 1 段指出了差异中的具体文件或函数
- 没有编造的指标或结果
- 没有破折号
- 没有填充短语
- 总字数少于 150 字
- 如果没有明确的“为什么”,则省略第 2 段而非猜测
在发布前修正任何违规。
第 5 步:作为 PR 评论发布
向用户展示解释。询问:“准备好将此作为 PR 评论发布,还是您想先编辑它?”
确认后,通过标准输入传递正文,以安全处理反引号、引号和换行符:
gn pr comment PR_URL_OR_NUMBER --body-file - << 'EOF'
EXPLANATION_HERE
EOF
发布后:“评论已添加。查看地址:[第 2 步中的 URL]”
如果用户说“仅输出”,则将解释放在一个代码块中供手动复制粘贴,而不进行发布。