因此,我的分支以 bugtracker 票号命名,例如“issue-1234”,并且我们有一个约定,即始终在提交消息中写下票号。我想知道当我在 issues-* 分支上工作时是否可以自动将票号附加到提交消息中,而无需我显式键入它。
我查看了 git commit hooks,即预提交、准备消息和后提交,它们似乎都不能做我想要的事情。提交后挂钩已接近,但您无法修改使用 -m 提交的消息。
重申一下,我想知道这是否可能:
在分支上:issue-1234
git commit -a -m"fixed this pesky issue"
提交后,在 git log 中,显示消息为:
fixed this pesky issue. ticket number: #1234
你错过了一个钩子。你想要的是
commit-msg
:
该钩子由 git commit 调用,可以使用 --no-verify 选项绕过。它采用单个参数,即保存建议的提交日志消息的文件的名称。以非零状态退出会导致 git 提交中止。
举个例子:
#!/bin/sh
ticket=$(git symbolic-ref HEAD | awk -F- '/^issue-/ {print $2}')
if [ -n "$ticket" ]; then
echo "ticket #$ticket" >> $1
fi
这是对分支名称的非常幼稚的解析,它只是附加到自己的行上的提交消息中。如果这对您来说不够好,请修改它。
当然,我实际上建议在
prepare-commit-msg
中执行此操作,并使用 git commit
进行提交(不使用 -m
)。您实际上可以在单行提交消息中写入足够的信息,这是非常非常罕见的。此外,这将使您在提交之前看到消息,以防您的钩子没有达到您想要的效果。
您也可以使用
prepare-commit-msg
钩子,它比 commit-msg
接受更多的参数。然后您可以检查消息是否来自文件、模板等,以避免在您不需要时附加问题编号。
使用
.git/hooks/prepare-commit-msg
中的以下脚本,当您在名为 foo-123
的功能分支中工作时,[#123]
将被添加到您所做的每个提交的第三行。
#!/bin/sh
if [ x = x${2} ]; then
BRANCH_NAME=$(git symbolic-ref --short HEAD)
STORY_NUMBER=$(echo $BRANCH_NAME | sed -n 's/.*-\([0-9]\)/\1/p')
if [ x != x${STORY_NUMBER} ]; then
sed -i.back "1s/^/\n\n[#$STORY_NUMBER]/" "$1"
fi
fi
通过这种方式,您可以将分支名称添加到提交消息的开头。这是准备提交消息钩子。 适用于“git commit -m”和“git commit”命令。该选项是文件 .git/hooks/pre-commit.skip,其中包含您不想自动添加的分支列表。
BRANCH="$(git rev-parse --abbrev-ref HEAD)"
FILE_CONTENT="$(cat $1)"
skip_list=`git rev-parse --git-dir`"/hooks/pre-commit.skip"
if grep -E "^$BRANCH$" $skip_list; then
exit
fi
if [ $2 = "message" ]; then
echo $BRANCH: $FILE_CONTENT > $1
else
echo $BRANCH: > $1
echo $FILE_CONTENT >> $1
fi
使用 pre-commit 以及 giticket 钩子,可以很好地自动在提交中包含票号。
这是针对任何类型的问题/票据编号提交消息的完整解决方案:
准备提交消息
#!/bin/bash
# Append issue number / bug tracking URL to commit.
#
# If the branch name contains the issue number, it will append it to the
# commit message. Example:
#
# BRANCH NAME LINE TO APPEND
# feature/GH-123-emoji GitHub: #123
# WRIKE-123-add-payment Wrike: https://www.wrike.com/open.htm?id=123
# UNKNOWN-123 Issue: #123
branchName=`git rev-parse --abbrev-ref HEAD`
IFS=- read issueTracker issueNumber <<< $(echo $branchName | sed -nr 's,([a-z-]+/)?([A-Z]+-[0-9]+)-.+,\2,p')
if [[ -z $issueNumber ]]; then
exit 0
fi
case "$issueTracker" in
WRIKE)
line="Wrike: https://www.wrike.com/open.htm?id=$issueNumber"
;;
GH)
line="GitHub: #$issueNumber"
;;
GL)
line="GitLab: #$issueNumber"
;;
*)
line="Issue: #$issueNumber"
;;
esac
# If the commit message already contains the line (`--amend`), then do
# not add it again.
if ! ( grep "$line" "$1" > /dev/null ); then
sed -i.bak -e "/# Please enter the commit message for your changes./ s,^,$line\n\n," $1
fi
将其放入存储库的
.git/hooks
目录中以仅应用于存储库,或在 ~/.gitconfig
中设置 core.hooksPath并复制到该目录以应用于所有存储库。
除了其他有用的脚本之外,请参见我的配置文件存储库。
因为这对于寻求快速解决方案的人来说可能很有用 - 具有改进的可能性和相当好的可移植性(将其添加到新盒子中只需简单的 bash
source git-tricks.sh
)
我们的分支名称通常采用以下形式:
<work-category>/<ticket-id>-<short-description>
喜欢:
bug/ID-1234-bad-button-color
然后我有以下别名:
alias git-branch-name='git rev-parse --abbrev-ref HEAD'
bug/ID-1234-bad-button-color
alias git-branch-ticket='git-branch-name | grep -oP "^[^/]*/\K[^-]*-[0-9]+"'
ID-1234
(如果问题的作者应该是:'git-branch-name | grep -oP "^issue-\K[0-9]+"'
)最后一个:
alias git-describe-commit='git commit --all --edit --message "[$(git-branch-ticket)] --edit this--"'
这允许我使用
git-describe-commit
快速添加对存储库的更改。