五分钟内用Python实现GitHook


githooks.png
Githook 也称 Git 钩子,是在 Git 仓库中特定事件发生时自动运行的脚本。它可让你自定义 Git 内部的行为,在开发周期中的关键点出发自定义行为。python

Git Hook 最多见的使用场景包括推行提交信息规范,根据仓库状态来改变项目环境,和接入持续集成工做流。可是由于脚本能够彻底定制,你能够用 Git Hook 来自动化或者优化你开发工做流中任意部分。git

Git Hook 是仓库中特定事件发生时 Git 自动运行的普通脚本。所以 Git Hook 安装和配置也很是容易。Hook 在本地或服务端仓库均可以部署,且只会在仓库中事件发生时被执行。shell

背景:想在每一次代码commit的时候发送一封邮件到相关人员的邮箱安全

前提:阅读如下文字须要有必定Git基础的朋友,请参见以前的文章:五步法掌握Git基本操做服务器

实验环境:
Python3.5
Pycharm(最顺手的IDE而已)
Windows系统 Win7函数

Hook 存在于每一个 Git 仓库的 .git/hooks 目录中。当你初始化仓库时,Git 自动生成这个目录和一些示例脚本。你能够在某个 .git/hooks 中,查看这些文件,以下图:post

Hooks目录.png测试

注:本地没有git仓库的能够随意git clone一个,可是须要有权限能够作git commit,好作以后的练习。优化

编写脚本语言
内置的脚本大可能是 shell 和 perl 语言实现的,但你也可使用任何脚本语言,只要它们最后能编译到可执行文件。每次脚本中 #!/bin/sh 定义了你的文件将如何被解释。
此次咱们采用Python语言来实现GitHook,在Linux系统下能够直接编写Python脚本,可是在Windows系统下须要作一个小小的转换。
1)新建一个shell脚本,取名为post-commit,内容以下:ui

#!/bin/sh
python3 .git/hooks/post-commit.py
2)新建一个post-commit.py,里面编写Hook中须要发送邮件的功能

注:上面一个文件中写的python3是由于CC先生的Windows环境中同时有python2和python3(Python2和Python3共存),此处特地代表用python3来处理,不然就直接写python便可。

内容以下:

# -*- coding: utf-8 -*-
 
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from subprocess import check_output
 
#使用QQ邮箱作测试,填写QQ的smtp服务器名称
mail_host = "smtp.qq.com"
#替换成本身使用的QQ邮箱
mail_user = "***@qq.com"
#替换成本身使用的受权码(非本身的QQ密码)受权码详见;http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256
mail_pass = "*****"
#使用Python中的subprocess的check_output函数来捕获运行了git命令后的标准输出
log = check_output(['git', 'log', '-1', '-p']).decode()
 
m = log.split('\n',5)[4]
#分割字符串获得最后的一个参数 email
arg = m.split(' ')[-1]
 
 
if arg[:6] == 'email:':
    receiver = arg[6:]
    print(receiver)
    sender = mail_user
    receivers = [receiver]
 
    message = MIMEText(log)
    message['From'] = Header(mail_user, 'utf-8')
    message['To'] =  Header(str(receivers), 'utf-8')
 
    subject = 'This is a commit log for you!'
    message['Subject'] = Header(subject, 'utf-8')
 
    try:
        smtpObj = smtplib.SMTP_SSL(mail_host, 465)
        smtpObj.login(mail_user,mail_pass)
        smtpObj.sendmail(sender, receivers, message.as_string())
        smtpObj.quit()
        print ("Send the diff email to:", receiver)
    except smtplib.SMTPException as e:
        print (e)
 
3.能够在git命令中尝试GitHook

随意改写一个仓库中的文件,好比README.md
$git add README.md
2)提交修改
$ git commit -m 'Update readme. email:xgengshax@msn.com',以下图:

gitcommit.png
4.查看QQ邮箱已发送邮件(此处由于QQ邮箱的安全设置会收到发送失败的提示邮件,不过这个表示Hook已经成功,只是QQ的安全设置而已)

QQ mail.png
至此,咱们已经完成了只要git commit一次,就会发送邮件的简单功能。

回顾一下使用到的知识点:

Git基础知识
Python对SMTP的使用
Python中subprocess子进程的使用
拓展:
钩子的做用域
对于任何 Git 仓库来讲 Hook 都是本地的,并且它不会随着 git clone 一块儿复制到新的仓库。并且由于钩子是本地的,任何能接触到仓库的人均可以修改。对于开发团队来讲,这有很大的影响。因此在开发团队中维护钩子是比较复杂的,由于 .git/hooks 目录不随你的项目一块儿拷贝,也不受版本控制影响。一个简单的解决办法是把你的 Hook 存在项目的实际目录中(在 .git 外)。这样你就能够像其余文件同样进行版本控制。为了安装 Hook ,你能够在 .git/hooks 中建立一个符号连接,或者简单地在更新后把它们复制到 .git/hooks 目录下。

本地 Hook 只影响它们所在的仓库。如下是最经常使用的 6 个本地 >Hook:

pre-commit prepare-commit-msg commit-msg post-commit post-checkout pre-rebase 前四个 Hook 介入到版本提交的生命周期,后两个容许执行一些额外的操做,分别为 git checkout 和 git rebase 的安全检查。全部与带 pre- 的 Hook 表明即将发生的某个阶段,带 post- 只用于通知。 ---------------------  做者:weixin_33695450  来源:CSDN  原文:https://blog.csdn.net/weixin_33695450/article/details/86909554  版权声明:本文为博主原创文章,转载请附上博文连接!

相关文章
相关标签/搜索