使用“dev-分支名”需同时满足仓库配置、分支真实存在、lock文件清理三条件,且分支名须完全一致(含大小写与斜杠),并显式声明vcs仓库;否则将回退至packagist映射版本。

直接写 "dev-main" 或 "dev-develop" 不保证拉到对应分支——它只是个“稳定性标识符”,是否生效取决于仓库配置、分支真实性、lock 文件状态三者是否同时满足。
dev-前缀必须配合 VCS 仓库声明才有效
Composer 默认只查 Packagist,"dev-main" 这类写法在包已注册到 Packagist 时会被忽略,仍走 metadata 映射到 master 或最新 stable 标签。必须显式添加 "repositories" 声明 Git 地址:
- 在
composer.json根级加"repositories"数组,"type": "vcs","url"指向真实 Git 仓库(SSH 或 HTTPS 均可) - URL 必须能被 Composer 解析为合法 VCS 源,比如
"git@github.com:acme/package.git"或"https://github.com/acme/package.git" - 如果仓库是私有库,确保 SSH key 已配置或 HTTPS 凭据已缓存,否则 clone 失败会静默回退到 Packagist
dev-分支名拼写必须完全一致(含大小写和斜杠)
分支名不是模糊匹配:"dev-auth-refactor" 和远程实际存在的 "dev/auth-refactor" 是两个不同分支,Composer 不会自动转换斜杠为短横线。
- 用
git ls-remote --heads <repo-url></repo-url>确认远程分支名(注意大小写) - 分支含斜杠时,
dev-前缀后必须完整写出,例如"dev-dev/auth-refactor" -
"dev-main"≠"dev-master",哪怕两个分支内容相同,也必须按远程真实名称写
vendor 和 composer.lock 必须清理干净才能生效
旧 composer.lock 里可能还锁着 master 的 commit hash,导致 composer install 直接复用,根本不会重新解析分支。
- 运行前先删掉
vendor/和composer.lock - 执行
composer update acme/package --with-dependencies,不加--with-dependencies可能因子依赖锁定而跳过更新 - 确认安装后
vendor/acme/package/.git/HEAD是否指向目标分支(如ref: refs/heads/dev-auth-refactor)
dev- vs #commit-hash:安全性和可维护性取舍
"dev-main" 每次都拉最新 commit,适合 CI/CD;"dev-main#abc1234" 固定提交,但有 force-push 失效风险。
-
#abc1234不校验 GPG 签名,也不做深度 clone,仅 shallow fetch,一旦该 commit 被覆盖,composer install会报Could not find package at commit abc1234 -
dev-main更可靠,但需配合 CI 流水线做分支保护(禁止 force-push),否则上线行为不可控 - 生产环境慎用任何
dev-约束,除非你完全掌控该仓库的发布节奏和分支生命周期
最容易被忽略的是 lock 文件残留和分支名大小写——这两个点几乎占了 dev 分支拉取失败案例的 80%。别信“应该没问题”,每次改完 composer.json 都手动验证 vendor/xxx/.git/HEAD 内容。











