composer不管理分支,仅按字符串精确匹配远端git分支名并拉取head;真正锁定需用dev-分支名#commit-hash格式,且分支名须大小写、斜杠全一致,require时须加--stability=dev或@dev,私有库必配vcs repositories。

Composer 不“指向”分支,它只按字符串精确匹配 Git 分支名并拉取 HEAD —— 所以所谓“临时依赖版本”,本质是用 dev-xxx 锁定某次提交,或靠 #commit-hash 实现真正可控的快照。
dev-分支名必须和远端 Git 分支完全一致
写 dev-main 却报 Could not find a version of package xxx matching your minimum-stability?不是 Composer 抽风,是你远端根本没 main 分支。常见错配:
- 远端是
master→ 只能写dev-master,dev-main无效 - 远端是
feature/login→ 必须写dev-feature/login,不能写成dev-feature-login或漏掉dev- - 远端是
Main(首字母大写)→dev-Main和dev-main是两个不同分支,大小写敏感
require dev-分支必须加 --stability=dev 或 @dev
默认 minimum-stability 是 stable,所有 dev- 开头的引用都属于不稳定版本,不显式放宽就进不了解析阶段。两种安全做法:
- 临时安装:用
composer require vendor/pkg:dev-main --stability=dev(推荐,不改全局配置) - 单包放宽:用
composer require vendor/pkg:dev-main@dev(@dev后缀只对该包生效) - 别永久设
"minimum-stability": "dev"—— 这会让所有依赖都可能降级到任意-dev版本,失控风险极高
dev-分支默认浮动,锁定 commit 必须用 #hash
"vendor/pkg": "dev-main" 看似指定了分支,实际每次 composer update 都可能拉新提交;force push 后旧 hash 在 composer.lock 中直接失效。真正锁定要:
- 手动写死:
"vendor/pkg": "dev-main#abc1234"(注意:斜杠分支需 URL 编码,如dev-feature%2Flogin#def5678) - 运行
composer update vendor/pkg,确保composer.lock的source.reference字段变成 40 位或至少 7 位小写哈希,而不是main或HEAD - 加
--prefer-source参数可强制走 git clone,避免因 dist 模式忽略#hash
私有 Git 仓库必须配 vcs repositories,且顺序要对
光写 "vendor/private": "dev-main" 不行,Composer 根本不知道去哪找这个包。必须在 composer.json 顶层加:
{
"repositories": [
{
"type": "vcs",
"url": "https://git.example.com/team/utils.git"
}
]
}
关键点:
-
type必须是vcs,不是git或package -
url要带.git后缀(尤其 HTTPS 地址),否则部分版本会解析失败 - 多个私有源时,把它们放在
repositories数组前面;若官方 Packagist 源在前,同名包永远被短路,你的私有分支不会被加载 - SSH 地址(如
git@git.example.com:team/pkg.git)要求执行机已配好对应 SSH key,auth.json对它无效
最易被忽略的是:branch 名是否真实存在、composer.lock 里 source.reference 是否为有效 commit hash、私有源是否排在 repositories 数组靠前 —— 这三点任一出错,都会导致本地能装、CI 构建失败、线上环境拉不到代码。











