8.3 Git 鉤子

2018-02-24 15:22 更新

Git 鉤子

和其它版本控制系統(tǒng)一樣,Git 能在特定的重要?jiǎng)幼靼l(fā)生時(shí)觸發(fā)自定義腳本。 有兩組這樣的鉤子:客戶(hù)端的和服務(wù)器端的。 客戶(hù)端鉤子由諸如提交和合并這樣的操作所調(diào)用,而服務(wù)器端鉤子作用于諸如接收被推送的提交這樣的聯(lián)網(wǎng)操作。 你可以隨心所欲地運(yùn)用這些鉤子。

安裝一個(gè)鉤子

鉤子都被存儲(chǔ)在 Git 目錄下的?hooks?子目錄中。 也即絕大部分項(xiàng)目中的?.git/hooks?。 當(dāng)你用?git init?初始化一個(gè)新版本庫(kù)時(shí),Git 默認(rèn)會(huì)在這個(gè)目錄中放置一些示例腳本。這些腳本除了本身可以被調(diào)用外,它們還透露了被觸發(fā)時(shí)所傳入的參數(shù)。 所有的示例都是 shell 腳本,其中一些還混雜了 Perl 代碼,不過(guò),任何正確命名的可執(zhí)行腳本都可以正常使用 —— 你可以用 Ruby 或 Python,或其它語(yǔ)言編寫(xiě)它們。 這些示例的名字都是以?.sample?結(jié)尾,如果你想啟用它們,得先移除這個(gè)后綴。

把一個(gè)正確命名且可執(zhí)行的文件放入 Git 目錄下的?hooks?子目錄中,即可激活該鉤子腳本。 這樣一來(lái),它就能被 Git 調(diào)用。 接下來(lái),我們會(huì)講解常用的鉤子腳本類(lèi)型。

客戶(hù)端鉤子

客戶(hù)端鉤子分為很多種。 下面把它們分為:提交工作流鉤子、電子郵件工作流鉤子和其它鉤子。

NOTE

需要注意的是,克隆某個(gè)版本庫(kù)時(shí),它的客戶(hù)端鉤子?并不?隨同復(fù)制。 如果需要靠這些腳本來(lái)強(qiáng)制維持某種策略,建議你在服務(wù)器端實(shí)現(xiàn)這一功能。(請(qǐng)參照?使用強(qiáng)制策略的一個(gè)例子中的例子。)

提交工作流鉤子

前四個(gè)鉤子涉及提交的過(guò)程。

pre-commit?鉤子在鍵入提交信息前運(yùn)行。 它用于檢查即將提交的快照,例如,檢查是否有所遺漏,確保測(cè)試運(yùn)行,以及核查代碼。 如果該鉤子以非零值退出,Git 將放棄此次提交,不過(guò)你可以用git commit --no-verify?來(lái)繞過(guò)這個(gè)環(huán)節(jié)。 你可以利用該鉤子,來(lái)檢查代碼風(fēng)格是否一致(運(yùn)行類(lèi)似?lint?的程序)、尾隨空白字符是否存在(自帶的鉤子就是這么做的),或新方法的文檔是否適當(dāng)。

prepare-commit-msg?鉤子在啟動(dòng)提交信息編輯器之前,默認(rèn)信息被創(chuàng)建之后運(yùn)行。 它允許你編輯提交者所看到的默認(rèn)信息。 該鉤子接收一些選項(xiàng):存有當(dāng)前提交信息的文件的路徑、提交類(lèi)型和修補(bǔ)提交的提交的 SHA-1 校驗(yàn)。 它對(duì)一般的提交來(lái)說(shuō)并沒(méi)有什么用;然而對(duì)那些會(huì)自動(dòng)產(chǎn)生默認(rèn)信息的提交,如提交信息模板、合并提交、壓縮提交和修訂提交等非常實(shí)用。 你可以結(jié)合提交模板來(lái)使用它,動(dòng)態(tài)地插入信息。

