名称:changelog 描述:从两个引用(标签、提交或分支)之间的git历史中生成变更日志或发布笔记。适用于准备发布、总结变更或创建发布笔记时使用。关键词:changelog, release notes, release, changes, what changed, version, tag, diff, history, summary 上下文:fork 代理:Explore 禁用模型调用:true 参数提示:[from-ref] [to-ref] 允许的工具:Read, Grep, Glob, Bash(git *)
变更日志生成器
从两个引用之间的git历史中生成结构化发布笔记。按类型分类提交,读取重要更改的差异,并输出常规变更日志。
何时使用
- 准备新发布时需要发布笔记
- 总结两个标签或提交之间的变更
- 为版本升级创建CHANGELOG.md条目
- 审查自上次部署以来发布的内容
工作流程
1. 确定引用范围
解析$ARGUMENTS中的from-ref和to-ref。处理以下情况:
提供两个参数(例如,/changelog v1.2.0 v1.3.0):
FROM_REF="$1" # 例如,v1.2.0
TO_REF="$2" # 例如,v1.3.0
提供一个参数(例如,/changelog v1.2.0):
FROM_REF="$1" # 例如,v1.2.0
TO_REF="HEAD"
未提供参数(例如,/changelog):
# 自动检测:最新标签到HEAD
FROM_REF=$(git describe --tags --abbrev=0 2>/dev/null)
TO_REF="HEAD"
# 如果没有标签存在,使用第一个提交
if [ -z "$FROM_REF" ]; then
FROM_REF=$(git rev-list --max-parents=0 HEAD)
fi
验证引用存在:
git rev-parse --verify "$FROM_REF" >/dev/null 2>&1 || echo "ERROR: $FROM_REF is not a valid ref"
git rev-parse --verify "$TO_REF" >/dev/null 2>&1 || echo "ERROR: $TO_REF is not a valid ref"
2. 收集提交历史
# 完整提交列表,带哈希值
git log --oneline "$FROM_REF".."$TO_REF"
# 包含作者和日期上下文
git log --format="%h %s (%an, %ad)" --date=short "$FROM_REF".."$TO_REF"
# 统计摘要
git diff --stat "$FROM_REF".."$TO_REF"
# 贡献者数量
git log --format="%an" "$FROM_REF".."$TO_REF" | sort -u
3. 分类提交
解析每个提交消息,使用常规提交前缀分类:
| 类别 | 前缀 | 优先级 |
|---|---|---|
| 破坏性变更 | BREAKING CHANGE, breaking:, !: |
1(始终首位) |
| 功能 | feat:, add:, feature: |
2 |
| 错误修复 | fix:, bugfix:, bug: |
3 |
| 性能 | perf:, performance: |
4 |
| 文档 | docs:, doc: |
5 |
| 重构 | refactor:, refact: |
6 |
| 测试 | test:, tests: |
7 |
| 构建/CI | ci:, build:, chore: |
8 |
| 其他 | 任何不匹配的 | 9 |
对于没有常规前缀的提交,读取提交消息正文和差异以推断类别:
# 为模糊提交读取完整提交消息和差异
git show --stat <hash>
git show <hash> -- '*.rs' '*.ts' '*.py' '*.go' # 过滤源文件
4. 丰富重要变更
对于标记为功能或破坏性变更的提交,读取实际差异以编写比提交消息更好的摘要:
# 读取重要提交的差异
git show <hash> --stat
git diff <hash>~1..<hash> -- '*.rs' '*.ts' '*.py' '*.go' '*.js' '*.java'
编写一行人类可读的摘要,描述用户看到的变更,而非实现细节。
好:“添加批量导出用户数据为CSV” 差:“向UserService添加exportUsers函数”
5. 检测版本和日期
# 如果TO_REF是标签,从中提取版本
VERSION=$(echo "$TO_REF" | sed 's/^v//')
# 如果TO_REF是HEAD,标记为未发布
if [ "$TO_REF" = "HEAD" ]; then
VERSION="Unreleased"
fi
# 获取TO_REF的日期
DATE=$(git log -1 --format="%ad" --date=short "$TO_REF")
6. 生成变更日志
使用常规变更日志格式输出:
## [版本] - YYYY-MM-DD
### 破坏性变更
- 破坏性变更描述([`abcdef1`](commit-url))
- **迁移**:如何更新现有代码/配置
### 功能
- 功能描述([`abcdef2`](commit-url))
- 功能描述([`abcdef3`](commit-url))
### 错误修复
- 修复描述([`abcdef4`](commit-url))
### 性能
- 改进描述([`abcdef5`](commit-url))
### 文档
- 文档变更描述([`abcdef6`](commit-url))
### 内部
- 重构、测试、CI变更([`abcdef7`](commit-url))
---
**完整差异**:[`FROM_REF...TO_REF`](compare-url)
**贡献者**:@author1, @author2, @author3
输出规则:
- 省略空类别(如果没有,不显示“### 性能”)
- 破坏性变更始终首位,带迁移注释
- 每个条目一行,带短提交哈希链接
- 如果相关提交属于同一逻辑变更,分组处理
- 底部包含“完整差异”链接,使用GitHub比较URL格式
- 列出贡献者
7. 构建URL(如果存在GitHub远程)
# 检测GitHub远程
REMOTE_URL=$(git remote get-url origin 2>/dev/null | sed 's/\.git$//' | sed 's|git@github.com:|https://github.com/|')
# 提交URL模式
# ${REMOTE_URL}/commit/${HASH}
# 比较URL
# ${REMOTE_URL}/compare/${FROM_REF}...${TO_REF}
如果无GitHub远程,使用纯哈希,不带链接。
8. 输出
打印变更日志到标准输出。用户可随后:
- 复制到CHANGELOG.md
- 用作GitHub发布笔记
- 包含在PR描述中
处理边界情况
合并提交:跳过合并提交,除非它们代表有意义的压缩合并:
git log --no-merges --oneline "$FROM_REF".."$TO_REF"
Monorepo / 作用域变更:如果用户指定路径,限制日志范围:
git log --oneline "$FROM_REF".."$TO_REF" -- path/to/package/
无常规提交:如果仓库未使用常规提交,通过读取差异分类。按代码库区域而非类型分组。
非常大的范围(100+提交):将次要变更(文档、杂务、重构)汇总为单行每个。专注于功能和破坏性变更的细节。
示例调用
两个标签之间:
/changelog v2.0.0 v2.1.0
自上次标签到现在:
/changelog
自特定提交:
/changelog abc1234 HEAD
作用域到路径(参数中提及):
/changelog v1.0.0 v2.0.0 -- packages/api
示例输出
## [2.1.0] - 2025-03-15
### 功能
- 添加批量用户导出为CSV下载([`a1b2c3d`](https://github.com/org/repo/commit/a1b2c3d))
- 在设置面板支持暗黑模式([`e4f5g6h`](https://github.com/org/repo/commit/e4f5g6h))
### 错误修复
- 修复webhook交付中的竞争条件导致重复事件([`i7j8k9l`](https://github.com/org/repo/commit/i7j8k9l))
- 修正计划报告时区处理([`m0n1o2p`](https://github.com/org/repo/commit/m0n1o2p))
### 性能
- 缓存用户权限查找,减少p99延迟40%([`q3r4s5t`](https://github.com/org/repo/commit/q3r4s5t))
### 内部
- 从CircleCI迁移到GitHub Actions([`u6v7w8x`](https://github.com/org/repo/commit/u6v7w8x))
- 更新依赖项([`y9z0a1b`](https://github.com/org/repo/commit/y9z0a1b))
---
**完整差异**:[`v2.0.0...v2.1.0`](https://github.com/org/repo/compare/v2.0.0...v2.1.0)
**贡献者**:@alice, @bob, @charlie