更新日志必须包含操作命令、目标包与版本范围、触发原因三要素,否则无法追溯是安全补丁、主版本迁移还是误操作;跨主版本升级须标注[breaking]并附检查清单。

更新日志不是可选项,而是故障回溯的唯一依据;不记录具体包名、版本号和更新方式,等于没记。
为什么 composer update 不该直接进 Git 提交记录
直接提交 composer.lock 变更而不附带说明,会导致后续排查时完全无法判断:这次升级是安全补丁?主版本迁移?还是某人误操作?composer update 本身不带上下文,Git diff 只显示哈希值变化,看不出动机。
- 团队协作中,别人看到 lock 文件变动,第一反应是“谁动了依赖?”而不是“为什么动”
- CI/CD 流水线失败时,仅靠 lock 文件无法快速定位是否因
guzzlehttp/guzzle从 7.8 升到 7.9 引起 - PHP 版本升级后,必须确认所有包都满足新约束——但 lock 文件里没有 PHP 要求变更的痕迹
每次更新必须写明的三要素
一条有效的更新日志不是“升级了依赖”,而是能被机器解析、被人一眼看懂的结构化记录。核心字段缺一不可:
-
操作命令:例如
composer update guzzlehttp/guzzle --with-all-dependencies(不是composer update) -
目标包与版本范围:例如
"guzzlehttp/guzzle": "^7.8"→"^7.9",或明确写出从7.8.1升到7.9.0 -
触发原因:例如 “修复 CVE-2026-12345”、“适配 Laravel 11 要求
symfony/http-foundation ^7.2”
推荐格式:update guzzlehttp/guzzle ^7.8 → ^7.9 (CVE-2026-12345),直接作为 commit message 或 CHANGELOG.md 条目。
如何自动化提取这些信息
手动抄写容易漏、易错。用脚本辅助生成日志条目,比靠自觉靠谱得多:
- 更新前先运行
composer show guzzlehttp/guzzle记下当前版本,再执行composer update guzzlehttp/guzzle --dry-run看将升到哪版 - 更新后立刻跑
git diff composer.lock | grep -A5 -B5 'guzzlehttp/guzzle',快速定位变更行 - 把常用命令封装成 alias,例如:
alias cu-log='composer update --dry-run | head -20 && echo "↑ copy above, then run real update"'
注意:--dry-run 不会改 lock 文件,但能预览子依赖连带升级情况——比如 guzzlehttp/guzzle 升级可能触发 psr/http-client 从 1.0.3 到 1.1.0,这个必须记进日志。
跨主版本升级的日志要单独标记
主版本跳变(如 "laravel/framework": "^10.0" → "^11.0")不是普通更新,它意味着 API 废弃、配置重写、第三方包兼容性重检。这类操作必须:
- 在日志开头加
[BREAKING]标识,例如:[BREAKING] update laravel/framework ^10.0 → ^11.0 (PHP ≥ 8.2 required) - 附带检查清单:是否已改
php约束?是否删了config/app.php中废弃的'providers'数组项?是否运行过php artisan vendor:publish --tag=laravel-assets? - 禁止和日常小版本更新混在同一次 commit;否则 review 时极易忽略破坏性变更
最容易被忽略的是:升级后未清 Laravel 配置缓存,导致新配置不生效,却误判为“升级失败”。日志里写一句“✅ cleared config & view cache”比事后 debug 两小时强得多。