commit-msg?鉤子接收一個(gè)參數(shù),此參數(shù)即上文提到的,存有當(dāng)前提交信息的臨時(shí)文件的路徑。 如果該鉤子腳本以非零值退出,Git 將放棄提交,因此,可以用來(lái)在提交通過(guò)前驗(yàn)證項(xiàng)目狀態(tài)或提交信息。 在本章的最后一節(jié),我們將展示如何使用該鉤子來(lái)核對(duì)提交信息是否遵循指定的模板。

post-commit?鉤子在整個(gè)提交過(guò)程完成后運(yùn)行。 它不接收任何參數(shù),但你可以很容易地通過(guò)運(yùn)行git log -1 HEAD?來(lái)獲得最后一次的提交信息。 該鉤子一般用于通知之類(lèi)的事情。

電子郵件工作流鉤子

你可以給電子郵件工作流設(shè)置三個(gè)客戶(hù)端鉤子。 它們都是由?git am?命令調(diào)用的,因此如果你沒(méi)有在你的工作流中用到這個(gè)命令,可以跳到下一節(jié)。 如果你需要通過(guò)電子郵件接收由?git format-patch?產(chǎn)生的補(bǔ)丁,這些鉤子也許用得上。

第一個(gè)運(yùn)行的鉤子是?applypatch-msg?。 它接收單個(gè)參數(shù):包含請(qǐng)求合并信息的臨時(shí)文件的名字。 如果腳本返回非零值,Git 將放棄該補(bǔ)丁。 你可以用該腳本來(lái)確保提交信息符合格式,或直接用腳本修正格式錯(cuò)誤。

下一個(gè)在?git am?運(yùn)行期間被調(diào)用的是?pre-applypatch?。 有些難以理解的是,它正好運(yùn)行于應(yīng)用補(bǔ)丁?之后,產(chǎn)生提交之前,所以你可以用它在提交前檢查快照。 你可以用這個(gè)腳本運(yùn)行測(cè)試或檢查工作區(qū)。 如果有什么遺漏,或測(cè)試未能通過(guò),腳本會(huì)以非零值退出,中斷?git am?的運(yùn)行,這樣補(bǔ)丁就不會(huì)被提交。

post-applypatch?運(yùn)行于提交產(chǎn)生之后,是在?git am?運(yùn)行期間最后被調(diào)用的鉤子。 你可以用它把結(jié)果通知給一個(gè)小組或所拉取的補(bǔ)丁的作者。 但你沒(méi)辦法用它停止打補(bǔ)丁的過(guò)程。

其它客戶(hù)端鉤子

pre-rebase?鉤子運(yùn)行于變基之前,以非零值退出可以中止變基的過(guò)程。 你可以使用這個(gè)鉤子來(lái)禁止對(duì)已經(jīng)推送的提交變基。 Git 自帶的?pre-rebase?鉤子示例就是這么做的,不過(guò)它所做的一些假設(shè)可能與你的工作流程不匹配。

post-rewrite?鉤子被那些會(huì)替換提交記錄的命令調(diào)用,比如?git commit --amend?和?git rebase(不過(guò)不包括?git filter-branch)。 它唯一的參數(shù)是觸發(fā)重寫(xiě)的命令名,同時(shí)從標(biāo)準(zhǔn)輸入中接受一系列重寫(xiě)的提交記錄。 這個(gè)鉤子的用途很大程度上跟?post-checkout?和?post-merge?差不多。

在?git checkout?成功運(yùn)行后,post-checkout?鉤子會(huì)被調(diào)用。你可以根據(jù)你的項(xiàng)目環(huán)境用它調(diào)整你的工作目錄。 其中包括放入大的二進(jìn)制文件、自動(dòng)生成文檔或進(jìn)行其他類(lèi)似這樣的操作。

在?git merge?成功運(yùn)行后,post-merge?鉤子會(huì)被調(diào)用。 你可以用它恢復(fù) Git 無(wú)法跟蹤的工作區(qū)數(shù)據(jù),比如權(quán)限數(shù)據(jù)。 這個(gè)鉤子也可以用來(lái)驗(yàn)證某些在 Git 控制之外的文件是否存在,這樣你就能在工作區(qū)改變時(shí),把這些文件復(fù)制進(jìn)來(lái)。

