Composer install 不会意外覆盖代码,而是严格按 composer.lock 还原 vendor;手动修改 vendor 必被覆盖,应改用 path 仓库方案并上线前清理。

根本上,composer install 不会“意外”覆盖你改过的代码——它只是严格执行 composer.lock,把 vendor 目录还原成锁定状态。所谓“被覆盖”,说明你已经在 vendor/ 里手动改过文件,而这本身就是不被支持的操作。
为什么 vendor 里的修改一定会丢
Composer 把 vendor/ 当作只读缓存,所有内容由 composer.lock + 包源(dist 或 source)决定。只要 composer install 或 composer update 触发,就会按锁文件重新解压/复制/软链,你手改的任何文件都会被原始包内容覆盖。
- 常见现象:加了
var_dump()调试,第二天composer install后没了 - Git 无法跟踪
vendor/下的改动(多数包没带完整 .git,或被 .gitignore 排除) - CI 构建失败,因为别人机器上没有你那几行 patch
想临时改包逻辑,该用 path 仓库替代直接编辑 vendor
这是 Composer 官方推荐、可落地的方案:把包复制到项目外,用 "type": "path" 声明为本地源,Composer 会软链接过去,改代码立刻生效,且不会被覆盖。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 把包拷到项目同级目录,比如
../my-guzzle-patch - 在
composer.json的repositories中添加:{ "type": "path", "url": "../my-guzzle-patch" } - 把
require中对应包的版本改成"dev-main as 7.5.1"(假设原版是7.5.1) - 运行
composer update guzzlehttp/guzzle,vendor 里就变成指向你本地目录的 symlink
注意:CI 环境默认不该走 path 源,上线前必须切回稳定版本(删掉 repositories 并重置 require 版本)。
discard-changes 配置不是防覆盖,只是跳过确认提示
"discard-changes": true 只影响交互行为,不改变覆盖事实。它只在你手动改过 vendor/ 文件、又执行 composer update 时起作用——原本会卡在 [y,n,v,d,s,?] 提示,设成 true 就自动选 y 覆盖。
- 它完全不参与依赖解析,和
conflict字段无关 - 设了它,
composer install依然会覆盖;没设,也只是多问一句,结果一样 - 自动化部署中配它,只是为了避免卡住,不是为了“保护代码”
真正要防的是把 vendor 当工作区用
最常被忽略的一点:没人会故意去改 vendor/,但很多人误以为“临时改一下没问题”。问题不在命令本身,而在于这个操作破坏了 Composer 的契约模型——vendor/ 是输出,不是输入。
- 长期修改必须走 Fork + PR 流程,或利用包自身提供的扩展点(如事件监听、装饰器)
- 调试阶段用
path仓库,上线前必须清理掉所有repositories和dev-版本 - 提交前检查
git status是否显示vendor/下有未暂存更改——如果有,说明你已经踩进坑了

















