composer update --lock 是唯一可进 ci 且不引发环境漂移的解法:它不读旧 lock,仅基于 clean 合并后的 composer.json 重算 content-hash、platform 和 packages 顺序,生成全新合法快照,输出应为“0 installs, 0 updates, 0 removals”。

遇到 composer.lock Git 合并冲突,别修 JSON、别选 --ours/--theirs、别删了重装 —— 唯一能进 CI 流水线且不引发环境漂移的操作,是执行 composer update --lock,前提是 composer.json 已 clean 合并。
为什么 composer update --lock 是唯一可自动化的解法
Git 标出 composer.lock 冲突时,文件已含 等标记,JSON 结构损坏,<code>composer install 直接报错:Your lock file does not contain a compatible set of packages 或更底层的 Invalid argument supplied for foreach()。而 composer update --lock 完全不读旧 lock,只基于当前 composer.json 重算 content-hash、platform、packages 数组顺序与完整结构,输出一个全新合法快照。
- 它不改动任何已锁定包版本,不重装
vendor/,只重写 lock 文件 - 输出应为
Lock file operations: 0 installs, 0 updates, 0 removals;若出现大量Updating xxx,说明composer.json还没拉齐 - CI 中可安全封装为脚本:先
git checkout --theirs composer.json && rm composer.lock && composer update --lock
如何让 composer.lock 冲突在 PR 阶段就自动拦截
靠人手处理冲突永远滞后,真正自动化得从校验环节卡住。CI 必须在安装前验证 lock 是否“契约有效”:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 运行
composer validate --strict:检查 JSON 合法性、字段完整性 - 紧接着跑
composer install --dry-run:若提示The lock file is not up to date with composer.json,说明 PR 提交者漏了composer update --lock,立即失败 - 加
*composer.lock -merge到.gitattributes,禁用 Git 默认合并策略,避免误触发自动覆盖
composer.json 配置如何降低“假冲突”频率
70% 的 composer.lock 冲突并非依赖不一致,而是字段顺序、缩进、空行差异导致 Git 误判。这类冲突完全可通过配置压制:
- 在
composer.json根节点加入"config": { "sort-packages": true },强制所有包按字母序排列 - 统一声明平台约束,例如
"config": { "platform": { "php": "8.1.0" } },消除本地 PHP 小版本差异引发的 content-hash 变动 - 禁止在 feature 分支执行全量
composer update;只允许composer require或composer remove,它们会自动触发一次composer update --lock
CI 中绝对不能碰的三个操作
这些看似省事的做法,在敏捷迭代高频合并下等于埋雷:
-
composer install --no-lock:绕过 lock 校验,导致线上装的包和本地开发机版本不一致,安全补丁漏装、间接依赖意外升级、半夜报错无法复现 -
git checkout --ours composer.lock:可能丢掉对方新增的require-dev包(如phpunit),CI 通过但本地测试跑不起来 - 手动删冲突标记后保存 JSON:哪怕只调换
packages数组中两个包的顺序,content-hash 就失效,后续composer install可能静默跳过校验,运行时类找不到
真正难的不是命令怎么敲,是让所有人接受:lock 文件不是配置,是契约;它的生成权必须收口,不能分散在每个开发者本地。每次 composer.json 变更,都必须伴随一次 composer update --lock 和一次原子提交。










