composer.lock 必须提交到 git,是硬性要求而非建议——它记录精确版本、完整依赖树和sha256哈希值,确保环境一致性;缺失会导致 composer install 退化为 update,引发ci与本地版本不一致、运行时报错等问题。

composer.lock 必须提交到 Git,不是“建议”,是硬性要求——尤其对 Laravel、Symfony 等应用型项目。不提交它,等于放弃环境一致性。
为什么 composer.lock 不能丢?
它不是辅助文件,而是安装的“唯一权威说明书”。composer install 全程只读这个文件:精确版本、完整依赖树、每个包的 SHA256 哈希值。没有它,composer install 就自动退化为 composer update,重新解析所有版本约束——你改了 composer.json 里一个 ^8.0,结果 CI 装出 8.4.2,而你本地是 8.3.1,类找不到、类型报错、测试突然挂掉,全因这个文件缺失。
哪些情况会误删或绕过 composer.lock?
常见错误场景:
- 新人直接改完
composer.json就git commit,忘了跑composer install更新 lock 文件 - CI 流水线配置成
composer install --ignore-platform-reqs却没校验 lock 是否存在,导致跳过锁定逻辑 - 手动删了
composer.lock后执行composer install,等同于隐式运行了一次不受控的composer update - 合并分支时用图形化工具点选“接受双方”,把冲突后的 lock 文件当普通文本合并——内容完全无效
遇到 composer.lock 冲突怎么办?
别手改,别保留双方,别靠猜。按场景选操作:
- 你想以对方分支为准(比如合入 main):
git checkout --theirs -- composer.lock && composer install --no-scripts - 你想以自己分支为准(比如功能开发未完成):
git checkout --ours -- composer.lock && composer install --no-scripts - 双方都改了依赖(如 A 加了
monolog,B 升了laravel/framework):删掉当前composer.lock,切到目标基线(如main),运行composer install生成干净 lock,再切回你的分支,用composer require xxx或composer update vendor/package增量引入变更
长期协作中怎么避免反复冲突?
冲突不是技术问题,是节奏问题。关键在建立同步机制:
- 禁止任何人在改
composer.json后不跑composer install就提交 - 每天早间由一人执行
composer update --dry-run检查安全更新,确认后统一在main上composer update并推送,所有人基于该 commit 继续开发 -
.gitignore里必须有vendor/,且已用git rm -r --cached vendor/清理历史记录
composer.lock 的价值不在“有没有”,而在“是否每次变更都严格对应一次 composer install”。很多人以为冲突难解,其实真正难的是让团队养成“改声明 → 跑命令 → 提交结果”这一整条链路的肌肉记忆。










