prefer-source 是 composer 安装包时克隆 git 仓库而非下载 zip 归档的行为,保留完整 git 历史,仅适用于本地开发调试;ci/cd、docker 构建及线上部署必须禁用,以防拉取慢、体积大及元数据泄露风险。

prefer-source 是什么行为
它让 Composer 在安装包时,不下载预编译的 .zip 归档,而是直接克隆 Git 仓库(比如 GitHub 上的源码),保留完整的 Git 历史和工作区。这本质是开发态行为,不是部署态默认选项。
常见错误现象:composer install 后发现 vendor/foo/bar 里有 .git 目录,但线上服务器报错“权限不足”或 CI 构建变慢——说明误把开发配置带进了生产环境。
- 仅在本地开发、需要调试依赖源码、或要 patch 第三方库时启用
- CI/CD 流水线、Docker 构建、线上部署必须禁用(否则拉取慢、体积大、Git 元数据暴露风险)
- 该行为由
config.prefer-source控制,全局或项目级生效
怎么开启或关闭 prefer-source
它不是命令行开关,而是配置项,需显式写入 composer.json 或通过 composer config 设置。
使用场景:你刚 fork 了一个包,想本地改完直接测试,又不想发 PR 前先 publish 到 packagist。
- 项目级启用:
composer config prefer-source true(写入当前项目的composer.json的config段) - 全局禁用(推荐 CI 前执行):
composer config --global prefer-source false - 临时覆盖(单次命令):
composer install --prefer-source或--prefer-dist,但注意这不改变配置文件
prefer-source 和 prefer-dist 的实际差异
差异不止是“源码 vs zip”,还影响锁定、更新逻辑和网络行为。
参数差异:prefer-source 会强制走 Git 协议(https:// 或 git@),而 prefer-dist 优先走 CDN 加速的 .zip 包(由 packagist.org 提供)。
-
prefer-source下,composer update会执行git fetch+git checkout,可能因分支重写失败;prefer-dist则只校验 SHA256,更稳定 - 某些私有包没配 Git 镜像地址时,
prefer-source会直接失败,报错类似Failed to clone https://xxx.git, git was not found - PHP 扩展如
ext-zip缺失时,prefer-dist会 fallback 到prefer-source,但不会提示——容易误以为是网络问题
为什么 vendor 里突然多了 .git 目录
这不是 bug,是 prefer-source 的必然结果。只要某次安装用了源码模式,对应目录就会带完整 Git 工作区。
容易踩的坑:你删了 vendor 重装,却忘了检查当前配置,或者同事提交了带 "prefer-source": true 的 composer.json,导致团队行为不一致。
- 查当前生效配置:
composer config --list | grep prefer - 确认某包是否以 source 方式安装:
ls -la vendor/foo/bar/.git - Docker 构建中务必加一句:
RUN composer config --global prefer-source false,避免继承宿主机配置
Git 工作区的存在本身不危险,但会让 git status 在项目根目录下意外显示 vendor 变更,也会让某些扫描工具误报“敏感文件泄露”。这事关习惯,不难,但得记得它存在。










