composer status 列出 vendor/ 中被修改的包内文件,格式为“包名: 修改的文件路径”;它比对安装时的原始快照(zip 或 Git commit),跳过 path 类型包、无 .git 目录的源码包及自动生成文件。

composer status 会列出哪些文件?
composer status 的作用是比对 vendor/ 目录下已安装的包与它们原始压缩包(或 Git commit)的文件差异。它只检查那些通过 Composer 安装的、有明确源码来源的包(比如从 packagist.org 下载的 zip,或克隆的 Git 仓库),不检查手动放入 vendor/ 的文件、软链接目录,也不检查 composer install --no-dev 后被删掉的 dev 包。
默认行为是静默的:如果没修改,什么也不输出;一旦发现差异,就逐行打印形如 package-name: modified file path 的结果。
为什么 status 没输出,但我知道 vendor 里有改动?
常见原因包括:
-
vendor/下某个包是用path类型仓库引入的(比如"repositories": [{"type": "path", "url": "../my-local-package"}]),composer status会跳过这类本地路径包,因为没有“原始快照”可比 - 该包安装时用了
--prefer-source,但后来你删了.git目录,导致 Composer 无法读取 HEAD 或比对 commit —— 此时它会直接忽略整个包 - 你改的是
vendor/autoload.php或vendor/composer/下的自动生成文件,这些不属于任何包的源码,status不管 - 使用了
composer install --no-scripts或禁用了钩子,某些包可能跳过了标准初始化流程,状态检测失效
如何让 status 显示更详细的信息?
加 -v(verbose)参数可看到每一步在检查哪个包,以及跳过的原因:
composer status -v
加 --verbose(等价于 -vvv)还能显示底层执行的 git status 或 diff 命令,适合排查为什么某包没被检测到。
如果只想看特定包,直接指定包名:
composer status monolog/monolog
注意:包名必须和 composer.json 中声明的一致,大小写敏感,且不能带 v 前缀(例如写 phpunit/phpunit,而不是 v9.6.13)。
status 和 git status 在 vendor 里的区别
composer status 是语义级检查:它依赖 Composer 自己记录的安装元数据(vendor/composer/installed.json 和各包下的 composer.lock 快照),判断“这个文件是否偏离了当初安装时的样子”。而 git status 进入某个 vendor/package 目录后,只反映当前 Git 工作区状态,跟 Composer 无关。
典型冲突场景:
- 你用
git checkout切换了vendor/package的分支,git status显示 clean,但composer status仍报 modified —— 因为 Composer 记录的原始 commit 和当前 HEAD 不一致 - 你删了
vendor/package/.git,git status失效,但composer status可能转为基于 zip 校验(如果当初是 zip 安装),依然有效
真正可靠的判断依据,始终是 composer status 输出的内容,不是 git 或文件系统时间戳。