pre-push?鉤子會(huì)在?git push?運(yùn)行期間, 更新了遠(yuǎn)程引用但尚未傳送對(duì)象時(shí)被調(diào)用。 它接受遠(yuǎn)程分支的名字和位置作為參數(shù),同時(shí)從標(biāo)準(zhǔn)輸入中讀取一系列待更新的引用。 你可以在推送開(kāi)始之前,用它驗(yàn)證對(duì)引用的更新操作(一個(gè)非零的退出碼將終止推送過(guò)程)。

Git 的一些日常操作在運(yùn)行時(shí),偶爾會(huì)調(diào)用?git gc --auto?進(jìn)行垃圾回收。?pre-auto-gc?鉤子會(huì)在垃圾回收開(kāi)始之前被調(diào)用,可以用它來(lái)提醒你現(xiàn)在要回收垃圾了,或者依情形判斷是否要中斷回收。

服務(wù)器端鉤子

除了客戶(hù)端鉤子,作為系統(tǒng)管理員,你還可以使用若干服務(wù)器端的鉤子對(duì)項(xiàng)目強(qiáng)制執(zhí)行各種類(lèi)型的策略。 這些鉤子腳本在推送到服務(wù)器之前和之后運(yùn)行。 推送到服務(wù)器前運(yùn)行的鉤子可以在任何時(shí)候以非零值退出,拒絕推送并給客戶(hù)端返回錯(cuò)誤消息,還可以依你所想設(shè)置足夠復(fù)雜的推送策略。

pre-receive

處理來(lái)自客戶(hù)端的推送操作時(shí),最先被調(diào)用的腳本是?pre-receive。 它從標(biāo)準(zhǔn)輸入獲取一系列被推送的引用。如果它以非零值退出,所有的推送內(nèi)容都不會(huì)被接受。 你可以用這個(gè)鉤子阻止對(duì)引用進(jìn)行非快進(jìn)(non-fast-forward)的更新,或者對(duì)該推送所修改的所有引用和文件進(jìn)行訪(fǎng)問(wèn)控制。

update

update?腳本和?pre-receive?腳本十分類(lèi)似,不同之處在于它會(huì)為每一個(gè)準(zhǔn)備更新的分支各運(yùn)行一次。 假如推送者同時(shí)向多個(gè)分支推送內(nèi)容,pre-receive?只運(yùn)行一次,相比之下?update?則會(huì)為每一個(gè)被推送的分支各運(yùn)行一次。 它不會(huì)從標(biāo)準(zhǔn)輸入讀取內(nèi)容,而是接受三個(gè)參數(shù):引用的名字(分支),推送前的引用指向的內(nèi)容的 SHA-1 值,以及用戶(hù)準(zhǔn)備推送的內(nèi)容的 SHA-1 值。 如果 update 腳本以非零值退出,只有相應(yīng)的那一個(gè)引用會(huì)被拒絕;其余的依然會(huì)被更新。

post-receive

post-receive?掛鉤在整個(gè)過(guò)程完結(jié)以后運(yùn)行,可以用來(lái)更新其他系統(tǒng)服務(wù)或者通知用戶(hù)。 它接受與?pre-receive?相同的標(biāo)準(zhǔn)輸入數(shù)據(jù)。 它的用途包括給某個(gè)郵件列表發(fā)信,通知持續(xù)集成(continous integration)的服務(wù)器,或者更新問(wèn)題追蹤系統(tǒng)(ticket-tracking system) —— 甚至可以通過(guò)分析提交信息來(lái)決定某個(gè)問(wèn)題(ticket)是否應(yīng)該被開(kāi)啟,修改或者關(guān)閉。 該腳本無(wú)法終止推送進(jìn)程,不過(guò)客戶(hù)端在它結(jié)束運(yùn)行之前將保持連接狀態(tài),所以如果你想做其他操作需謹(jǐn)慎使用它,因?yàn)樗鼘⒑馁M(fèi)你很長(zhǎng)的一段時(shí)間。

以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)