Back to home

为Git添加提交邮件通知

为Git添加提交邮件通知

Introduction

为Git repository 添加hook,每次commit 时发送一封diff email

Procedure

  1. 拷贝Git-core自带的post-receive-email Shell 脚本

    mv YOUR_REPO_PATH/hooks/post-receive YOUR_REPO_PATH/hooks/post-receive.back cp PATH/TO/GIT-CORE/contrib/hooks/post-receive-email YOUR_REPO_PATH/hooks/post-receive chmod a+x YOUR_REPO_PATH/hooks/post-receive

  2. 设置 Git repository 的config

    vi YOUR_REPO_PATH/config

    [hooks] mailinglist = “Receive1@email.address,Receive2@email.address” emailprefix = “[git]” announcelist = envelopesender = “Sender Sender@email.address” sendmail = /usr/sbin/sendmail showrev=

其中 mailinglist 为收件人,emailprefix 为邮件前缀,announce list 为repo创建tag时的汇总信息邮件收件人列表, evelopesender 为发件邮箱地址,sendmail 为发件程序地址,showrev 为Log打印格式。

然后推送一个提交试试。It's work!

More useful

Email Content formatted

发送的是纯文本的邮件,对于Diff信息很难辨识。我们可以通过修改post-receive脚本自定义邮件样式。 [Making Git show post-receive emails as an HTML colour formatted diff]提供了这个脚本,我就直接拿来用。

但是标题我们要求是"[ProjectName][CommitAuthor][Action][Branch]CommitLog",所以还需要自己定制。 首先是获取ProjectName,因为我们是使用GitLab作为Git repository server,它集成 gitelitolite 了,自己负责创建项目,一些MetaData并没有保存在Repo中,而是在数据库中。比如ProjectName,它没有提供YOUR_REPO_PATH/description这个文件,所以直接使用文章中的post-receive会出现项目名称为空的情况。

我就将ProjectName设置为Repo目录名称:

projectdesc=$(basename $(pwd))
projectdesc=${projectdesc%.git*}

然后我们再修改邮件标题:

Subject: ${emailprefix}[$projectdesc][$(git log --pretty=format:"%cn" -1 $describe)][${change_type}d][$short_refname]$(git log --pretty=format:"%s" -1 $describe)

其中$(git log --pretty=format:"%s" -1 $describe为获取提交日志,$describe为Commit reversion。

好了自此,邮件内容格式问题解决了。

441ad22223f61fef6b307db6dbf0ff4b.png

Integrate with Gitlab

并不是所有的Repo都需要邮件绑定,不过我们可以将这些配置放到YOUR_REPO_PATH/config中作为开关。
此外Gitlab Dashboard的提交动态同样需要绑定post-receive hook,所以需要将这两个脚本整合在一起。

我们直接将Gitlab工作的那一行逻辑复制到我们的脚本中。
这里发生一个事故,我直接粘贴rpush那一行,导致其中变量引用错误,Gitlab 的默认版本不是$refname,导致提交了部分脏数据到Gitlab中,最后通过删除那部分的events数据解决。耗时半小时。

# --- Main loop
# Allow dual mode: run from the command line just like the update hook, or
# if no arguments are given then run as a hook script
if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
        # Output to the terminal in command line mode - if someone wanted to
        # resend an email; they could redirect the output to sendmail
        # themselves
        PAGER= generate_email $2 $3 $1
else
        while read oldrev new rev refname
        do
                repo_path=`pwd`
                env -i redis-cli rpush "resque:gitlab:queue:post_receive" "{\"class\":\"PostReceive\",\"args\":[\"$repo_path\",\"$oldrev\",\"$newrev\",\"$refname\",\"$GL_USER\"]}" > /dev/null 2>&1
                if [ -n "$recipients" ]; then # validate repo email notify information
                        generate_email $oldrev $newrev $refname | send_mail
                fi
        done
fi

然后将这个脚本替换Gitlab默认的post-receive . 以后的项目只需要添加YOUR_REPO_PATH/confighooks邮件信息就可以触发。

Reference