Git版本过低会导致composer update卡在git clone阶段,因旧版Git不支持现代协议特性而静默阻塞;可通过git --version检查并升级至2.15.0+,或用--prefer-dist绕过Git克隆。

Git 版本过低会导致 composer update 卡在 git clone 阶段
Composer 在安装或更新 vcs 类型包(如 "type": "git")时,会调用系统 Git 命令执行克隆。若 Git 版本太旧(如低于 2.10),可能不支持现代仓库的协议特性(如 HTTPS 推送认证、稀疏检出、refspec 优化),导致 git clone 进程卡住不动、无报错、CPU 占用为 0 —— 表面看是 Composer 卡了,实则是子进程被 Git 自身阻塞。
- 检查当前 Git 版本:
git --version,低于2.15.0就建议升级(尤其 Windows 用户常见 1.9.x 或 2.7.x) - 确认卡点:运行
composer update -vvv,最后一行若停在Executing command (CWD): git clone --no-checkout ...或反复重试git ls-remote,基本可锁定为 Git 层问题 - 旧版 Git 在遇到 GitHub 新仓库(启用
git://禁用、强制 HTTPS + Token 认证)时,常静默等待 SSH 密码输入,而 Composer 不提供交互入口,于是挂起
临时绕过 Git 依赖,强制走压缩包下载
不升级 Git 也能快速验证和恢复流程:用 --prefer-dist 参数让 Composer 跳过 git clone,改从 dist(ZIP/TAR 包)安装。这能绕过所有 Git 协议、权限、版本兼容性问题。
- 执行:
composer update --prefer-dist,观察是否立刻开始下载 ZIP 包 - 若成功,说明问题确实出在 Git 流程;失败则需排查其他层(如网络、镜像源)
- 注意:
--prefer-dist仅对已发布 tag 的包有效;若依赖的是dev-master或未打 tag 的分支,仍会 fallback 到 Git 克隆 - 项目级固化该行为:在
composer.json的config段加"preferred-install": {"*": "dist"}
Git 升级后仍卡住?重点检查 SSH 和 HTTPS 协议映射
Git ≥2.18 后默认禁用不安全协议,且很多企业网络会拦截 git://。即使 Git 版本够新,若配置残留旧规则,依然会卡在 git ls-remote 等待响应。
- 检查全局 Git 协议重写:
git config --global --get-all url."https://".insteadOf git://,应有输出;若无,运行:git config --global url."https://".insteadOf git:// - 测试私有仓库连通性:
git ls-remote -h https://github.com/your-org/private-repo.git,若卡住或提示Authentication failed,说明 Git 凭据或 Token 权限不足 - 避免 SSH 密钥交互卡死:把
git@github.com:org/repo.git改成https://token:x-oauth-basic@github.com/org/repo.git(配合github-oauth配置更安全) - Windows 用户注意:Git for Windows 自带的 Bash 和 CMD 下的 Git 可能版本不同,用
where git确认 Composer 调用的是哪个
为什么 COMPOSER_PROCESS_TIMEOUT=0 有时也不管用
设为 0 只是延长等待,但无法解决 Git 进程本身因协议不匹配而无限阻塞的问题。比如 Git 在等一个永远不会出现的 SSH 密码提示,或卡在 TLS 握手失败后的重试逻辑里 —— 此时它根本没触发超时机制,而是陷入系统调用等待。
-
COMPOSER_PROCESS_TIMEOUT控制的是 PHPproc_open启动子进程后的“最大存活时间”,不是 Git 内部状态机的 timeout - 真正有效的诊断方式是:在
composer update -vvv卡住时,另开终端执行ps aux | grep git,看是否有git clone进程处于S(sleep)或D(uninterruptible sleep)状态 - 若看到
git-remote-https卡在connect或SSL_read,说明是 TLS/CA 或代理问题,和 Git 版本无关,需查curl.cainfo或代理设置
Git 版本只是表象,背后常混着协议配置、凭据管理、TLS 根证书、甚至 Windows 子系统调度等多层问题。最稳妥的做法是:先用 --prefer-dist 快速验证是否 Git 相关,再针对性升级 + 重配协议,而不是一上来就调超时或换镜像。











