git commit觸發(fā)的hook

git中提供了一組hook,規(guī)定了每個(gè)hook的名字,以及hook接收的參數(shù)個(gè)數(shù)和每個(gè)參數(shù)的含義。用戶如果要使用hook的話,需要在.git/hooks/目錄中創(chuàng)建對(duì)應(yīng)名字的hook文件,賦予該文件可執(zhí)行權(quán)限,用bash或者python或者其它腳本語言來實(shí)現(xiàn)該hook具體要做哪些事。hook就是類似于onClick()、onRun()這樣的事件,也可以理解成是一組回調(diào)函數(shù)。

git commit是最常用的命令之一,它可以觸發(fā)四個(gè)hook,分別是pre-commit,prepare-commit-msg,commit-msg和post-commit。從字面上可以猜測(cè)到這四個(gè)hook分別對(duì)應(yīng)“commit之前”、“準(zhǔn)備commit log message的時(shí)候”、“生成commit log message的時(shí)候”、“commit之后”這四個(gè)觸發(fā)時(shí)機(jī)。這四個(gè)hook也的確是按照這個(gè)先后順序被觸發(fā)的。如果git commit時(shí)使用了-n(等價(jià)于--no-verify)參數(shù)的話,pre-commit和commit-msg就不會(huì)被觸發(fā)。

pre-commit不接收參數(shù)。這個(gè)hook可以用來在commit之前檢查修改的代碼是否符合規(guī)范、檢查文件名是否含有空格、或者僅僅單純地輸出“hello world”等等,具體想要做什么可以根據(jù)實(shí)際情況來決定。如果以非0狀態(tài)退出的話,譬如檢測(cè)到文件名中有空格,而用戶不希望這種文件被commit,在這種情況下執(zhí)行exit 1,那么git commit會(huì)以失敗而終止。

prepare-commit-msg接收三個(gè)參數(shù)。第一個(gè)是commit log message所在的文件名,通常是.git/COMMIT_EDITMSG。第二個(gè)是commit log message的來源。在《git commit中輸入message的幾種方式》 中有介紹過-m,不加參數(shù),-c,-C,-F,-t等方式輸入commit log message,這些都是不同的來源。如果是-m的話,第二個(gè)參數(shù)的值是"message";如果是不加參數(shù)的話,第二個(gè)參數(shù)的值是"";如果是-c或-C或者其他情況但加了--amend參數(shù)的話,第二個(gè)參數(shù)的值是"commit";如果是-F的話,第二個(gè)參數(shù)的值是"message";如果是-t或者設(shè)置了commit.template的話,第二個(gè)參數(shù)的值是"template"。

如果第二個(gè)參數(shù)不是"commit",那第三個(gè)參數(shù)值為""。如果第二個(gè)參數(shù)值是“commit"的話,那第三個(gè)參數(shù)值就是-c或者-C后面接的那個(gè)值,可能是tag name、branch name、HEAD、HEAD^1、具體的某個(gè)commit SHA-1等等。有--amend的話,第三個(gè)參數(shù)值是"HEAD"。

此外,git merge和git cherry-pick可能會(huì)觸發(fā)這個(gè)hook。git merge如果是ff(fast-forward) merge那不會(huì)觸發(fā)這個(gè)hook,但如果發(fā)生no-ff類型的merge,或者git merge --no-ff,那么會(huì)觸發(fā)這個(gè)hook,第二個(gè)參數(shù)值為"merge";git merge --squash && git commit的情況下,第二個(gè)參數(shù)值為"squash"。git cherry-pick默認(rèn)情況下會(huì)觸發(fā)這個(gè)hook,除非使用了-n(等價(jià)于--no-commit)參數(shù),第二個(gè)參數(shù)值為"message"。

