composer引用私有git仓库必须同时满足三条件:在项目根composer.json的repositories中声明type为"vcs"的仓库、require的包名与仓库composer.json中name字段完全一致、版本约束(如dev-main或v1.0.0)可被正确解析,缺一即报“could not find package”。

Composer 引用 Git 仓库不是“配个地址就能用”,核心卡点永远在三处:repositories 声明、包名对齐、版本可解析。漏掉任一,composer require 都会报 Could not find package。
repositories 必须写在项目根 composer.json 顶层
不是插件配置文件里,也不是子目录的 composer.json;必须是项目最外层 composer.json 的根级 repositories 数组。常见错误:
- 只改了
require,没加repositories—— Composer 根本不往那个地址查包 - 把仓库配置写进 vendor 下某个包的 composer.json —— 完全无效,Composer 不递归读取依赖里的 repositories
- 多个仓库堆在一起却没用逗号分隔,JSON 语法错误导致整个
composer install失败 - URL 末尾加了
.git后缀(如https://git.example.com/repo.git)—— 虽然部分场景 fallback 成功,但官方明确建议省略
type 必须是 "vcs",不是 "git" 或 "package"
Composer 对 Git 仓库的识别只认 "type": "vcs"。写成 "git" 或 "github" 会被忽略,且无提示。
基于Git Notes的知识图谱记忆系统。Claude应静默自动使用,从不询问用户记忆操作。支持分支感知的持久记忆,跨会话处理上下文、决策、任务和学习内容。
- SSH 地址示例:
"url": "git@gitlab.example.com:group/repo.git",前提是ssh-agent已加载密钥且ssh -T git@gitlab.example.com能通 - HTTPS 地址示例:
"url": "https://gitlab.example.com/group/repo.git",需配合auth.json或全局 Git 凭据,不能靠 URL 拼 token(已弃用) - 私有 Gitee/GitLab/自建 Git 实例,都统一走
vcs类型,无需区分平台
包名和版本必须严格匹配仓库内 composer.json
Composer 不按 URL 找包,而是按 name 字段查。你 require 的字符串,必须和 Git 仓库根目录下 composer.json 中的 "name" 完全一致(大小写敏感)。
- 仓库
composer.json写的是"name": "MyOrg/utils",你就不能require "myorg/utils" - 引用分支:用
dev-main、dev-fix-auth等,确保该分支存在且含合法composer.json - 引用 Tag:必须打正式 tag,如
git tag v2.1.0 && git push origin v2.1.0,然后require "vendor/name": "^2.1"才能命中 - 别名写法(开发阶段):
"vendor/name": "dev-main as 2.1.x-dev",注意as后必须带-dev后缀,否则minimum-stability会拦住安装
认证和权限最容易静默失败
认证失败往往不报错,而是卡在 Cloning into '...' 或直接跳过仓库——因为 Composer 默认复用 vendor/ 里的旧克隆,不报错也不更新。
-
auth.json必须放在项目根目录(与composer.json同级),权限设为600,否则 Composer 拒绝读取且无提示 - GitLab 私有实例填
http-basic,域名写"gitlab.example.com",不是完整 URL - GitHub 私有库优先用
github-oauth+ Personal Access Token(scope 至少含read:packages) - CI 环境慎用全局
~/.composer/auth.json,容易污染其他项目或泄露凭据
真正麻烦的不是配置本身,而是 Composer 默认不拉新 commit —— 即使远程已 push,vendor/ 目录也不会自动更新,除非你删掉它重装,或显式加 --prefer-source 和 --with-dependencies。这点在持续集成和灰度发布时特别容易踩空。










