五分鐘內(nèi)用Python實現(xiàn)GitHook

githooks.png

Githook 也稱 Git 鉤子,是在 Git 倉庫中特定事件發(fā)生時自動運行的腳本艇抠。它可以讓你自定義 Git 內(nèi)部的行為家淤,在開發(fā)周期中的關(guān)鍵點出發(fā)自定義行為瑟由。

Git Hook 最常見的使用場景包括推行提交信息規(guī)范歹苦,根據(jù)倉庫狀態(tài)來改變項目環(huán)境,和接入持續(xù)集成工作流。但是因為腳本可以完全定制痴施,你可以用 Git Hook 來自動化或者優(yōu)化你開發(fā)工作流中任意部分。

Git Hook 是倉庫中特定事件發(fā)生時 Git 自動運行的普通腳本动遭。因此 Git Hook 安裝和配置也非常容易神得。Hook 在本地或服務(wù)端倉庫都可以部署,且只會在倉庫中事件發(fā)生時被執(zhí)行宵蕉。

背景:想在每一次代碼commit的時候發(fā)送一封郵件到相關(guān)人員的郵箱

前提:閱讀以下文字需要有一定Git基礎(chǔ)的朋友羡玛,請參見之前的文章:五步法掌握Git基本操作

實驗環(huán)境:
Python3.5
Pycharm(最順手的IDE而已)
Windows系統(tǒng) Win7

  1. Hook 存在于每個 Git 倉庫的 .git/hooks 目錄中宗苍。當你初始化倉庫時讳窟,Git 自動生成這個目錄和一些示例腳本。你可以在某個 .git/hooks 中谋右,查看這些文件碌上,如下圖:
Hooks目錄.png

注:本地沒有g(shù)it倉庫的可以隨意git clone一個馏予,但是需要有權(quán)限可以做git commit天梧,好做之后的練習。

  1. 編寫腳本語言
    內(nèi)置的腳本大多是 shell 和 perl 語言實現(xiàn)的霞丧,但你也可以使用任何腳本語言呢岗,只要它們最后能編譯到可執(zhí)行文件。每次腳本中 #!/bin/sh 定義了你的文件將如何被解釋蛹尝。
    這次我們采用Python語言來實現(xiàn)GitHook后豫,在Linux系統(tǒng)下可以直接編寫Python腳本,但是在Windows系統(tǒng)下需要做一個小小的轉(zhuǎn)換突那。

1)新建一個shell腳本挫酿,取名為post-commit,內(nèi)容如下:

#!/bin/sh
python3 .git/hooks/post-commit.py

2)新建一個post-commit.py,里面編寫Hook中需要發(fā)送郵件的功能

注:上面一個文件中寫的python3是因為CC先生的Windows環(huán)境中同時有python2和python3(Python2和Python3共存)愕难,此處特意表明用python3來處理惫霸,否則就直接寫python即可。

內(nèi)容如下:

# -*- coding: utf-8 -*-

import smtplib
from email.mime.text import MIMEText
from email.header import Header
from subprocess import check_output

#使用QQ郵箱做測試葱弟,填寫QQ的smtp服務(wù)器名稱
mail_host = "smtp.qq.com"
#替換成自己使用的QQ郵箱
mail_user = "***@qq.com"
#替換成自己使用的授權(quán)碼(非自己的QQ密碼)授權(quán)碼詳見壹店;http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256
mail_pass = "*****"
#使用Python中的subprocess的check_output函數(shù)來捕獲運行了git命令后的標準輸出
log = check_output(['git', 'log', '-1', '-p']).decode()

m = log.split('\n',5)[4]
#分割字符串得到最后的一個參數(shù) 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

  1. 隨意改寫一個倉庫中的文件,比如README.md
    $git add README.md
    2)提交修改
    $ git commit -m 'Update readme. email:xgengshax@msn.com'芝加,如下圖:
    gitcommit.png

4.查看QQ郵箱已發(fā)送郵件(此處因為QQ郵箱的安全設(shè)置會收到發(fā)送失敗的提示郵件硅卢,不過這個表示Hook已經(jīng)成功,只是QQ的安全設(shè)置而已)


QQ mail.png

至此藏杖,我們已經(jīng)完成了只要git commit一次将塑,就會發(fā)送郵件的簡單功能。

回顧一下使用到的知識點:

  • Git基礎(chǔ)知識
  • Python對SMTP的使用
  • Python中subprocess子進程的使用

拓展:
鉤子的作用域
對于任何 Git 倉庫來說 Hook 都是本地的制市,而且它不會隨著 git clone 一起復制到新的倉庫抬旺。而且因為鉤子是本地的,任何能接觸到倉庫的人都可以修改祥楣。對于開發(fā)團隊來說开财,這有很大的影響。所以在開發(fā)團隊中維護鉤子是比較復雜的误褪,因為 .git/hooks 目錄不隨你的項目一起拷貝责鳍,也不受版本控制影響。一個簡單的解決辦法是把你的 Hook 存在項目的實際目錄中(在 .git 外)兽间。這樣你就可以像其他文件一樣進行版本控制历葛。為了安裝 Hook ,你可以在 .git/hooks 中創(chuàng)建一個符號鏈接嘀略,或者簡單地在更新后把它們復制到 .git/hooks 目錄下恤溶。

本地 Hook 只影響它們所在的倉庫。以下是最常用的 6 個本地 >Hook:

pre-commit
prepare-commit-msg
commit-msg
post-commit
post-checkout
pre-rebase
前四個 Hook 介入到版本提交的生命周期帜羊,后兩個允許執(zhí)行一些額外的操作咒程,分別為 git checkout 和 git rebase 的安全檢查。所有與帶 pre- 的 Hook 代表即將發(fā)生的某個階段讼育,帶 post- 只用于通知帐姻。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市奶段,隨后出現(xiàn)的幾起案子饥瓷,更是在濱河造成了極大的恐慌,老刑警劉巖痹籍,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呢铆,死亡現(xiàn)場離奇詭異,居然都是意外死亡蹲缠,警方通過查閱死者的電腦和手機棺克,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進店門鳖宾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人逆航,你說我怎么就攤上這事∮婕纾” “怎么了因俐?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長周偎。 經(jīng)常有香客問我抹剩,道長,這世上最難降的妖魔是什么蓉坎? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任澳眷,我火速辦了婚禮拴疤,結(jié)果婚禮上单刁,老公的妹妹穿的比我還像新娘。我一直安慰自己大莫,他們只是感情好勿侯,可當我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布拓瞪。 她就那樣靜靜地躺著,像睡著了一般助琐。 火紅的嫁衣襯著肌膚如雪祭埂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天兵钮,我揣著相機與錄音蛆橡,去河邊找鬼。 笑死掘譬,一個胖子當著我的面吹牛泰演,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播屁药,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼粥血,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了酿箭?” 一聲冷哼從身側(cè)響起复亏,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缭嫡,沒想到半個月后缔御,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡妇蛀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年耕突,在試婚紗的時候發(fā)現(xiàn)自己被綠了笤成。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡眷茁,死狀恐怖炕泳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情上祈,我是刑警寧澤培遵,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站登刺,受9級特大地震影響籽腕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜纸俭,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一皇耗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧揍很,春花似錦郎楼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蛉迹,卻和暖如春傅寡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背北救。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工荐操, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人珍策。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓托启,卻偏偏與公主長得像,于是被迫代替她去往敵國和親攘宙。 傳聞我的和親對象是個殘疾皇子屯耸,可洞房花燭夜當晚...
    茶點故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內(nèi)容