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 版權聲明:本文爲博主原創文章,轉載請附上博文連接!