如何让Git commmit-msg钩子仅针对git commit执行特定逻辑?
解决commit-msg钩子被非commit操作触发的问题
可以通过检查Git的操作上下文,在钩子脚本中判断当前是否是git commit触发的场景,从而跳过其他操作的逻辑。以下是两种实用方案:
方案一:检测合并/变基状态
Git在执行merge、pull(需合并时)、rebase等操作时,会在仓库内生成临时标记文件,我们可以用git rev-parse命令检测这些状态,直接跳过钩子逻辑:
# 检查是否处于合并操作 if git rev-parse --is-inside-merge >/dev/null 2>&1; then exit 0 fi # 检查是否处于变基操作 if git rev-parse --is-inside-rebase >/dev/null 2>&1; then exit 0 fi # 此处放置你的commit-msg原有逻辑,仅在git commit时执行 # 示例:校验提交信息格式 if ! grep -E "^feat|fix|docs|style|refactor|test|chore:" "$1"; then echo "错误:提交信息必须以指定类型开头(feat/fix/docs等)" exit 1 fi
这种方法无需依赖系统进程工具,兼容性更好,能覆盖绝大多数非手动commit的场景。
方案二:追踪父进程判断触发命令
如果需要更精准判断是否是git commit命令触发,可以遍历父进程栈,找到发起钩子的Git命令:
current_pid=$$ # 向上遍历父进程,查找Git进程 while true; do parent_pid=$(ps -o ppid= -p "$current_pid" | xargs) if [ "$parent_pid" -eq 1 ]; then # 未找到git commit,直接退出 exit 0 fi cmd_name=$(ps -o comm= -p "$parent_pid") if [ "$cmd_name" = "git" ]; then git_args=$(ps -o args= -p "$parent_pid") # 检查Git命令参数是否包含commit if echo "$git_args" | grep -q "commit"; then # 确认是git commit触发,执行后续逻辑 break else exit 0 fi fi current_pid=$parent_pid done # 此处放置你的commit-msg原有逻辑
注意:这种方法依赖ps命令,不同操作系统(如Linux/macOS)的输出格式可能略有差异,需根据实际环境调整。
内容的提问来源于stack exchange,提问作者wasp256
相关产品推荐
相关产品推荐

