必须加 --prefer-source 的场景包括:①修改依赖代码或本地调试需断点进 vendor 类;②基于依赖提交 pr;③查看 commit 历史(如 git log -p);④依赖仅提供 dev-main 等开发分支;⑤ci/cd 需静态分析且依赖 git 元数据。

用 --prefer-source 安装包,本质是让 Composer 放弃下载 zip 包,改用 git clone 拉取源码 —— 这对开发调试、打 patch、看 commit 历史很关键,但不是所有场景都该开。
什么时候必须加 --prefer-source
你正在改一个依赖的代码,或者需要在本地直接调试它的逻辑(比如断点进 vendor 里的某个类),又或者要基于它提交 PR,这时候必须用源码模式。否则 vendor 下只有压缩包解出来的文件,没 .git 目录,没法 git diff、没法 git checkout 切分支、也没法 git push。
- 本地开发中要修改依赖并测试效果
- 想快速查看某包某次 commit 的具体变更(
git log -p) - 依赖本身没有发布稳定版 tag,只靠
dev-main这类开发分支提供功能 - CI/CD 中需对依赖做静态分析或 lint(某些工具依赖 git 元数据)
--prefer-source 和 --prefer-dist 的实际差异
默认情况下 Composer 优先走 --prefer-dist:从 packagist.org 或镜像下载预打包的 zip/tar.gz,速度快、占空间小、无 git 历史。而 --prefer-source 强制走 git 克隆,哪怕包有 dist 包也忽略。
- 克隆后
vendor/foo/bar下会有完整的.git目录,可自由操作 - 首次安装慢(尤其大包如
symfony/symfony),后续composer update会走git fetch+git reset --hard,比重下 zip 稍快但不明显 - 某些私有 GitLab/GitHub 私仓若未配好 SSH key 或 token,
--prefer-source会直接报Cloning into ... Permission denied - 如果包的
composer.json里写了"source": { "url": "...", "type": "git" },那--prefer-source才生效;纯 zip-only 包(比如部分老旧 PEAR 风格包)即使加了参数也 fallback 回 dist
怎么安全地全局或局部启用
别盲目全局设,容易拖慢团队协作或 CI 构建。推荐按需启用,且优先写进 composer.json 而非命令行。
- 单次安装:运行
composer require foo/bar --prefer-source或composer install --prefer-source - 项目级默认:在
composer.json根对象加"config": { "preferred-install": "source" },这样所有依赖都走源码(慎用) - 只对特定包强制源码:用
"repositories"重写该包来源,例如指定其type: "vcs"+url指向 git 地址,比全局--prefer-source更精准 - CI 中建议显式禁用:
composer install --no-interaction --prefer-dist,避免因网络或权限问题中断构建
常见报错和绕过方式
最常卡在权限和网络上,尤其是企业内网或用了 GitHub App Token 的场景。
-
Failed to clone https://github.com/xxx/yyy.git via https, ssh protocol→ 检查是否配置了git config --global url."git@github.com:".insteadOf "https://github.com/",或把 token 写进 URL:https://<code>YOUR_TOKEN@github.com/xxx/yyy.git -
Source directory ... is not clean, cannot switch to ...→ 进入对应vendor/xxx/yyy,手动git stash或git reset --hard清理脏状态 - 私有包提示
Could not fetch https://repo.example.com/packages.json→--prefer-source不影响 repo 发现逻辑,先确认repositories配置正确且能 curl 通 - 用了
path类型仓库时,--prefer-source无效 —— path repo 本就不走 git,它直接 symlink
真正麻烦的不是参数本身,而是混用场景:比如开发时开了 --prefer-source,提 PR 前忘了删掉,结果同事 composer install 卡在私有库权限上。所以最好把策略写进 README 或 pre-commit hook 里,而不是靠人记。










