必须用--prefer-source:需看源码、打补丁、切分支、查commit历史;否则默认--prefer-dist更快更省空间。它强制git clone而非下载ZIP,前提为包含有效source字段、本地装有git且可直连仓库。

想看源码、打补丁、切分支、查 commit 历史,就必须用 --prefer-source;只跑程序、上线部署,它反而拖慢速度、增大体积。
什么时候必须加 --prefer-source
这不是“可选优化”,而是行为切换开关:它让 Composer 放弃下载 ZIP 包,转而尝试 git clone 源仓库。适用场景非常具体:
- 需要阅读或修改包里的
tests/、.github/、CHANGELOG.md等非运行必需文件 - 要基于某个包的
dev-main分支调试,且需随时git pull同步(注意:Composer 默认克隆后是 detached HEAD,这点后面会说) - 准备给上游提 PR,得在
vendor/xxx/yyy里直接git add+git commit - 审计安全问题,需比对特定 commit 的原始代码,而非 dist 解压后可能被脚本修改过的产物
--prefer-source 成功的前提条件
它不是万能钥匙,能否真正 clone 下来,取决于三方配合:
- 包的
composer.json必须声明有效的"source"字段(含"url"和"type": "git"),否则 Composer 会静默 fallback 到 dist - 你的机器上必须装了
git命令,且能直连该 URL(比如 GitHub 公共地址没问题,但私有 GitLab 若没配 SSH key 或 token 就会失败) - 不能用纯镜像源(如阿里云镜像)——它们只代理
packages.json和 dist ZIP,不代理git clone请求 - 若已安装过包,默认不会重装;得先
rm -rf vendor/xxx/yyy,再跑composer install --prefer-source
为什么进了 vendor/xxx/yyy 还是 not a git repository
即使 --prefer-source 日志显示 Cloning abc123 from https://...,你也可能看不到 .git/ 目录。原因很实在:
- Composer 默认执行
git clone --no-checkout+git checkout -qf,然后删掉整个.git/—— 这是为节省空间、避免部署污染 - 要保留
.git/,必须额外加--keep-vcs:例如composer install --prefer-source --keep-vcs - 加了
--keep-vcs后,git remote -v才能看见原始仓库地址,git log才能翻历史 - 副作用明显:vendor 体积翻倍,且下次
composer update可能因本地有未提交修改而报错
dev-main 安装后,HEAD 指向哪?
用 composer require vendor/name:dev-main 装完,进目录执行 cat .git/HEAD,看到的几乎肯定是 abc123def456... 这类 commit hash,而不是 ref: refs/heads/main。
这是 Composer 故意设计的:保证可重现性。它把远程分支当前 HEAD 当作一个快照固定下来,不随 upstream 移动。所以别指望在 vendor 里 git pull 自动更新 —— 想同步最新,得手动 git fetch && git reset --hard origin/main,或者重新 composer update。











