必须用vcs类型仓库(如file:///path)并确保本地目录是合法Git仓库,才能通过dev-branch#commit-hash精准锁定提交;path类型不支持哈希定位,且version字段无效。

用 dev-branch#commit-hash 指定提交必须配 VCS 仓库
Composer 不会从本地路径解析 dev-main#abc123 这类带哈希的版本——path 类型仓库只认目录内容,不支持 commit 级别定位。真要锁定某次提交,必须把本地包当作 Git 仓库来用:repositories 类型得设为 vcs,url 填本地 Git 路径(如 file:///full/path/to/my-local-package),且该目录需是合法 Git 仓库(含 .git 子目录)。否则 composer update 会直接忽略哈希部分,退化成拉整个 dev-main 分支最新态。
composer.json 中的 version 字段对 dev-xxx#hash 无影响
本地包自己的 composer.json 里写 "version": "dev-main" 或 "1.0.0" 都不重要;真正起作用的是 Git 的 tag、分支名和 commit hash。Composer 在 vcs 模式下完全绕过 version 字段,只按你 require 里写的 dev-main#abc123 去检出对应 commit。但注意:如果目标 commit 没打 tag,也没在任何分支上,Git 本身无法检出,Composer 就会报 Could not find branch or tag。
Windows 下 file:// URL 容易因空格或路径编码失败
用 vcs + file:// 方式时,Windows 路径若含空格、中文或特殊字符(如 C:\my project\pkg),file:///C:/my%20project/pkg 这种手动编码极易出错。更稳的方式是:把本地包推到局域网 Git 服务器(哪怕只是 git daemon),或改用 SSH 路径(ssh://user@localhost/path/to/pkg.git);实在不行,先用 cd 进入包目录,运行 git config --local core.bare false 确保是非裸仓库,再用绝对路径加 file:// 并双引号包裹命令参数。
装完后 composer.lock 里 source.reference 是长哈希,不是短哈希
确认是否真按提交安装,别只看 vendor 目录时间戳。打开 composer.lock 找对应包条目,检查 source.reference 字段:它必须是完整的 40 位 commit hash(如 "source": {"type": "git", "url": "file:///...", "reference": "a1b2c3d4..."})。如果 reference 是短哈希(7 位)或为空,说明没走 commit 锁定,而是 fallback 到了分支 HEAD。这种情况常见于 Git 版本太老(git fetch 同步远程 ref。











