如何在pre-commit钩子中可靠获取待创建提交的父提交哈希值
在pre-commit钩子里靠谱拿到待创建提交的父提交哈希
分场景处理就稳了
1. 普通提交和--amend的情况
平时用git rev-parse HEAD就能拿到父提交,但--amend的时候,HEAD指向的是要被替换的旧提交,这时候得拿它的父节点HEAD^。其实不用分别写判断,直接用git rev-parse HEAD@{1}就能通吃:
- 普通提交时,
HEAD@{1}和HEAD是同一个值(因为还没生成新提交,reflog里HEAD的上一条记录就是当前HEAD)。 - 执行
--amend时,HEAD@{1}正好指向旧提交的父节点,完美符合需求。 - 命令示例:
PARENT_COMMIT=$(git rev-parse HEAD@{1} 2>/dev/null)
2. 变基(rebase)场景
变基的时候情况特殊,这时候可以通过检查Git的临时目录来判断:如果.git/rebase-merge或者.git/rebase-apply目录存在,就说明正在变基。这时候待创建提交的父提交就是当前的HEAD,因为变基是在新基础上逐个应用提交,当前HEAD就是你要修改的提交的父节点。
- 判断+取值的代码:
if [ -d "$(git rev-parse --git-dir)/rebase-merge" ] || [ -d "$(git rev-parse --git-dir)/rebase-apply" ]; then PARENT_COMMIT=$(git rev-parse HEAD) fi
3. 初始提交(没父节点)的容错
如果是仓库的第一个提交,根本没有父节点,得加个判断避免报错:
if [ -z "$PARENT_COMMIT" ]; then COMMIT_COUNT=$(git rev-list --count HEAD 2>/dev/null) if [ "$COMMIT_COUNT" -eq 0 ]; then echo "注意:这是仓库的第一个提交,没有父节点" PARENT_COMMIT="" # 或者根据你的测试逻辑设个默认值 else PARENT_COMMIT=$(git rev-parse HEAD) fi fi
完整的钩子脚本示例
#!/bin/sh PARENT_COMMIT="" # 先判断是不是在变基 if [ -d "$(git rev-parse --git-dir)/rebase-merge" ] || [ -d "$(git rev-parse --git-dir)/rebase-apply" ]; then PARENT_COMMIT=$(git rev-parse HEAD) else # 拿HEAD@{1}处理普通提交和amend PARENT_COMMIT=$(git rev-parse HEAD@{1} 2>/dev/null) # 处理初始提交的情况 if [ -z "$PARENT_COMMIT" ]; then COMMIT_COUNT=$(git rev-list --count HEAD 2>/dev/null) if [ "$COMMIT_COUNT" -eq 0 ]; then echo "警告:当前是初始提交,无父提交" PARENT_COMMIT="" else PARENT_COMMIT=$(git rev-parse HEAD) fi fi fi # 输出父提交哈希,方便调试 echo "待创建提交的父提交哈希:$PARENT_COMMIT" # 这里放你的测试逻辑,用PARENT_COMMIT变量就行 # ... # 测试失败的话返回非0值,终止提交 # exit 1
内容的提问来源于stack exchange,提问作者Piotr Siupa
相关产品推荐
相关产品推荐

