【问题标题】:Git post-recieve hookGit post-receive 钩子
【发布时间】:2026-01-10 07:15:02
【问题描述】:

我需要帮助来编写一个 git post-receive 钩子。

我需要 hook 来调用外部 .exe 文件并传入参数。

到目前为止,这是我的钩子:

#!/bin/sh

call_external()
{
     # --- Arguments
     oldrev=$(git rev-parse $1)
     newrev=$(git rev-parse $2)
     refname="$3"

     DIR="$(cd "$(dirname "$0")" && pwd)"

     $DIR/post-receive.d/External.exe
 }

 # --- Main loop


while read oldrev newrev refname
do
    call_external  $oldrev $newrev $refname 
done

它工作得很好,除了我需要将一些参数传递给那个 exe,而且我不知道如何从 Git 中获取它们。

感谢 'phd' 更新: 我每次推送都需要这些参数

  • 作者/电子邮件
  • 提交哈希
  • 提交说明
  • 分公司名称

我不知道如何从 GIT 获取此信息。

编辑(2021-04-22) 多亏了“博士”,我才能拼凑起来

#!/bin/sh
call_external()
{
    # --- Arguments
    oldrev=$(git rev-parse $1)
    newrev=$(git rev-parse $2)
    refname="$3"
    
    if [ $(git rev-parse --is-bare-repository) = true ]
    then
        REPOSITORY_BASENAME=$(basename "$PWD") 
    else
        REPOSITORY_BASENAME=$(basename $(readlink -nf "$PWD"/..))
    fi
    
    DIR="$(cd "$(dirname "$0")" && pwd)"
    BRANCH=$refname

    git rev-list "$oldrev..$newrev"|
    while read hash 
    do
    
        COMMIT_HASH=$hash
        AUTHOR_NAME=$(git show --format="%an" -s)
        AUTHOR_EMAIL=$(git show --format="%ae" -s)
        COMMIT_MESSAGE=$(git show --format="%B" -s)
    
        $($DIR/post-receive.d/External.exe "$BRANCH" "$AUTHOR_NAME" "$AUTHOR_EMAIL" "$COMMIT_MESSAGE" "$COMMIT_HASH" "$REPOSITORY_BASENAME")
        
    done
}

 # --- Main loop
while read oldrev newrev refname
do
    call_external  $oldrev $newrev $refname 
done

【问题讨论】:

  • "推动提交的人的电子邮件" 什么是提交?更新引用时调用钩子; oldrevnewrev 之间可能有一百个提交。 "提交编号#" 编号是多少?提交哈希? “描述/评论” 再说一遍,这是什么?提交消息? "Repository name" 你不能从 git 得到这个——它不存储存储库名称。可以从OS获取顶层目录的名称,仅此而已。

标签: git sh githooks


【解决方案1】:

每次推送中的每个提交都需要这些参数

Commit hash

运行以下循环:

git rev-list oldrev..newrev | while read hash; do echo $hash; done

循环内部$hash 是一个提交的哈希值。

Author/Email

那是git show --format="%an" -sgit show --format="%ae" -s%an 表示“作者姓名”,%ae — “作者电子邮件”。查看占位符列表https://git-scm.com/docs/git-show#_pretty_formats

Commit description

git show --format="%B" -s。那是“提交消息的全文”。可以拆分成%s%b

Branch name

你不需要循环使用它,你总是拥有它。更新引用时调用 post-receive 钩子,引用是分支。 refname 在你的脚本中。

让我把所有这些组合成一个循环:

git rev-list oldrev..newrev |
while read hash; do
    echo Commit hash: $hash
    echo Author name: git show --format="%an" -s
    echo Author email: git show --format="%ae" -s
    echo Commit message: git show --format="%B" -s
done

【讨论】:

  • 谢谢,我用完成的脚本更新了我的问题。