git - 使用部分名称扩展commit hook

时间:2016-08-03 11:56:58

标签: git jira bitbucket githooks

我想使用 prepare-commit-msg 挂钩。我正在使用功能和bugfix分支(功能/ ISSUEKEY-23123-some-feature),我想在提交消息中添加ISSUEKEY-23123:

#!/bin/bash
BRANCH_NAME=$(git branch | grep '*' | sed 's/* //')
STR=`echo $BRANCH_NAME | grep -E 'ISSUEKEY-[0-9]*' -o`
if [[ $BRANCH_NAME == *"feature"* ]] || [[ $BRANCH_NAME == *"bugfix"* ]]
then
    echo $STR > $1
fi

这有效,但它丢弃了标准消息vi向我显示提交,例如:

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Explicit paths specified without -i or -o; assuming --only paths...
# On branch feature/ISSUEKEY-1716-model-implement
# Your branch is based on 'origin/feature/ISSUEKEY-1716-model-implement', but the upstream is gone.
#   (use "git branch --unset-upstream" to fixup)
#
# Changes to be committed:
#       new file:   asd
#
# Untracked files:
#       FSTD-1716
#       TMP
#

有没有办法将STR添加到输出中,或调用git命令打印我提到的标准提交消息?

打开的提交消息应为:

ISSUEKEY-1716 
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Explicit paths specified without -i or -o; assuming --only paths...
# On branch feature/ISSUEKEY-1716-model-implement
# Your branch is based on 'origin/feature/ISSUEKEY-1716-model-implement', but the upstream is gone.
#   (use "git branch --unset-upstream" to fixup)
#
# Changes to be committed:
#       new file:   asd
#
# Untracked files:
#       FSTD-1716
#       TMP
#

2 个答案:

答案 0 :(得分:2)

引自the githooks documentation

  

在准备默认日志消息之后,以及在编辑器启动之前, git commit 会调用此挂接。 ...钩子的目的是编辑消息文件,然后......

(粗体我的)。这意味着您必须按照说法执行操作:编辑文件。不要只是覆盖它!因此,而不是:

echo $STR > $1
你可能会这样做:

ed - "$1" << end
0a
$STR
.
w
q
end

在“here document”脚本上运行ed编辑器,该脚本包含在第0行之后添加$STR扩展的指令,然后编写并退出编辑器。 (您可以使用任何编辑器; sed也很受欢迎。)

顺便说一句,不要这样做:

BRANCH_NAME=$(git branch | grep '*' | sed 's/* //')

因为它过分依赖各种“瓷器”命令输出样式。相反,请使用git symbolic-ref(通常是脚本的首选方法)或git rev-parse。这两者之间的区别有点哲学:

  • git symbolic-ref <options> HEAD获取您当前所在分支的名称,如果您使用的是特殊的匿名“分离HEAD”案例,则会失败。 (此处您需要的<options>--short可省略refs/heads/前缀。)

  • git rev-parse <options> HEAD主要保证会产生某种成功的名称,因为HEAD 总是有效名称 1 和因此将对应某事。这意味着将HEAD转换为修订哈希ID,但使用--symbolic选项时,它会留下“尽可能符号”的名称,而--abbrev-ref则会遗漏refs/heads/当它这样做时。

关键的区别在于,当HEAD“分离”时,rev-parse方法不会失败,而symbolic-ref方法会失败。失败让您区分这种情况,这有时很重要。出于您的目的,它并不那么重要,当使用symbolic-ref时,您需要为“当前分支的无名称”分离HEAD案例的后备。

因此,你想要:

BRANCH_NAME=$(git rev-parse --symbolic --abbrev-ref HEAD)

或:

BRANCH_NAME=$(git symbolic-ref --short HEAD || echo HEAD)

(奇怪的是,这些命令的字节数完全相同)。

1 这里有一个角落案例。虽然HEAD 总是有效 - 如果它无效,你就没有Git存储库(Git会给你一个“致命:”的消息) - 如果你在“未出生的分支”,HEAD是对不存在的分支名称的符号引用。在这种特殊情况下,git symbolic-ref成功git rev-parse HEAD失败,这是从分离的HEAD的更常见情况向后退。

答案 1 :(得分:0)

我修好了它:

#!/bin/bash

BRANCH_NAME=$(git branch | grep '*' | sed 's/* //')
COMMIT_MSG=`echo $BRANCH_NAME | grep -E 'ISSUEKEY-[0-9]*' -o`
if [[ $BRANCH_NAME == *"feature/"* ]] || [[ $BRANCH_NAME == *"bugfix/"* ]]
then
    PRE_COMMIT_MSG=$(cat $1)
    if [ -z "$COMMIT_MSG" ] ; then
        exit 0
    else
        COMMIT_MSG="$COMMIT_MSG - $PRE_COMMIT_MSG"
        echo "$COMMIT_MSG" > $1
    fi
fi