使用git提交钩子添加票号?

31
所以我的分支名称是根据错误追踪票号命名的,类似于“issue-1234”,我们有一个惯例,在提交信息中始终写下票号。我想知道是否可以在我处理问题-*分支时自动将票号附加到提交消息中,而无需我显式输入它。我查看了git提交钩子,即pre-commit, prepare-message和post-commit,并且它们都似乎无法做到我想要的事情。 Post-commit hook接近,但是您无法修改使用-m提交的消息。再次强调,我想知道这是否可能:在分支上:issue-1234
git commit -a -m"fixed this pesky issue"

提交后,在git log中,消息显示为:

fixed this pesky issue. ticket number: #1234
7个回答

24

你错过了一个钩子。你想要的是 commit-msg 钩子:

这个钩子由 git commit 调用,可以通过 --no-verify 选项绕过。它接受一个参数,即保存建议提交日志消息的文件名。以非零状态退出将导致 git commit 中止。

例如:

#!/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)进行提交。很少情况下你可以在单行提交消息中编写足够的信息。此外,在提交之前,这将让你看到消息,以防钩子没有完全达到你的预期。


如果您将多行注释重定向到文件中,然后执行git commit --file=myMultiLineCommentFile命令,是否仍然可以使用commit-msg钩子呢? - VonC
@VonC:每次提交时都会触发commit-msg钩子 - 除了完全自动合并提交(即没有冲突,没有--no-commit)。但这对于OP来说不应该是问题。(这实际上是一个小错误/疏忽。最近他们为自动合并添加了prepare-commit-msg 钩子的支持,但我认为 post-commitcommit-msg 仍然缺失。) - Cascabel
我认为 git symbolic-ref HEAD 始终以 refs/heads 开头,而不是 issue - xi.lin
-m 可以多次使用,每次都会向提交消息中添加一行新的内容。这是我大多数时候提交代码的方式;传递给 -m 的字符串本身也可以是一个多行字符串,但其构造方式取决于所使用的 shell。 - Alex Povel

8
您还可以使用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

这个代码在使用 commit -m 命令时无法按预期工作,因为它会在提交信息前加上故事编号。如果你将正则表达式中的 ^ 替换为 $,那么它就可以在两种情况下都正常工作。 - Geekfish

4

这样可以在提交信息的开头添加分支名称。这是通过使用prepare-commit-msg钩子实现的。 它适用于“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

4
使用pre-commitgiticket钩子一起使用,可以很好地自动将票号添加到提交中。

2

这是一个针对任何问题/工单编号提交信息的完整解决方案:

prepare-commit-msg

#!/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并将其复制到该目录中,以应用于您所有的存储库。
请参见我的配置文件存储库,其中包括其他有用的脚本。

2
另一个选项是使用git notes,通过你提到的钩子之一,将票号信息添加到提交中。
(有关注释机制的更多信息,请参见"笔记"博客文章条目)

钩子的问题在于,如果我已经使用-m提供了提交消息,它实际上不起作用。只有在启动外部编辑器时,prepare-commit-message钩子才起作用。 - EnToutCas
@EnToutCas:你的意思是当通过“-m”指定提交消息时,你根本没有钩子可以执行吗? - VonC
+1 对于 VonC 也是如此。每天都能沐浴在新知识中真是一种美妙的感觉。Stackoverflow 真的很棒,正是 Stackoverflow 的人们让它变得如此。 - ralphtheninja
注释是一个有趣的想法,但与共享它们相关的缺点有点违背了将票号添加到提交中的目的(通常你这样做是为了让远程处理这些提交消息并在票务跟踪系统和给定提交之间创建链接)。 - Adam Parkin

0

如果有人正在寻找快速解决方案,这可能会很有用-具有改进和相当好的可移植性(将其添加到新框中只是一个简单的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快速添加更改到仓库中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接