Husky v7.0.4 pre-commit钩子间隔执行报错:无法锁定HEAD引用问题
问题根因
这个间隔报错的核心原因是你把修改HEAD指针的git reset操作放在了pre-commit钩子中执行,刚好踩中了git的提交校验逻辑:
git在调用pre-commit钩子之前,就已经提前锁定了当前HEAD的哈希值作为本次提交的父提交校验值,如果你在钩子运行过程中通过git reset修改了HEAD指针,钩子执行完毕后git会做一致性校验,发现当前HEAD和预先锁定的哈希值不一致,就会抛出你遇到的cannot lock ref 'HEAD'错误,直接终止本次提交。
交替成功失败的原因
这个现象的触发逻辑很清晰:
- 当你执行提交时如果当前分支有多个未合并的提交,
pre-commit中的git reset会把HEAD修改为和develop分支的公共祖先哈希,和git预先锁定的哈希不一致,提交直接报错终止。但此时git reset和git add .已经执行完成,你的HEAD已经变成了公共祖先哈希,所有修改也已经存入暂存区。 - 你再次执行提交时,当前HEAD已经是公共祖先哈希,
pre-commit中执行git reset的目标哈希和当前HEAD完全一致,没有修改HEAD指针,git校验通过,提交正常完成。
两次提交构成一个循环,就出现了你遇到的奇偶次交替成功失败的现象。
修复方案
pre-commit钩子的设计定位就是做代码检查、格式化这类不改变git提交树的操作,绝对不能在里面执行修改HEAD、修改分支指针的操作,推荐两种调整方案:
- 把squash逻辑迁移到
pre-push钩子中执行,这个阶段没有提交时的HEAD锁定校验,不会触发冲突 - 单独写一个git自定义别名执行squash操作,需要合并提交时手动调用,不要和
pre-commit钩子耦合
内容的提问来源于stack exchange,提问作者Jamie
相关产品推荐
相关产品推荐

