composer status 列出 vendor/ 中被手动修改但未提交或打补丁的第三方包文件,如 symfony/console: src/Command/Command.php,并比对 composer.lock 中记录的原始 commit hash 或 checksum。

composer status 会列出哪些被修改的包
composer status 的核心作用是扫描 vendor/ 下已安装的包,比对当前文件内容与该包在 composer.lock 中记录的原始 commit hash(或 dist zip checksum),找出被手动改过、未提交、未打补丁的本地变更。
它不检查你自己的项目代码,只关注 vendor 里第三方包的“纯净度”。常见触发场景包括:调试时直接改了 vendor/symfony/console/Command.php、加了 var_dump()、临时注释掉某行逻辑。
输出格式通常是:Package name: files modified (list),例如:
symfony/console: src/Command/Command.php, src/Output/OutputInterface.php
为什么 status 不报错但实际已破坏可复现性
这个命令默认静默成功(退出码 0),即使发现修改也不会中断流程——它只是“告知”,不是“校验失败”。这点容易让人误以为“没报错=没问题”,但其实只要有一个包被改过,composer install 在其他机器上就无法还原出完全一致的 vendor 状态。
关键影响包括:
-
composer update可能跳过该包的更新(Composer 认为“本地有改动,先保留”) - CI 环境因无修改而通过,但开发机行为已和线上不一致
-
git diff vendor/被忽略后,这些修改可能意外提交到私有仓库
配合 --verbose 或 --dry-run 定位真实问题
composer status 本身不提供修复能力,但加参数能帮你判断严重程度:
-
composer status --verbose:显示每个被修改包对应的预期 commit hash 和当前实际 hash,方便核对是否只是文档/测试文件改动 -
composer status --dry-run:不会真正扫描,仅检查配置是否有效(极少用,基本可忽略) - 更实用的是组合:
composer status | grep -v "No local changes"快速过滤出真有问题的包
注意:status 对使用 path repository 的本地包无效——它跳过这类包,因为本来就不走 git/dist 校验。
替代方案:用 git 检查 vendor 更可靠
Composer 的 status 依赖 lock 文件完整性,一旦 lock 被手改或不同步,结果就不可信。更底层、更稳的方式是直接用 git:
- 进入某个包目录:
cd vendor/react/promise - 运行:
git status --porcelain,看是否有M(modified)、??(untracked) - 批量检查(需 bash/zsh):
find vendor/ -mindepth 2 -maxdepth 2 -name '.git' -exec dirname {} \; | while read d; do echo "== $d =="; cd "$d" && git status --porcelain | head -3; cd - >/dev/null; done
这能绕过 Composer 解析逻辑,直接看到 git 认为的脏状态,尤其适合 CI 中做强校验。
真正麻烦的不是 status 找不到修改,而是它找到了却没人处理——比如团队中有人长期靠改 vendor 走捷径,而 status 输出被当成“已知问题”忽略。这种技术债积累起来,比任何命令都难清理。










