Git pre-receive脚本处理新分支遇bad object错误,如何解决?
解决pre-receive钩子推送新分支时的"bad object"错误
首先咱们来拆解下你遇到的问题:当推送新分支时,Git传给pre-receive钩子的old_sha是一串全0的ID(0000000000000000000000000000000000000000),这是因为这个分支在远程仓库之前完全不存在。而你的原脚本直接用git diff "$old_sha" "$new_sha",Git找不到这个全0的空对象,自然就抛出了"fatal: bad object"错误。
修改后的pre-receive脚本
我们只需要在脚本里加个判断,专门处理old_sha为全0的新分支推送场景:
#!/bin/bash while read old_sha new_sha refname do # 处理新分支:old_sha为空对象时,检查整个分支的所有内容 if [ "$old_sha" = "0000000000000000000000000000000000000000" ]; then if git diff-tree -r "$new_sha" | grep -qE '^\+(<<<<<<<|>>>>>>>)'; then echo "Error: Conflict marker found in new branch $(basename "$refname")!" git diff-tree -r "$new_sha" | grep -nE '^\+(<<<<<<<|>>>>>>>)' exit 1 fi else # 处理已有分支更新:检查新旧SHA之间的代码差异 if git diff "$old_sha" "$new_sha" | grep -qE '^\+(<<<<<<<|>>>>>>>)'; then echo "Error: Conflict marker found in $(basename "$refname")!" git diff "$old_sha" "$new_sha" | grep -nE '^\+(<<<<<<<|>>>>>>>)' exit 1 fi fi done exit 0
关于是否替换为update钩子
其实完全不需要替换!pre-receive和update钩子的核心差异是:
- pre-receive会一次性接收本次推送的所有引用(比如同时推多个分支/标签),适合做全局统一检查
- update钩子会为每个推送的引用单独运行一次,适合针对单个分支做更细粒度的控制
两种钩子都能处理新分支场景,只要正确判断old_sha是否为全0即可。如果你只是需要阻止带冲突标记的推送,修改现有pre-receive脚本就足够满足需求。
内容的提问来源于stack exchange,提问作者Eugen Konkov
相关产品推荐
相关产品推荐

