You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows Bash下Git提交钩子重复添加任务代码的问题排查

解决Git钩子中amend操作重复添加任务代码的问题

我明白你遇到的麻烦——用Git钩子自动给提交信息加分支里的任务代码时,执行git commit --amend会重复添加前缀,导致提交消息变得乱糟糟的。咱们一步步来把这个问题搞定。

最初的脚本问题

你一开始的脚本核心逻辑是对的:提取分支里的任务代码,给提交消息加前缀,但它缺少了关键的判断步骤——没有检查提交消息里是否已经存在这个前缀,所以每次amend都会再添一遍。

#!/bin/bash
# Include any branches for which you wish to disable this script
if [ -z "$BRANCHES_TO_SKIP" ]; then
 BRANCHES_TO_SKIP=(master develop)
fi
# Get the current branch name and check if it is excluded
BRANCH_NAME=$(git symbolic-ref --short HEAD)
BRANCH_EXCLUDED=$(printf "%s\n" "${BRANCHES_TO_SKIP[@]}" | grep -c "^$BRANCH_NAME$")
# Trim it down to get the parts we're interested in
TRIMMED=$(echo $BRANCH_NAME | sed -e 's:\([a-z]\+\/\)*\([A-Z]\+-[0-9]\+\).\+:\2:')
# If it isn't excluded, preprend the trimmed branch identifier to the given message
if [ -n "$BRANCH_NAME" ] &&! [[ $BRANCH_EXCLUDED -eq 1 ]]; then
 sed -i.bak -e "1s,^,$TRIMMED: ," $1
fi

你修改时犯的错误

你参考了Windows CMD的脚本,但忘了当前用的是Bash(Shell脚本),两者语法完全不兼容:

  • CMD里的set 变量|find "字符串"是用来查找变量内容里的字符串,但Bash里的set是用来配置Shell选项的,根本不是输出变量值的命令。
  • Bash里的find命令是用来搜索文件系统中的文件的,不是用来在字符串或文本里查找内容的,所以你写的set BRANCH_NAME|find "$TRIMMED"会被解析成“查找名为LG-132的文件”,自然会报错找不到文件。

正确的修改方案

我们需要用Bash的方式检查提交消息文件(也就是脚本参数$1指向的临时文件)里是否已经有任务代码前缀。这里用grep命令最适合,它可以直接搜索文件内容:

修改后的完整脚本

#!/bin/bash
# Include any branches for which you wish to disable this script
if [ -z "$BRANCHES_TO_SKIP" ]; then
 BRANCHES_TO_SKIP=(master develop)
fi
# Get the current branch name and check if it is excluded
BRANCH_NAME=$(git symbolic-ref --short HEAD)
BRANCH_EXCLUDED=$(printf "%s\n" "${BRANCHES_TO_SKIP[@]}" | grep -c "^$BRANCH_NAME$")
# Trim it down to get the parts we're interested in
TRIMMED=$(echo "$BRANCH_NAME" | sed -e 's:\([a-z]\+\/\)*\([A-Z]\+-[0-9]\+\).\+:\2:')
# If it isn't excluded, check if message already has the prefix before adding
if [ -n "$BRANCH_NAME" ] &&! [[ $BRANCH_EXCLUDED -eq 1 ]]; then
  # 检查提交消息的第一行是否已以任务代码前缀开头
  if! grep -q "^$TRIMMED:" "$1"; then
    # 如果没有,就给第一行添加前缀
    sed -i.bak -e "1s,^,$TRIMMED: ," "$1"
  fi
fi

关键修改点解释

  1. 用grep检查文件内容:grep -q "^$TRIMMED:" "$1" 里的-q是静默模式,不会输出内容,只返回退出码:
    • 如果提交消息文件里有以$TRIMMED:开头的行(比如LG-132:),grep返回0,!取反后条件不成立,跳过添加操作。
    • 如果没有找到匹配的行,grep返回非0,!取反后条件成立,执行sed添加前缀。
  2. 引号包裹变量:把echo $BRANCH_NAME改成echo "$BRANCH_NAME",避免分支名称里有空格时出现解析错误。
  3. 精准匹配前缀:用^$TRIMMED: 匹配行开头的前缀,这样可以避免提交消息中间出现相同任务代码时的误判。

这样修改后,不管你执行多少次git commit --amend,都只会在第一次添加前缀,不会重复叠加了。

内容的提问来源于stack exchange,提问作者Alex Ironside

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:00:00