Husky 预提交钩子和压缩提交

Husky pre commit hook and squashing commits

我正在使用 "husky": "^7.0.4"

我的团队在打开 PR 之前压缩他们的提交。

我有一个 pre-commit 文件来自动执行此工作流程。每隔一段时间我 运行 提交功能,预提交流程完美运行。所以第 1、第 3、第 5 等有效。第二次、第四次、第六次等打印此错误

fatal: cannot lock ref 'HEAD': is at 766hdjoXXX but expected 766e11XXX

我想这可能是因为我没有更改文件,但是当我尝试更改某些内容时,它也没有用(无论如何它每隔一段时间都会成功并失败)。知道出了什么问题吗?

这是 pre-commit 文件:

read -n1 -p "Do you want to squash commits? [n/Y]" SHOULD_SQUASH < /dev/tty

case $SHOULD_SQUASH in  
  n|N) 
    echo
    echo Skipping squash, now linting files...
    ;;
  y|Y) 
    [ -z "$SQUASH_BRANCH" ] && SQUASH_BRANCH=develop
    branch=$(git symbolic-ref HEAD)
    echo
    echo Squashing all commits from $branch
    git reset $(git merge-base $SQUASH_BRANCH $branch)
    echo ------SUCCESS!------
    echo Commits successfully squashed.
    git add .
    echo Added all files successfully.
    ;;
  *) 
    echo
    echo Skipping squash, now linting files...
    ;;
esac

npx pretty-quick --staged
npm run lint

squash 函数来自一个自定义函数,可以正常工作,我们在 .zshrc.

中创建了它

预提交文件一般不应该使用git resetgit add。有时 可以使这项工作有效,但您会得到奇怪的效果,包括您看到的效果(有时甚至更糟)。预提交脚本应将自身限制为测试提交是否正常,如果是,则退出零;如果不是,脚本应该以非零值退出,而不尝试进行任何更改。1

不要调用您的脚本 .git/pre-commit 并使用 git commit 调用它,而是调用它 makecommit 并使用 makecommit 调用它。或者,将其命名为 git-c 并将其调用为 git c。让脚本执行它的操作——包括 运行 npm lint——如果一切看起来都不错,让它执行 运行 git commit。您根本不需要预提交挂钩,但如果您愿意,您可以使用如下内容:

[ "$RUN_FROM_OUR_SCRIPT" = yes ] && exit 0
echo "don't run git commit directly, run our script instead"
exit 1

然后让您的脚本执行以下操作,而不只是 git commit

RUN_FROM_OUR_SCRIPT=yes git commit

这将设置预提交挂钩测试的变量,以确保 git commit 来自您的脚本 运行。

请注意,您将不再需要从 /dev/tty 重定向 read。 (您可能还应该考虑使用 git reset --soft、and/or 来验证索引内容是否与工作树内容匹配。)


1如果你喜欢危险的生活,并且很想有一个可以更新文件的脚本,确保$GIT_INDEX_FILE 未设置或设置为 .git/index,以确保您未被调用为 git commit --only