必须用pre-install-cmd和pre-update-cmd钩子,因二者在读取composer.lock后、写入前触发,可确保备份原始快照;post-*钩子执行时lock已被重写或损坏,备份失去回滚意义。

必须用 pre-install-cmd 和 pre-update-cmd 钩子,其他时机都不可靠——post-* 执行时 composer.lock 已被重写,备份失去意义。
为什么 pre-* 钩子是唯一安全时机
Composer 在执行 install 或 update 时,会先读取当前 composer.lock,再决定装什么、怎么装。只有在这“读取之后、写入之前”的窗口期,文件内容才是你真正想保留的原始快照。
-
pre-install-cmd:触发于读取 lock 后、解析依赖前,此时 lock 还没被任何逻辑修改 -
pre-update-cmd:触发于执行 update 前,能捕获更新前的完整状态 -
post-install-cmd或post-update-cmd:lock 文件可能已被覆盖、校验失败甚至写入中断,备份的是“半成品”或“新版本”
Shell 脚本怎么写才不踩坑
一行命令就能搞定,但得处理三个现实问题:文件不存在、时间戳冲突、跨平台兼容性。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 加
if [ -f composer.lock ]判断,避免项目首次初始化时报错退出 - 用
$(date -u +%Y%m%d-%H%M%S)生成 UTC 时间戳,防止多时区协作下命名重复;Mac 用户若没装coreutils,改用date +%Y%m%d-%H%M%S(本地时区) - 备份名带
.bak后缀,不干扰 IDE 或 CI 默认识别逻辑(它们只认composer.lock) - 示例脚本:
"pre-install-cmd":"if [ -f composer.lock ]; then cp composer.lock \"composer.lock.$(date -u +%Y%m%d-%H%M%S).bak\"; fi"
Git 脏状态会被备份吗?该不该拦
会。只要磁盘上存在 composer.lock,脚本就无差别复制——包括你手动改了两行还没 git add 的版本。
- 这不是 bug,是 feature:能帮你找回误删、手抖改错但尚未提交的变更
- 若硬要只备份“Git 已知干净版”,得加
git status --porcelain composer.lock | grep -q '^ M' || exit 0,但这会引入 Git 依赖和失败风险(比如 CI 中 Git 环境不完整) - 更务实的做法是接受“所有磁盘上的 lock 都值得留痕”,靠文件名区分,人工定期清理冗余
.bak
真正容易被忽略的其实是磁盘和权限
脚本默认把备份写在当前目录,长期运行 CI 或多人共用环境时,.bak 文件会越积越多,直到填满磁盘或触发权限拒绝错误。
建议把备份路径改成独立目录(如 ./.lock-backups/),再配一条清理逻辑:find ./.lock-backups/ -mmin +1440 -delete(删 24 小时前的)。否则某天构建突然卡住,排查半天才发现是备份占满了 /tmp。










