composer 默认解压 zip 包而非克隆 git 仓库,--prefer-source 可强制尝试 git 克隆,但需包支持 source、本地有 git 且网络可达;加 --keep-vcs 才保留 .git 目录,否则仍被清除。

composer install 和 composer update 都不下载源码,只解压
Composer 默认行为是把包的 ZIP 包下载到 vendor/composer/archives/,再解压进 vendor/。你看到的 vendor/foo/bar 是解压后的文件,不是原始 Git 仓库或完整源码树——比如缺失 .git/、tests/(如果没被 autoload-dev 包含)、CHANGELOG.md 等非运行必需文件。
想“一键下载所有包的源代码(非压缩)”,本质是让 Composer 放弃 ZIP 模式,全部走 Git 克隆。这只有在满足以下条件时才可行:
- 所有包都托管在支持 Git 的仓库(GitHub/GitLab/自建 Git),且
composer.json中指定了source类型(而非dist) - 你的
composer.json显式禁用了dist,并强制启用source - 本地装了
git命令,且网络能直连各仓库(无代理/防火墙拦截)
用 --prefer-source 强制走 Git 克隆
--prefer-source 是唯一接近“一键下载源码”的开关。它会让 Composer 对每个包尝试从 source(Git)安装,失败再回落到 dist(ZIP)。注意:它不会“保证全部成功”,尤其对私有包或配置不全的包容易失败。
实操建议:
- 运行
composer install --prefer-source(已有composer.lock)或composer update --prefer-source(刷新依赖) - 加
-v查看每步来源:Cloning 123abcde from https://github.com/foo/bar.git表示走 Git;Downloading https://api.github.com/.../archive/refs/tags/v1.2.3.zip表示 fallback 到 ZIP - 若某包始终 fallback,检查其
composer.json是否定义了"source"字段(如"url": "https://github.com/foo/bar.git"),没有就只能靠 ZIP
为什么 vendor 里还是看不到 .git 目录?
即使 --prefer-source 成功克隆,Composer 默认会执行 git clone --no-checkout + git checkout -qf <commit></commit>,然后删掉 .git 目录(为节省空间、避免污染部署环境)。所以你看到的是干净工作区,不是完整克隆体。
要保留 .git,必须手动干预:
- 设置环境变量:
COMPOSER_DISCARD_CHANGES=0(防止 Composer 清理变更) - 但关键一步是:加
--keep-vcs参数,例如composer install --prefer-source --keep-vcs - 注意副作用:所有
vendor/下的包都会带.git/,体积翻倍,且composer update时可能因本地修改冲突失败
私有包、Satis 或 Artifactory 场景下 source 不可用
如果你用的是私有 Packagist(如 Satis、Artifactory)、或包只发布了 dist(ZIP)而没配 source,--prefer-source 会直接报错:Source is not available for package foo/bar。这时候没有“一键”办法。
替代路径有限:
- 联系包维护者,在其
composer.json中补全"source"字段并重发版本 - 自己 fork 后改
composer.json,然后在repositories中指向你的 fork(需维护同步) - 接受 ZIP 解压结果 —— 它已是“源代码”,只是不含 VCS 元数据和非 autoload 文件
真正需要深度阅读(比如看测试用例、历史提交、CI 配置),直接去 GitHub 页面看,比折腾 vendor/ 更可靠。Composer 的设计目标从来不是提供源码镜像,而是可复现的依赖快照。










