补丁不生效的首要原因是未安装cweagans/composer-patches插件,composer原生完全忽略extra.patches配置;必须运行composer require cweagans/composer-patches:^1.7显式安装至当前项目,删掉vendor和composer.lock后重装才能触发补丁应用。

补丁不生效?先确认 cweagans/composer-patches 是否已安装
Composer 原生完全不处理 extra.patches,没装插件时所有配置都是死文本。运行 composer require cweagans/composer-patches:^1.7 是强制前置步骤,不是可选项。
常见错误现象:
-
composer install成功但vendor/下文件毫无变化 - 终端日志里压根没出现
Applying patch字样 -
composer show cweagans/composer-patches报错或无输出
必须显式安装到当前项目(不能靠全局安装),且建议用 ^1.7 版本——它兼容 Composer 2.x,而旧版 ^1.6 在某些 PHP 8.3+ 环境下会静默失败。
extra.patches 配置写在哪、怎么写才有效
补丁声明必须放在项目根目录的 composer.json 的 extra.patches 字段下,其他位置全无效:子模块的 composer.json、repositories 里定义的包、甚至 config.platform 都不会被插件读取。
键名必须是标准包名格式:"monolog/monolog",不能写成 "./vendor/monolog/monolog" 或 "monolog";值必须是对象,例如:
"extra": {
"patches": {
"monolog/monolog": {
"Fix null dereference in JsonFormatter": "patches/monolog-null-check.patch"
}
}
}
路径是相对于 composer.json 的,所以 "patches/monolog-null-check.patch" 就表示该文件在项目根目录下的 patches/ 子目录里。
容易踩的坑:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 路径含中文或空格 →
json_decode()解析失败,插件直接跳过该条目 - 用了 Windows 换行符(CRLF)→
patch命令报错,必须用 LF - 补丁描述用了冒号或引号未转义 → JSON 格式错误,整个
extra.patches被忽略
补丁文件必须是标准 git diff,且路径匹配 vendor 解压结构
补丁不是任意 diff 文件都能用。插件底层调用系统 patch 命令,因此必须符合 POSIX 格式,最稳妥的做法是进到 vendor/monolog/monolog 目录后生成:
cd vendor/monolog/monolog git checkout -b fix-branch # 修改 src/JsonFormatter.php git add src/JsonFormatter.php git diff --no-prefix > ../../patches/monolog-null-check.patch
生成的补丁头应为 diff --git a/src/JsonFormatter.php b/src/JsonFormatter.php,不能带 vendor/monolog/monolog/ 前缀,也不能是 a/vendor/monolog/monolog/src/...。
验证方式(在项目根目录执行):
-
file patches/*.patch→ 输出里不能有CRLF -
git apply --check patches/monolog-null-check.patch→ 无任何输出才算通过 - 补丁内所有
--- a/xxx和+++ b/xxx中的xxx必须和vendor/monolog/monolog/xxx实际路径一致
为什么删了 vendor 和 composer.lock 后重装才生效
因为 Composer 安装依赖时,优先从本地缓存解压 tar 包,而不是重新 clone 或下载源码。如果之前已安装过 monolog/monolog,缓存包里没有补丁逻辑,插件根本没机会介入。
只有在以下情况,插件才会真正触发补丁应用:
- 首次运行
composer install(composer.lock存在但vendor/为空) -
composer update monolog/monolog(该包版本变更,触发重新解压) - 删掉
vendor/和composer.lock后再composer install
注意:已安装的包不会自动重打补丁。比如你加了一个新补丁,但没删 vendor/ 就直接 composer install,插件会跳过已存在的目录,补丁形同虚设。
复杂点在于,补丁应用是一次性动作,且强依赖当前 composer.lock 锁定的版本。如果上游包发布新版,而你的补丁是基于旧 commit 生成的,hunk offset 很可能偏移,导致 patch failed: src/xxx.php:42 —— 这时候不能硬改补丁行号,得回 vendor/ 重新 git diff。










