Composer的VCS缓存无固定过期时间,依赖内容一致性校验自动更新:每次update/install时比对远程commit hash、分支HEAD或tag,落后则自动git fetch同步;手动刷新可删对应vcs子目录或执行git fetch --all --prune。

Composer的VCS缓存默认不过期,但会自动失效
Composer的vcs缓存(位于{$cache-dir}/vcs)本身没有硬性TTL或定时过期机制。它靠“内容一致性校验”触发更新:每次执行composer update或composer install时,Composer会检查远程仓库的最新commit hash、分支HEAD或tag信息;如果发现本地缓存的git clone副本落后了,就自动执行git fetch同步元数据,必要时还会git reset --hard到目标提交。所以它不是“多久后过期”,而是“什么时候被判定为脏”。
常见误判场景包括:私有GitLab仓库启用了强制推送(force-push)、镜像源未及时同步上游变更、或本地缓存目录被手动修改过权限/时间戳。
如何手动刷新VCS缓存而不清空整个cache-dir
直接删掉vcs子目录最彻底,但影响所有包。更精准的做法是只清理特定仓库:
- 查出某包对应的缓存路径:
composer show vendor/package --verbose→ 看输出里Source行的本地克隆路径(通常是{$cache-dir}/vcs/xxx.git/) - 进入该目录执行:
git fetch --all --prune,再git remote set-head origin -a确保HEAD指向正确分支 - 若仍报错“could not load package”,可加
-vvv运行composer update vendor/package,观察是否卡在Cloning into …——说明缓存已损坏,此时删掉对应.git目录即可
修改VCS缓存行为的三个关键配置项
这些配置不控制“过期时间”,但能显著影响缓存命中率和拉取策略:
-
cache-vcs-ttl:仅影响HTTP元数据缓存(如GitHub API响应),单位秒,默认3600。对git clone本身无影响,composer config cache-vcs-ttl 7200可延长API响应缓存 -
github-protocols:指定克隆私有仓库时优先用https还是ssh。协议不一致会导致同一仓库被缓存两份(vcs/github.com-xxx.git和vcs/git@github.com:xxx.git),徒增空间 -
disable-tls:设为true会跳过SSL验证,可能让某些内网GitLab仓库缓存失败(因证书不被信任导致fetch中断),建议配合git config --global http.sslVerify false而非全局关TLS
CI/CD中VCS缓存管理的典型陷阱
在GitHub Actions或GitLab CI里复用composer cache时,VCS缓存最容易引发非确定性失败:
- 缓存key若只含
composer.lock哈希,但没包含Git仓库的commit hash或branch name,会导致不同PR共用同一份vcs缓存,出现“安装了错误分支代码”的静默错误 - Docker构建中挂载
~/.composer/cache/vcs到容器,但宿主机git版本太旧(如1.8.x),而缓存里用了git sparse-checkout等新特性,导致git checkout失败 - 使用
composer install --no-interaction --prefer-dist本意是跳过VCS,但如果composer.json里写了"type": "package"并指定了"source",依然会走VCS流程——这点常被忽略
VCS缓存真正难缠的地方不在“过期”,而在“状态漂移”:它的有效性高度依赖外部仓库的稳定性、本地git环境的一致性,以及你是否清楚自己到底在拉哪个commit。每次遇到“明明改了远程却装不到新代码”,先ls -la {$cache-dir}/vcs/看时间戳,再git -C path/to/cache/repo log -1核对HEAD,比盲目清缓存快得多。


















