必须用git diff配合结构化筛选,因直接看composer.lock的JSON差异易淹没在数百行中;应聚焦包名、版本、源类型三类字段,可用grep或专用工具composer-lock-diff精准识别增删改及不稳定引用。

composer.lock 变更必须用 git diff 配合结构化筛选
只看 git diff composer.lock 会淹没在几百行 JSON 中,真正要关注的是包名、版本、源类型三类字段。直接执行下面命令能快速定位有效变更:
-
git diff --no-color HEAD~1 composer.lock | grep -E '^\+ {4}"(name|version|source|type|reference)"'—— 筛出新增/修改的包名、版本号、源类型("type": "git"比"type": "package"更需警惕) - 发现
"version": "dev-main"或"reference": "abc123"→ 指向不稳定分支或特定 commit,必须确认是否必要 - 同一包出现多个版本(如
symfony/event-dispatcher同时存在6.3.2和7.0.0)→ 是依赖冲突信号,Composer 已做降级处理,需人工干预
用 composer-lock-diff 替代手写 grep 命令
composer-lock-diff 是专为这个场景设计的工具,它自动比对当前 composer.lock 和 Git HEAD 的差异,并按包分组展示增删改,不依赖 shell 技巧,也不怕 JSON 格式换行错乱。
- 安装:
composer global require davidrjonas/composer-lock-diff:^1.0,Zsh 用户记得rehash - 使用:
composer update && composer-lock-diff,输出清晰标出哪些包升了、降了、新增或移除 - 注意:它默认只比对
packages,若项目上线用--no-dev,但你想监控require-dev变更,得先手动切到含packages-dev的 commit 再运行
为什么不能只看 composer.json 的增删
composer.json 里没动,不代表依赖没变——composer.lock 才是运行时真实依赖清单。常见误判场景:
- PR 中
composer.json零改动,composer.lock却有 300 行变更 → 很可能是 CI 自动执行了composer update,必须追问触发原因 - 新增一个包,
composer.lock里却带进 5 个子依赖,其中guzzlehttp/psr7升到2.6.0→ 这个版本含已知 CVE,但composer.json完全不体现 -
content-hash字段变了 → 说明依赖图确实不同;没变 → 大概率只是 lock 文件重生成,无实质风险
检查 vendor 实际文件是否被篡改
composer status 是唯一能告诉你 vendor 里哪些包“被手改过”的命令,但它默认只校验 Git 包,且不报 dist 包问题。
- 基础扫描:
composer status→ 快速看到标 “modified” 的包 - 深度排查:
composer status -v→ 对 Git 包显示git status --porcelain输出(如M src/Helper.php),对 dist 包则比对dist.shasum - 注意:IDE 自动生成的
.idea/或测试产生的vendor/bin/.phpunit也会被识别为 modified,需结合git status --ignored=matching -s vendor/排查真实文件变更
composer update。有人手动改了 vendor/ 里的代码、有人用 path 类型仓库指向本地修改版、还有人用 post-install-cmd 脚本动态打 patch——这些都不会体现在 composer.lock 的 diff 里,但会影响运行结果。


