理論上來說,pre-commit中的事情可以放到prepare-commit-msg中來做,但不推薦這么做 。prepare-commit-msg的設(shè)計(jì)本意是在commit-msg之前編輯message文件用的。譬如,希望在commit log message中記錄下當(dāng)前某個(gè)系統(tǒng)的某些狀態(tài)值(譬如jenkins上某個(gè)編譯job的環(huán)境變量和用戶變量),那可以在prepare-commit-msg中對(duì)準(zhǔn)備用于-F或者-t的文件進(jìn)行編輯,將那些實(shí)時(shí)獲取的狀態(tài)值插入到文件中去。然后這個(gè)文件的內(nèi)容會(huì)被寫入.git/COMMIT_EDITMSG,commit成功以后,這些內(nèi)容就變成了commit log message的一部分。當(dāng)然,這些內(nèi)容也可以在git commit之前組織好,然后在git commit的時(shí)候直接用起來。但如果放在hook里來做,就等于封裝到了git commit的內(nèi)部。用戶可以根據(jù)實(shí)際情況考量是否需要用這個(gè)hook。同樣的,這個(gè)hook如果以非0狀態(tài)退出的話,會(huì)使git commit失敗而終止。

和prepare-commit-msg比起來,commit-msg使用的場景更多些。這個(gè)hook接收一個(gè)參數(shù),commit log message所在的文件名,通常是.git/COMMIT_EDITMSG。從這個(gè)文件中,可以讀取到最終運(yùn)用于commit log message的內(nèi)容。比較常見的運(yùn)用是在這里檢查commit log message是否符合事先規(guī)定的格式。另外一個(gè)實(shí)際運(yùn)用是使用gerrit系統(tǒng)的場合下,git commit時(shí)會(huì)根據(jù)已有的信息生成一個(gè)類似commit SHA-1的Change-Id,并將其插入到commit log message中去。生成Change-Id的算法會(huì)用到用戶編輯完成后的commit log message的內(nèi)容,所以生成Change-Id的動(dòng)作不能在commit-msg之前做。同樣的,這個(gè)hook如果以非0狀態(tài)退出的話,會(huì)使git commit失敗而終止。

post-commit在commit完成后被觸發(fā),不接收參數(shù)。post-commit能夠執(zhí)行,說明git commit已經(jīng)成功了。接下來可以做很多事,譬如執(zhí)行g(shù)it push到一個(gè)備份branch上,或者啟動(dòng)編譯,或者關(guān)機(jī)(每天只做一個(gè)commit),或者也可以很無聊地git reset --hard回到新生成的commit的parent上(這么做毫無意義),也可以把硬盤格式化掉(再見!)

要試驗(yàn)這四個(gè)hook的話,可以在.git/hooks/下創(chuàng)建四個(gè)文件,文件名分別為pre-commit,prepare-commit-msg,commit-msg,post-commit,將它們都改為可執(zhí)行文件。假如要用hook打印每個(gè)hook接收了哪些參數(shù):

#!/usr/bash

echo $@

或者

#!/usr/bin/env python

import sys

print sys.argv

然后執(zhí)行各種git commit看看效果吧。別忘了每個(gè)hook的參數(shù)列表第0個(gè)是hook文件的路徑,后面才是接收的參數(shù)。hook是一扇門,你的腦洞有多大,門后面的世界就有多大。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,724評(píng)論 19 139
  • 1.什么是 Git Hooks 如同其他許多的版本控制系統(tǒng)一樣,Git 也具有在特定事件發(fā)生之前或之后執(zhí)行特定腳本...
    就叫yang閱讀 3,542評(píng)論 3 11
  • 本片內(nèi)容轉(zhuǎn)自CSDN http://blog.csdn.net/ithomer/article/details/7...
    五娃兒閱讀 5,053評(píng)論 2 87
  • 泰戈?duì)栐模?The mist is like the earth’s desire. It hides the ...
    語熙閱讀 1,917評(píng)論 9 14
  • 題目要求 Write a program that outputs the string representati...
    TW妖妖閱讀 381評(píng)論 0 0

友情鏈接更多精彩內(nèi)容