GIt Hooks (2):腳本分類

上篇中提到一個Git Hooks列表,以下:git

  • applypatch-msg
  • pre-applypatch
  • post-applypatch
  • pre-commit
  • prepare-commit-msg
  • commit-msg
  • post-commit
  • pre-rebase
  • post-checkout
  • post-merge
  • pre-receive
  • update
  • post-receive
  • post-update
  • pre-auto-gc
  • post-rewrite

這些腳本能夠按照運行環境分爲兩類:本地Hooks與服務端Hooks。服務器

Client Side

也就是上面提到的本地hooks。
其實本地hooks仍是佔大多數的,能夠給它們分紅三類:app

  • commit hooks
  • e-mail hooks
  • 其餘

Commit Hooks

git commit相關的hooks一共有四個,均由git commit命令觸發調用,按照一次發生的順序分別是:編輯器

  • pre-commit
  • prepare-commit-msg
  • commit-msg
  • post-commit

其中,pre-commit是最早觸發運行的腳本。在提交一個commit以前,該hook有能力作許多工做,好比檢查待提交東西的快照,以確保這份提交中沒有缺乏什麼東西、文件名是否符合規範、是否對這份提交進行了測試、代碼風格是否符合團隊要求等等。
這個腳本能夠經過傳遞--no-verify參數而禁用,若是腳本運行失敗(返回非零值),git提交就會被終止。ide

prepare-commit-msg腳本會在默認的提交信息準備完成後但編輯器還沒有啓動以前運行。
這個腳本的做用是用來編輯commit的默認提交說明。
該腳本有1~3個參數:包含提交說明文件的路徑,commit類型(message, template, merge, squash),一個用於commit的SHA1值。這個腳本用的機會不是太多,主要是用於能自動生成commit message的狀況。
該不會由於--no-verify參數而禁用,若是腳本運行失敗(返回非零值),git提交就會被終止。post

commit-msg包含有一個參數,用來規定提交說明文件的路徑。
該腳本能夠用來驗證提交說明的規範性,若是做者寫的提交說明不符合指定路徑文件中的規範,提交就會被終止。
該腳本能夠經過傳遞--no-verify參數而禁用,若是腳本運行失敗(返回非零值),git提交就會被終止。測試

post-commit腳本發生在整個提交過程完成以後。這個腳本不包含任何參數,也不會影響commit的運行結果,能夠用於發送new commit通知。code

須要注意到,這幾個腳本並不會經過clone傳到項目中,並且既然是徹底運行在本地,那就沒法徹底保證驗證能起到做用(能夠隨便修改),但爲了保證一些項目的可靠性,還須要開發者們自覺遵照這些規則。orm

E-mail Hooks

git am相關的腳本由三個,均由git am觸發運行,按順序依次是:對象

  • applypatch-msg
  • pre-applypatch
  • post-applypaych

若是在工做流中用不到這個命令,那也就無所謂了。不過,若是要用git format-patch命令經過Email提交補丁,這部份內容仍是比較有用的。

applypatch-msg腳本最早被觸發,它包含一個參數,用來規定提交說明文件的路徑。該腳本能夠修改文件中保存的提交說明,以便規範提交說明以符合項目標準。若是提交說明不符合規定的標準,腳本返回非零值,git終止提交。

說明一點,這個腳本看上去和commit-msg做用幾乎同樣。沒錯,默認狀況下該腳本是這樣寫的:

#!/bin/sh
. git-sh-setup
test -x "$GIT_DIR/hooks/commit-msg" &&
    exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
:

也就是說,該腳本會調用commit-msg並執行。實際上,這一切都是可修改的。

pre-applypatch會在補丁應用後但還沒有提交前運行。這個腳本沒有參數,能夠用於對應用補丁後的工做區進行測試,或對git tree進行檢查。若是不能經過測試或檢查,腳本返回非零值,git終止提交。
一樣須要注意,git提供的此默認腳本中只是簡單調用了pre-commit,所以在實際工做中須要視狀況修改。

post-applypatch腳本會在補丁應用並提交以後運行,它不包含參數,也不會影響git am的運行結果。該腳本能夠用來向工做組成員或補丁做者發送通知。

其餘Hooks

  • pre-rebase

git rebase命令調用,運行在rebase執行以前,能夠用來阻止任何已發發生過的提交參與變基(字面意思,找不到合適的詞彙了)。默認的pre-rebase確實是這麼作的,不過腳本中的next是根據Git項目自身而寫的分支名,在使用過程當中應該將其改爲本身的穩定分支名稱。

  • post-checkout

git checkout命令調用,在完成工做區更新以後執行。該腳本由三個參數:以前HEAD指向的引用,新的HEAD指向的引用,一個用於標識這次檢出是不是分支檢出的值(0表示文件檢出,1表示分支檢出)。

也能夠被git clone觸發調用,除非在克隆時使用參數--no-checkout。在由clone調用執行時,三個參數分別爲null, 1, 1

這個腳本能夠用於爲本身的項目設置合適的工做區,好比自動生成文檔、移動一些大型二進制文件等,也能夠用於檢查版本庫的有效性。

  • post-merge

git merge調用,在merge成功後執行。該腳本有一個參數,標識合併是否爲壓縮合並。該腳本能夠用於對一些Git沒法記錄的數據的恢復,好比文件權限、屬主、ACL等。

Server Side

除了本地執行的Hooks腳本以外,還有一些放在Git Server上的Hooks腳本,做爲管理員,能夠利用這些服務端的腳原本強制確保項目的任何規範。這些運行在服務端的腳本,會在push命令發生的先後執行。pre系列的腳本能夠在任什麼時候候返回非零值來終止某次push,並向push方返回一個錯誤說明。

這裏簡單介紹這幾個腳本:

  • pre-receive

由服務器端的git receive-pack命令調用,當從本地版本庫完成一個推送以後,遠端服務器開始批量更新以前,該腳本被觸發執行。該腳本會從標準輸入中讀入一連串push過來的引用,若是這裏面存在任何非零值,這批更新將不會被服務器接受。能夠利用這個腳原本檢查推送過來的提交是否合法。

  • post-receive

由服務器端的gir receive-pack命令調用,當從本地版本庫完成一個推送,而且在遠程服務器上全部引用都更新完畢後執行。該腳本能夠用於對其餘鏡像版本庫的更新,或向用戶發送提示(直接經過服務器端的echo命令)。如上文我提到的利用Git實現生產代碼的自動化部署,就能夠經過這個腳本完成。

  • update
    這是一個強大的hook腳本。它和pre-recieve有些相似,只是它會爲推送過來的更新中涉及到的每個分支都作一次檢查,然後者則至始至終只有一次檢查。另外,它不是從標準輸入中讀取數據,而是包含三個參數:

    • 要更新的引用或分支的名稱
    • 引用中保存的舊對象名稱(SHA1)
    • 將要保存到引用中的新對象名稱(SHA1)

若是檢查到返回非零值,以後返回非零值的引用會被拒絕,其餘正常的引用更新都會被接受。除此以外,該腳本還能夠用來防止引用被強制更新,由於它能夠經過這些參數來檢查新舊引用對象中是否存在繼承關係,從而提供更細緻的推送受權。

在Gitolite中,該腳本有更強大的應用實例。

本篇完結,敬請期待後續……

相關文章
相關標籤/搜索