composer.lock冲突不能随便删或重生成,因其是确定性依赖快照,需严格匹配composer.json和执行环境;随意操作会导致依赖不一致,引发CI失败或线上异常。

为什么 composer.lock 冲突不能随便删或重生成
直接 git checkout --ours 或 rm composer.lock && composer install 是高危操作——它会让两个分支实际安装的依赖版本不一致,轻则 CI 失败,重则线上行为异常。因为 composer.lock 不是“中间产物”,而是**确定性依赖快照**,它的哈希、平台配置、插件顺序都必须严格匹配当前 composer.json 和执行环境。
- 不同人本地执行
composer install可能因 PHP 版本、扩展差异导致composer.lock中platform字段或content-hash不同 -
composer update会重排包安装顺序,即使版本没变,lock文件 diff 也可能巨大 - CI 环境通常校验
composer.lock是否由composer install生成(而非update),冲突后乱改会导致构建拒绝
用 composer merge-plugin 自动合并(推荐)
这不是官方内置功能,但它是目前最接近“语义合并”的方案:把 composer.lock 当作结构化数据处理,而非纯文本。需提前在项目中启用:
- 运行
composer require --dev "wikimedia/composer-merge-plugin:dev-master" - 在
composer.json根级加配置:"extra": { "merge-plugin": { "include": [ "composer.local.json" ], "recurse": true, "replace": false, "ignore-duplicates": false } } - 真正合并时,先确保双方分支都已
composer install过,再用git merge;插件会在安装阶段自动合并多份 lock 的依赖声明(如 dev 与 prod 区分)
注意:它不解决平台字段冲突(如 php 版本声明),这类仍需人工确认。
手动修复冲突的最小安全操作路径
当无法用插件或时间紧急时,按以下顺序操作,避免引入隐性不一致:
- 先
git checkout --ours composer.lock(保留当前分支的 lock) - 运行
composer install --dry-run:看是否报错“Your requirements could not be resolved”——如果报错,说明对方分支改了composer.json但没提交对应 lock,此时必须拉取对方composer.json再生成 lock - 若
--dry-run通过,再执行真实composer install,然后git add composer.lock - 重点检查
packages和packages-dev下是否有被意外降级/跳过更新的包(尤其关注version和source字段变化)
CI/CD 流程里必须加的防护
很多团队只在本地修 lock 冲突,却没拦住“带毒 lock”进主干。关键动作要固化到流程中:
- Git hook 或 CI 脚本里加校验:
composer validate --strict(检查 lock 是否与 json 匹配) +composer show --locked | md5sum对比基准值 - 禁止在 CI 中运行
composer update;所有 lock 更新必须由开发者本地完成并提交 - 在
.gitattributes中设composer.lock merge=union(仅辅助,不能替代逻辑判断)
真正麻烦的不是冲突本身,而是有人把 composer.lock 当成普通配置文件对待——它本质是二进制级契约,任何绕过语义的文本合并,都在给下次发布埋雷。










