Git分支命名策略管控:rebase-merge与rebase-apply目录差异问题
Git分支命名钩子在变基时失效的解决方案
问题根源
Git的变基分为两种模式,对应不同的临时目录:
- 交互式变基(带
-i参数)会生成.git/rebase-merge目录,通过其中的head-name文件保存原分支名称 - 普通变基(无
-i参数)会生成.git/rebase-apply目录,原分支的哈希值存在orig-head文件中,需要通过Git命令转成分支名
你的脚本只处理了交互式变基的情况,普通变基时找不到rebase-merge目录,导致错误获取分支名(拿到分离状态的HEAD),进而触发分支名校验失败。
解决方案
可以同时检查两种变基目录,针对不同变基模式获取原分支名,以下是修改后的完整钩子脚本:
修改后的钩子脚本
#!/usr/bin/env sh # # Enforce branch naming policy LC_ALL=C top_level=$(git rev-parse --show-toplevel) local_branch="" # 处理交互式变基场景 rebase_merge_head="${top_level}/.git/rebase-merge/head-name" if [[ -f ${rebase_merge_head} ]]; then local_branch=$(<${rebase_merge_head}) local_branch=${local_branch#"refs/heads/"} # 处理普通变基场景 elif [[ -d ${top_level}/.git/rebase-apply ]]; then orig_head_hash=$(<${top_level}/.git/rebase-apply/orig-head) # 将哈希值转换为分支名,去除远程分支前缀(如果存在) local_branch=$(git name-rev --name-only ${orig_head_hash} | sed 's|^remotes/[^/]*/||') # 正常分支场景 else local_branch=$(git rev-parse --abbrev-ref HEAD) fi valid_branch_regex="^(main|((feature|bugfix|improvement|library|prerelease|refactoring|release|hotfix)\/[a-z0-9._-]+))$" if ! [[ ${local_branch} =~ ${valid_branch_regex} ]]; then message="分支名称 ${local_branch} 不符合规范。\ 本项目分支名必须遵循规则:${valid_branch_regex}。\ 提交将被拒绝,请重命名分支后重试。" echo "${message}" >&2 exit 1 fi
关键改进点
- 新增普通变基场景的处理:读取
rebase-apply/orig-head的哈希值,通过git name-rev转换为分支名,再去除可能的远程分支前缀 - 统一分支名获取逻辑,覆盖正常分支、交互式变基、普通变基三种场景
- 补充了校验失败后的退出逻辑(原脚本缺少
exit 1,可能导致校验不生效)
更优实现思路
如果想进一步简化脚本,可以利用Git的git branch --contains结合orig-head哈希直接匹配分支,但上述修改已经能覆盖绝大多数场景,且逻辑清晰易维护。
内容的提问来源于stack exchange,提问作者loris
相关产品推荐
相关产品推荐

