问题 使用部分分支名称前置Git提交消息


我目前的分支命名约定是这样的:

ticket-45-my-new-feature-branch-description

我目前在我的.git / hooks / prepare-commit-msg文件中使用此代码来为每个提交消息添加分支名称,如下所示:

BRANCH_NAME=$(git branch 2>/dev/null | grep -e ^* | tr -d ' *')
if [ -n "$BRANCH_NAME" ] && [ "$BRANCH_NAME" != "master" ]; then
    echo "[$BRANCH_NAME] $(cat $1)" > $1
fi

最终结果:

[ticket-45-my-new-feature-branch-description] test commit

我想要完成的是这样输出:

[ticket-45] test commit

布朗尼指出,如果我们可以利用它:

[TICKET-45] test commit

我希望保留我的描述性分支名称,但在提交消息中截断前置文本。我确定我必须使用一些正则表达式,但我真的不知道如何实现这一点。我应该提一下,我们有几个项目同时进行,所以分支名称是不同的,如下所示:

ticket-123-branch-name
abc-22-my-branch
ua-11-my-feature

唯一的共同点是我需要在第二个' - '之前的所有内容。

任何帮助是极大的赞赏!!!


4008
2017-11-09 01:53


起源



答案:


好的,首先,这个:

BRANCH_NAME=$(git branch 2>/dev/null | grep -e ^* | tr -d ' *')

是主要的矫枉过正:-)使用:

branch=$(git symbolic-ref --short HEAD) || ...

获取当前分支名称。之后的部分 || 是“如果你不在一个分支上该怎么办”(即,如果你处于“超级头”模式) - 你必须自己决定。 (您当前的代码将BRANCH_NAME设置为空字符串;为此,您甚至不需要 || 部分,但您可能想要添加 -q或者a 2>/dev/null,以避免symbolic-ref中的“致命:”消息。)

其余的只是基本的脚本。在bash中你可以直接使用正则表达式,在旧的sh你可以调用 expr 要么 sed。都 sed 和 tr 可以大写ife,但sed也可以做一个正则表达式,所以它看起来像一个很好的候选人:

$ trimmed=$(echo $branch | sed -e 's:^\([^-]*-[^-]*\)-.*:\1:' -e \
    'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/')
$ echo $trimmed
TICKET-45

最后,这样做有点危险:

echo "some stuff $(cat $1)" > $1

因为你依靠shell来扩展 $(cat $1) 在它截断输出文件之前 > $1 部分。 (显然它有效,但你受到了变幻莫测的影响。)最好使用一个临时文件,或者另一个 sed 但就地:

sed -i .bak -e "1s:^:[$trimmed] :" $1
# or use -i '', but note minor warning in sed man pages

以上只是零碎测试,但应该有效。


15
2017-11-09 02:25



这就像一个魅力。谢谢你的详细信息! - gjunkie
上面发布的脚本很可能来自我的博客,所以对我来说都是耻辱。非常感谢torek详细解释。现在我可以称自己为“更好的shell n00b”:)我将根据您的建议更新我的博客。 - bartosz.majsak
@ bartosz.majsak:嘿,每个人都要从某个地方开始:-) - torek
branch=$(git symbolic-ref --short HEAD) $trimmed=$(echo $branch | sed -e 's/^\([^-]*-[^-]*\)-.*/\1/' -e \ 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/') sed -i .bak -e "1s/^/[$trimmed] /" $1  - 这会产生这样的提交消息:[]我的通信消息。可能是什么原因? - alex
@alex:你上面的引用了 $trimmed= 而不是 trimmed= (但如果我这样做,我会得到类似的东西 =...: command not found 所以我不确定你的原件是什么的。 - torek


答案:


好的,首先,这个:

BRANCH_NAME=$(git branch 2>/dev/null | grep -e ^* | tr -d ' *')

是主要的矫枉过正:-)使用:

branch=$(git symbolic-ref --short HEAD) || ...

获取当前分支名称。之后的部分 || 是“如果你不在一个分支上该怎么办”(即,如果你处于“超级头”模式) - 你必须自己决定。 (您当前的代码将BRANCH_NAME设置为空字符串;为此,您甚至不需要 || 部分,但您可能想要添加 -q或者a 2>/dev/null,以避免symbolic-ref中的“致命:”消息。)

其余的只是基本的脚本。在bash中你可以直接使用正则表达式,在旧的sh你可以调用 expr 要么 sed。都 sed 和 tr 可以大写ife,但sed也可以做一个正则表达式,所以它看起来像一个很好的候选人:

$ trimmed=$(echo $branch | sed -e 's:^\([^-]*-[^-]*\)-.*:\1:' -e \
    'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/')
$ echo $trimmed
TICKET-45

最后,这样做有点危险:

echo "some stuff $(cat $1)" > $1

因为你依靠shell来扩展 $(cat $1) 在它截断输出文件之前 > $1 部分。 (显然它有效,但你受到了变幻莫测的影响。)最好使用一个临时文件,或者另一个 sed 但就地:

sed -i .bak -e "1s:^:[$trimmed] :" $1
# or use -i '', but note minor warning in sed man pages

以上只是零碎测试,但应该有效。


15
2017-11-09 02:25



这就像一个魅力。谢谢你的详细信息! - gjunkie
上面发布的脚本很可能来自我的博客,所以对我来说都是耻辱。非常感谢torek详细解释。现在我可以称自己为“更好的shell n00b”:)我将根据您的建议更新我的博客。 - bartosz.majsak
@ bartosz.majsak:嘿,每个人都要从某个地方开始:-) - torek
branch=$(git symbolic-ref --short HEAD) $trimmed=$(echo $branch | sed -e 's/^\([^-]*-[^-]*\)-.*/\1/' -e \ 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/') sed -i .bak -e "1s/^/[$trimmed] /" $1  - 这会产生这样的提交消息:[]我的通信消息。可能是什么原因? - alex
@alex:你上面的引用了 $trimmed= 而不是 trimmed= (但如果我这样做,我会得到类似的东西 =...: command not found 所以我不确定你的原件是什么的。 - torek