git - 使用分支名称的一部分扩展提交挂钩
git - extend commit hook with part of branch name
我想使用 prepare-commit-msg 挂钩。我正在使用功能和错误修复分支 (feature/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 >
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
#
我修好了:
#!/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 )
if [ -z "$COMMIT_MSG" ] ; then
exit 0
else
COMMIT_MSG="$COMMIT_MSG - $PRE_COMMIT_MSG"
echo "$COMMIT_MSG" >
fi
fi
引用自the githooks documentation:
This hook is invoked by git commit right after preparing the default log message, and before the editor is started. ... The purpose of the hook is to edit the message file in place, and ...
(我的粗体字)。这意味着你必须按照它说的去做:就地编辑文件。不要只是覆盖它!因此,而不是:
echo $STR >
你可能会这样做:
ed - "" << end
0a
$STR
.
w
q
end
在 "here document" 脚本上运行 ed
编辑器,该脚本包含在第 0 行之后添加 $STR
扩展的指令,然后编写并退出编辑器。 (您可以使用任何编辑器;sed
在这里也很受欢迎。)
顺便说一句,不要这样做:
BRANCH_NAME=$(git branch | grep '*' | sed 's/* //')
因为它过度依赖于各种 "porcelain" 命令输出样式。相反,使用 git symbolic-ref
(通常是脚本的首选方法)或 git rev-parse
。这两者的区别有点哲理:
git symbolic-ref <options> HEAD
获取您当前所在分支的名称,如果您处于特殊的匿名 "detached HEAD" 情况下,则失败。 (您在这里想要的 <options>
只是 --short
以省略 refs/heads/
前缀。)
git rev-parse <options> HEAD
基本上可以保证产生某种成功的名称,因为 HEAD
始终 是一个有效的名称1 因此将对应于 something。它的目的是将 HEAD
变成一个修订散列 ID,但是使用 --symbolic
选项它会留下一个名称 "as symbolic as possible" 而使用 --abbrev-ref
它也会遗漏 refs/heads/
当它这样做时。
主要区别在于当 HEAD 为 "detached" 时 rev-parse
方法不会失败,而 symbolic-ref
方法会失败。失败可以让您区分这种情况,这有时很重要。出于您的目的,它并不是那么重要,并且在使用 symbolic-ref
时,您需要为 "no name for current branch" 分离的 HEAD 案例提供回退。
因此,您想要:
BRANCH_NAME=$(git rev-parse --symbolic --abbrev-ref HEAD)
或:
BRANCH_NAME=$(git symbolic-ref --short HEAD || echo HEAD)
(奇怪的是,这些命令的字节数完全相同)。
1这里有一个极端情况。虽然 HEAD
是 始终有效——如果它无效,则您没有 Git 存储库(Git 会给您一个 "fatal:" 消息)—如果您在 "unborn branch" 上,HEAD
是对不存在的分支名称的符号引用。在这种特殊情况下,git symbolic-ref
将 成功 而 git rev-parse HEAD
将 失败 ,这与更常见的情况相反一个独立的 HEAD。
我想使用 prepare-commit-msg 挂钩。我正在使用功能和错误修复分支 (feature/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 >
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
#
我修好了:
#!/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 )
if [ -z "$COMMIT_MSG" ] ; then
exit 0
else
COMMIT_MSG="$COMMIT_MSG - $PRE_COMMIT_MSG"
echo "$COMMIT_MSG" >
fi
fi
引用自the githooks documentation:
This hook is invoked by git commit right after preparing the default log message, and before the editor is started. ... The purpose of the hook is to edit the message file in place, and ...
(我的粗体字)。这意味着你必须按照它说的去做:就地编辑文件。不要只是覆盖它!因此,而不是:
echo $STR >
你可能会这样做:
ed - "" << end
0a
$STR
.
w
q
end
在 "here document" 脚本上运行 ed
编辑器,该脚本包含在第 0 行之后添加 $STR
扩展的指令,然后编写并退出编辑器。 (您可以使用任何编辑器;sed
在这里也很受欢迎。)
顺便说一句,不要这样做:
BRANCH_NAME=$(git branch | grep '*' | sed 's/* //')
因为它过度依赖于各种 "porcelain" 命令输出样式。相反,使用 git symbolic-ref
(通常是脚本的首选方法)或 git rev-parse
。这两者的区别有点哲理:
git symbolic-ref <options> HEAD
获取您当前所在分支的名称,如果您处于特殊的匿名 "detached HEAD" 情况下,则失败。 (您在这里想要的<options>
只是--short
以省略refs/heads/
前缀。)git rev-parse <options> HEAD
基本上可以保证产生某种成功的名称,因为HEAD
始终 是一个有效的名称1 因此将对应于 something。它的目的是将HEAD
变成一个修订散列 ID,但是使用--symbolic
选项它会留下一个名称 "as symbolic as possible" 而使用--abbrev-ref
它也会遗漏refs/heads/
当它这样做时。
主要区别在于当 HEAD 为 "detached" 时 rev-parse
方法不会失败,而 symbolic-ref
方法会失败。失败可以让您区分这种情况,这有时很重要。出于您的目的,它并不是那么重要,并且在使用 symbolic-ref
时,您需要为 "no name for current branch" 分离的 HEAD 案例提供回退。
因此,您想要:
BRANCH_NAME=$(git rev-parse --symbolic --abbrev-ref HEAD)
或:
BRANCH_NAME=$(git symbolic-ref --short HEAD || echo HEAD)
(奇怪的是,这些命令的字节数完全相同)。
1这里有一个极端情况。虽然 HEAD
是 始终有效——如果它无效,则您没有 Git 存储库(Git 会给您一个 "fatal:" 消息)—如果您在 "unborn branch" 上,HEAD
是对不存在的分支名称的符号引用。在这种特殊情况下,git symbolic-ref
将 成功 而 git rev-parse HEAD
将 失败 ,这与更常见的情况相反一个独立的 HEAD。