vendor目录绝不能提交到Git,composer.lock必须提交;vendor是可再生构建产物,提交导致体积膨胀、diff失控、合并冲突及环境不一致,而lock文件锁定精确依赖版本,保障开发、CI、生产环境一致性。

vendor/ 目录绝不能提交到 Git,composer.lock 文件必须提交且每次变更后立即 commit。 这不是建议,而是 Composer 项目在 Git 下能正常协作的底线。踩错其中一条,团队里至少一人会在 composer install 时失败,CI 构建会随机卡住,历史记录迅速膨胀到无法 review。
为什么 vendor/ 必须从 Git 中彻底清除
它不是源码,是构建产物:含平台相关二进制(如 ext-redis 编译结果)、符号链接、临时文件,不同机器生成内容天然不一致。一旦被 track 过,后果直接可见:
- Git 历史体积暴涨,克隆变慢,
git status总被一堆 vendor/ 差异刷屏 - CI 构建时因路径权限或符号链接解析失败,报
failed to open stream: No such file or directory - IDE 自动重建 vendor/ 后,
git diff出现大量无关变更,掩盖真正代码改动
补救动作只有一条可靠路径:git rm -r --cached vendor,之后确认 .gitignore 里有且仅有这一行:/vendor(开头的 / 很关键,防子目录误匹配)。
composer.lock 提交后为什么还会报 “Lock file is not up to date”
这个错误几乎总是因为有人改了 composer.json(比如加了个 require),但没运行 composer install 或 composer update,导致本地 composer.lock 没更新,也没 git add 它。别人拉下来后,composer install 发现 lock 和 json 对不上,直接中止。
使用 `gh` CLI 与 GitHub 交互。通过`gh issue`、`gh pr`、`gh run` 和 `gh api` 管理 issue、PR、CI 运行以及高级查询。
- 每次运行
composer require、composer remove、composer update后,composer.lock必定变化,必须和composer.json一起git add并git commit - 合并 PR 时若出现
composer.lock冲突,优先保留目标分支(如main)的 lock 内容,再在当前分支执行composer update --lock—— 它不升级包,只重生成 lock 结构以对齐 - Windows/macOS 下 lock 文件换行符或 JSON 排序可能不一致,建议在项目根加
.gitattributes:写入composer.lock text eol=lf
CI 流程中 composer install 总卡住或失败的常见原因
不是网络慢,是配置或环境没对齐:
- 私有 Git 包(如
"type": "vcs")在 CI 中默认走git clone,但 CI 环境通常没配 SSH key 或 HTTPS 认证,直接 401 或超时;应改用--prefer-dist强制走 zip 包下载 - 漏加
--no-dev:生产环境不该装phpunit这类 dev-dependency,否则可能因扩展缺失(如ext-xdebug)报错 - PHP 版本或扩展不一致:CI 使用 PHP 8.2,而本地是 8.1,某些包的
platform约束(如"php": "^8.2")会让composer install直接拒绝执行 - CI 脚本里写了
composer install --ignore-platform-reqs却没加--no-interaction,遇到 license 提示会卡住等待输入
想保留 vendor/bin 或某个私有包源码怎么办
Git 不允许“忽略父目录却保留子目录”,只能靠 .gitignore 规则顺序绕过:
- 先写
/vendor(全局忽略) - 再写
!/vendor/bin和!/vendor/my-company/private-package(反向取消忽略) - 注意顺序:Git 从上到下匹配,第一条生效即停,所以
!规则必须放在/vendor之后 - 如果
vendor/bin已被 track 过,仍需先执行git rm -r --cached vendor/bin,否则忽略无效
最易被忽略的一点:所有这些规则都依赖于 git rm -r --cached 的彻底性——只要 vendor/ 任一子目录还在 Git 索引里,后续任何忽略规则都形同虚设。别跳过这一步,也别指望 git clean -fd 替代它。

















