<p>最合适的是 pre-install-cmd 和 pre-update-cmd 钩子,因其在读取 composer.lock 后、修改前触发,可确保备份原始状态;post-* 钩子因 lock 文件已被重写而失效。</p>

Composer 本身不提供“每次 composer install 或 composer update 前自动备份 composer.lock”的内置机制,但可以通过 scripts 钩子 + Shell 脚本实现,关键在于选对钩子时机、避免覆盖冲突、并处理 Git 状态干扰。
用哪个 Composer 钩子最合适?
必须用 pre-install-cmd 和 pre-update-cmd,不能用 post-* —— 后者执行时 lock 文件可能已被修改甚至写入失败,备份就晚了。
-
pre-install-cmd在读取composer.lock之后、安装依赖之前触发,此时文件还是干净的原始状态 -
pre-update-cmd在执行composer update前触发,能捕获更新前的 lock 快照 - 别把脚本塞进
post-install-cmd:这时 lock 已被重写,备份的是“新版本”,失去回滚意义
Shell 脚本怎么写才可靠?
核心是原子性备份 + 时间戳防覆盖 + 可读命名。直接在 composer.json 的 scripts 里调用一行命令即可,不用额外文件:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
"scripts": {
"pre-install-cmd": "if [ -f composer.lock ]; then cp composer.lock \"composer.lock.$(date -u +%Y%m%d-%H%M%S).bak\"; fi",
"pre-update-cmd": "if [ -f composer.lock ]; then cp composer.lock \"composer.lock.$(date -u +%Y%m%d-%H%M%S).bak\"; fi"
}
- 用
$(date -u +%Y%m%d-%H%M%S)确保每份备份唯一,UTC 时间避免时区歧义 -
if [ -f composer.lock ]防止项目首次初始化时因无 lock 文件而报错 - Mac 用户注意:
date -u在 macOS 上需装coreutils(brew install coreutils),否则改用date +%Y%m%d-%H%M%S(本地时区)
Git 未暂存的 lock 修改会被误备份吗?
会。只要 composer.lock 文件存在,脚本就无差别复制 —— 包括你手动编辑后还没 git add 的脏版本。
- 这其实是优点:能帮你找回意外修改但未提交的 lock 变更
- 但若想只备份“Git 已知的稳定版”,得加判断:
git status --porcelain composer.lock | grep -q '^ M' || exit 0,不过会增加复杂度和失败风险 - 更务实的做法是:接受“所有磁盘上的 lock 都值得留痕”,靠文件名时间戳区分,人工删冗余备份
真正容易被忽略的是备份路径权限和磁盘空间——脚本默认存当前目录,如果长期运行 CI 或多人共用环境,.bak 文件会越积越多,得配定期清理逻辑,或者把备份路径改成独立目录再加 find ... -mmin +1440 -delete 这类限制。

















