最可靠方式是直接比对两个composer.lock文件;因composer show输出受排序、终端宽度、ansi颜色等干扰,且不带--locked会混入dev包或本地repo,无法准确反映依赖图谱变化。

直接比对两个 composer.lock 文件是最可靠、最贴近真实安装行为的差异方式;用 composer show --locked 或树形输出做对比,容易因排序、颜色、缩进等干扰导致误判。
为什么不能只用 composer show 对比依赖列表
它默认按字母序或深度优先输出,终端宽度不同会导致换行错位;不加 --locked 会混入 require-dev 中未安装的包或本地 path repo;加了 --no-ansi 和 | sort 也只能用于单包子依赖扁平化比对,无法反映整个图谱结构变化。
-
composer show monolog/monolog --tree只显示该包及其直系依赖,漏掉其他根依赖的变动 - 输出中包含 ANSI 颜色码(即使关了也偶发残留),
diff会把颜色字符当内容差异 - 没有哈希校验字段,看不出某包虽版本未变但 dist 包实际内容已更新(如 patch 重发)
用 composer show --locked --format=json + jq -S 生成可比快照
这是目前最稳定、可复现、带完整元数据(版本、源类型、dist hash、source commit 等)的导出方式。JSON 格式天然规避排序/换行问题,jq -S 强制键名排序,确保两次导出结构一致。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 更新前:运行
composer show --locked --format=json > composer.lock.before.json - 更新后:运行
composer show --locked --format=json > composer.lock.after.json - 格式化并比对:
jq -S . composer.lock.before.json > before.json && jq -S . composer.lock.after.json > after.json && diff before.json after.json - 注意:别用
composer show不带--locked,它读的是当前vendor/状态,可能含未提交的本地修改或 dev-only 包
用 composer-lock-diff 快速看人类可读变更
它专为这个场景设计,跳过 JSON 解析,直接解析 lock 文件结构,输出「新增」「删除」「升级」「降级」四类变更,并标出是否影响自动加载(autoload change)。
- 全局安装:
composer global require clue/composer-lock-diff,确保~/.composer/vendor/bin在$PATH中 - 备份旧 lock:
cp composer.lock composer.lock.bak,再执行composer update - 运行:
composer-lock-diff composer.lock.bak composer.lock - CI 场景下可直接从 Git 历史读取:
git show HEAD~1:composer.lock | composer-lock-diff - composer.lock - 它不依赖 vendor 目录存在,也不需要 PHP 运行时环境,纯静态分析 lock 文件
哪些差异其实不重要,但容易被误读
composer.lock 里有些字段变动并不影响运行时行为,比如 packages-dev 的顺序、content-hash 更新、某些包的 type 字段微调(如 library ↔ metapackage)。真正要盯的是 name、version、dist/sha256、source/reference、autoload 这几项。
-
content-hash变了 ≠ 依赖变了,只是composer.json内容有空格/注释等无关修改 -
packages-dev里phpunit/phpunit升级了,但你的测试没跑或没覆盖到新行为,就未必触发问题——得结合composer status -v和测试结果交叉判断 - 如果某包从
dist切到source(或反之),dist/sha256和source/reference会同时出现或消失,这不是 bug,是安装策略变更
真正难定位的是那种「版本号没变、但 dist 包被重新打包」的情况——比如 maintainer 修复了一个 bug 后重发了同版本 zip,此时只有 dist/sha256 变,composer status 不报 modified(因为没 git 仓库),但你的代码行为可能已变。这种必须靠 CI 中固定 checksum 校验或人工核对 release note。










