和其他版本控制系統一樣,當某些重要事件發生時,Git 以調用自定義腳本。有兩組掛鉤:客戶端和服務器端。客戶端掛鉤用于客戶端的操作,如提交和合并。服務器端掛鉤用于 Git 服務器端的操作,如接收被推送的提交。你可以隨意地使用這些掛鉤,下面會講解其中一些。
## 安裝一個掛鉤
掛鉤都被存儲在 Git 目錄下的hooks子目錄中,即大部分項目中的`.git/hooks。` Git 默認會放置一些腳本樣本在這個目錄中,除了可以作為掛鉤使用,這些樣本本身是可以獨立使用的。所有的樣本都是shell腳本,其中一些還包含了Perl的腳本,不過,任何正確命名的可執行腳本都可以正常使用 — 可以用`Ruby`或`Python`,或其他。在Git 1.6版本之后,這些樣本名都是以.sample結尾,因此,你必須重新命名。在Git 1.6版本之前,這些樣本名都是正確的,但這些樣本不是可執行文件。
把一個正確命名且可執行的文件放入 Git 目錄下的hooks子目錄中,可以激活該掛鉤腳本,因此,之后他一直會被 Git 調用。隨后會講解主要的掛鉤腳本。
## 客戶端掛鉤
有許多客戶端掛鉤,以下把他們分為:提交工作流掛鉤、電子郵件工作流掛鉤及其他客戶端掛鉤。
### 提交工作流掛鉤
有 4個掛鉤被用來處理提交的過程。pre-commit掛鉤在鍵入提交信息前運行,被用來檢查即將提交的快照,例如,檢查是否有東西被遺漏,確認測試是否運行,以及檢查代碼。當從該掛鉤返回非零值時,Git 放棄此次提交,但可以用git commit --no-verify來忽略。該掛鉤可以被用來檢查代碼錯誤(運行類似lint的程序),檢查尾部空白(默認掛鉤是這么做的),檢查新方法(譯注:程序的函數)的說明。
`prepare-commit-msg`掛鉤在提交信息編輯器顯示之前,默認信息被創建之后運行。因此,可以有機會在提交作者看到默認信息前進行編輯。該掛鉤接收一些選項:擁有提交信息的文件路徑,提交類型,如果是一次修訂的話,提交的SHA-1校驗和。該掛鉤對通常的提交來說不是很有用,只在自動產生的默認提交信息的情況下有作用,如提交信息模板、合并、壓縮和修訂提交等。可以和提交模板配合使用,以編程的方式插入信息。
`commit-msg`掛鉤接收一個參數,此參數是包含最近提交信息的臨時文件的路徑。如果該掛鉤腳本以非零退出,Git 放棄提交,因此,可以用來在提交通過前驗證項目狀態或提交信息。本章上一小節已經展示了使用該掛鉤核對提交信息是否符合特定的模式。
`post-commit`掛鉤在整個提交過程完成后運行,他不會接收任何參數,但可以運行git log -1 HEAD來獲得最后的提交信息。總之,該掛鉤是作為通知之類使用的。
提交工作流的客戶端掛鉤腳本可以在任何工作流中使用,他們經常被用來實施某些策略,但值得注意的是,這些腳本在clone期間不會被傳送。可以在服務器端實施策略來拒絕不符合某些策略的推送,但這完全取決于開發者在客戶端使用這些腳本的情況。所以,這些腳本對開發者是有用的,由他們自己設置和維護,而且在任何時候都可以覆蓋或修改這些腳本。
### E-mail工作流掛鉤
有3個可用的客戶端掛鉤用于e-mail工作流。當運行git am命令時,會調用他們,因此,如果你沒有在工作流中用到此命令,可以跳過本節。如果你通過e-mail接收由git format-patch產生的補丁,這些掛鉤也許對你有用。
首先運行的是applypatch-msg掛鉤,他接收一個參數:包含被建議提交信息的臨時文件名。如果該腳本非零退出,Git 放棄此補丁。可以使用這個腳本確認提交信息是否被正確格式化,或讓腳本編輯信息以達到標準化。
下一個在git am運行期間調用是pre-applypatch掛鉤。該掛鉤不接收參數,在補丁被運用之后運行,因此,可以被用來在提交前檢查快照。你能用此腳本運行測試,檢查工作樹。如果有些什么遺漏,或測試沒通過,腳本會以非零退出,放棄此次git am的運行,補丁不會被提交。
最后在git am運行期間調用的是post-applypatch掛鉤。你可以用他來通知一個小組或獲取的補丁的作者,但無法阻止打補丁的過程。
### 其他客戶端掛鉤
`pre-rebase`掛鉤在衍合前運行,腳本以非零退出可以中止衍合的過程。你可以使用這個掛鉤來禁止衍合已經推送的提交對象,Git pre-rebase掛鉤樣本就是這么做的。該樣本假定next是你定義的分支名,因此,你可能要修改樣本,把next改成你定義過且穩定的分支名。
在`git checkout`成功運行后,post-checkout掛鉤會被調用。他可以用來為你的項目環境設置合適的工作目錄。例如:放入大的二進制文件、自動產生的文檔或其他一切你不想納入版本控制的文件。
最后,在merge命令成功執行后,post-merge掛鉤會被調用。他可以用來在 Git 無法跟蹤的工作樹中恢復數據,諸如權限數據。該掛鉤同樣能夠驗證在 Git 控制之外的文件是否存在,因此,當工作樹改變時,你想這些文件可以被復制。
## 服務器端掛鉤
除了客戶端掛鉤,作為系統管理員,你還可以使用兩個服務器端的掛鉤對項目實施各種類型的策略。這些掛鉤腳本可以在提交對象推送到服務器前被調用,也可以在推送到服務器后被調用。推送到服務器前調用的掛鉤可以在任何時候以非零退出,拒絕推送,返回錯誤消息給客戶端,還可以如你所愿設置足夠復雜的推送策略。
### pre-receive 和 post-receive
處理來自客戶端的推送(push)操作時最先執行的腳本就是 pre-receive 。它從標準輸入(stdin)獲取被推送引用的列表;如果它退出時的返回值不是0,所有推送內容都不會被接受。利用此掛鉤腳本可以實現類似保證最新的索引中不包含非fast-forward類型的這類效果;抑或檢查執行推送操作的用戶擁有創建,刪除或者推送的權限或者他是否對將要修改的每一個文件都有訪問權限。
### post-receive
掛鉤在整個過程完結以后運行,可以用來更新其他系統服務或者通知用戶。它接受與 pre-receive 相同的標準輸入數據。應用實例包括給某郵件列表發信,通知實時整合數據的服務器,或者更新軟件項目的問題追蹤系統 —— 甚至可以通過分析提交信息來決定某個問題是否應該被開啟,修改或者關閉。該腳本無法組織推送進程,不過客戶端在它完成運行之前將保持連接狀態;所以在用它作一些消耗時間的操作之前請三思。
### update
`update` 腳本和` pre-receive `腳本十分類似。不同之處在于它會為推送者更新的每一個分支運行一次。假如推送者同時向多個分支推送內容,pre-receive 只運行一次,相比之下 update 則會為每一個更新的分支運行一次。它不會從標準輸入讀取內容,而是接受三個參數:索引的名字(分支),推送前索引指向的內容的 SHA-1 值,以及用戶試圖推送內容的 SHA-1 值。如果 update 腳本以退出時返回非零值,只有相應的那一個索引會被拒絕;其余的依然會得到更新。
- 1. 起步
- 1.1 關于版本控制
- 1.2 Git 簡史
- 1.3 Git 基礎
- 1.4 安裝 Git
- 1.5 初次運行 Git 前的配置
- 1.6 獲取幫助
- 1.7 小結
- 2. Git基礎
- 2.1 取得項目的 Git 倉庫
- 2.2 記錄每次更新到倉庫
- 2.3 查看提交歷史
- 2.4 撤消操作
- 2.5 遠程倉庫的使用
- 2.6 打標簽
- 2.7 技巧和竅門
- 2.8 小結
- 3. Git分支
- 3.1 何謂分支
- 3.2 分支的新建與合并
- 3.3 分支的管理
- 3.4 利用分支進行開發的工作流程
- 3.5 遠程分支
- 3.6 分支的衍合
- 3.7 小結
- 4. 服務器上的Git
- 4.1 協議
- 4.2 在服務器上部署 Git
- 4.3 生成 SSH 公鑰
- 4.4 架設服務器
- 4.5 公共訪問
- 4.6 GitWeb
- 4.7 Gitosis
- 4.8 Gitolite
- 4.9 Git 守護進程
- 4.10 Git 托管服務
- 4.11 小結
- 5. 分布式Git
- 5.1 分布式工作流程
- 5.2 為項目作貢獻
- 5.3 項目的管理
- 5.4 小結
- 6. Git工具
- 6.1 修訂版本(Revision)選擇
- 6.2 交互式暫存
- 6.3 儲藏(Stashing)
- 6.4 重寫歷史
- 6.5 使用 Git 調試
- 6.6 子模塊
- 6.7 子樹合并
- 6.8 總結
- 7. 自定義Git
- 7.1 配置 Git
- 7.2 Git屬性
- 7.3 Git掛鉤
- 7.4 Git 強制策略實例
- 7.5 總結
- 8. Git與其他系統
- 8.1 Git 與 Subversion
- 8.2 遷移到 Git
- 8.3 總結
- 9. Git 內部原理
- 9.2 Git 對象
- 9.3 Git References
- 9.4 Packfiles
- 9.5 The Refspec
- 9.6 傳輸協議
- 9.7 維護及數據恢復
- 9.8 總結
- 9.1 底層命令 (Plumbing) 和高層命令 (Porcelain)