【问题标题】:Append ticket number using git commit hooks?使用 git commit 钩子附加票号?
【发布时间】:2011-08-14 23:47:25
【问题描述】:

所以我的分支以 bugtracker 票号命名,类似于“issue-1234”,我们有一个约定,总是在提交消息中写下票号。我想知道是否可以在我处理 issue-* 分支时自动在提交消息中附加票号,而无需我明确输入。

我查看了 git commit 钩子,即 pre-commit、prepare-message 和 post-commit,但似乎没有一个能够做我想做的事情。提交后挂钩接近,但您无法修改使用 -m 提交的消息。

重申一下,我想知道这是否可能:

在分支上:issue-1234

git commit -a -m"fixed this pesky issue"

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

fixed this pesky issue. ticket number: #1234

【问题讨论】:

    标签: git githooks


    【解决方案1】:

    你错过了一个钩子。你要的是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)。您实际上可以在单行提交消息中写入足够的信息是非常非常罕见的。此外,这将使您在提交之前看到消息,以防您的钩子没有完全按照您的意愿行事。

    【讨论】:

    • +1。如果你在一个文件中重定向你的多行注释,做一个git commit --file=myMultiLineCommentFile,你仍然可以使用commit-msghook,对吧?
    • @VonC:commit-msg 钩子在提交时触发 - 除了全自动合并提交(即没有冲突,没有 --no-commit)。不过,这对 OP 来说应该不是问题。 (这确实是一个错误/疏忽。就在最近他们添加了对自动合并的prepare-commit-msg 钩子的支持,但我相信post-commitcommit-msg 仍然缺失。)
    • 我认为git symbolic-ref HEAD 总是以refs/heads 开头而不是issue
    【解决方案2】:

    您也可以使用prepare-commit-msg 钩子,它接受的参数比commit-msg 多。然后,您可以检查消息是否来自文件、模板等,以避免在不需要时附加问题编号。

    当您在名为foo-123 的功能分支中工作时,在.git/hooks/prepare-commit-msg 中使用以下脚本,然后[#123] 将添加到您所做的每个提交的第三行。

    More information in this post I wrote

    #!/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 的预期不太一样,因为它会将故事编号预先添加到提交消息中。如果您在正则表达式中将^ 替换为$,那么它应该适用于这两种情况。
    【解决方案3】:

    这样你可以在提交消息的开头添加分支名称。它是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】:

      另一种选择是使用 git notes 将票号信息添加到提交中,使用您提到的挂钩之一。
      (有关笔记机制的更多信息,请参阅"Notes to self" 博客文章)

      【讨论】:

      • 钩子的问题在于,如果我已经使用 -m 提供了提交消息,它就不起作用了。 prepare-commit-message 钩子仅在启动外部编辑器时起作用
      • @EnToutCas:你的意思是当提交消息通过-m 指定时,你在提交时根本没有执行自己的钩子?
      • +1 对于 VonC 也是如此。能够每天沐浴在新知识中的感觉真好。 Stackoverflow 摇滚,正是 stackoverflow 的人造就了它。
      • Notes 是一个有趣的想法,但是与共享它们相关的缺点有点违背了在提交中添加票证的目的(通常你这样做是为了让远程可以处理这些提交消息并创建链接在工单跟踪系统和给定提交之间)。
      【解决方案5】:

      使用pre-commitgiticket 挂钩,可以很好地在提交中自动包含票号。

      【讨论】:

        【解决方案6】:

        以下是针对任何类型的问题/票证编号提交消息的完整解决方案:

        准备提交消息

        #!/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 并复制到该目录以应用于所有存储库。

        除了其他有用的脚本之外,请参阅my config files repository

        【讨论】:

          【解决方案7】:

          因为这可能对寻求快速解决方案的人有用 - 具有改进的可能性和相当好的可移植性(将它添加到新盒子是简单 bash source git-tricks.sh 的问题)

          我们的分行名称通常采用以下形式: &lt;work-category&gt;/&lt;ticket-id&gt;-&lt;short-description&gt;

          点赞: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 快速添加对 repo 的更改。

          【讨论】:

            猜你喜欢
            • 2017-05-15
            • 2013-01-06
            • 1970-01-01
            • 2014-06-27
            • 2014-02-15
            • 1970-01-01
            • 1970-01-01
            • 2019-06-18
            • 2012-03-09
            相关资源
            最近更新 更多