如何使用 Git Hooks 簡化團隊的開發工作流程
已發表: 2022-03-10為團隊或開源項目工作的主要要求之一是使用版本控制系統 (VCS)。 Git 是一個免費的開源分佈式版本控制系統,用於在軟件開發過程中跟踪源代碼更改。 它由 Linus Torvalds 在 2005 年創建,用於開發 Linux 內核。 它易於學習,佔用空間小,性能快如閃電。
您很有可能已經使用過 Git(因為它是開發社區中最流行和採用最廣泛的 VCS 工具之一),並且您很可能已經了解了通過推送和拉取來暫存和提交代碼的知識它來自遠程存儲庫。 本文不會討論 git 工作流程的基礎知識,但主要關注 git 鉤子以及如何利用它們以在團隊中實現更好的協作。 隨著團隊規模的擴大,讓貢獻者保持一致並維護有關代碼的不同規則變得更加重要。
什麼是 Git 鉤子?
Git 掛鉤是在 git 存儲庫中執行特定操作或事件時觸發的腳本。 這些操作與版本控制工作流程的一部分有關,例如提交和推送。 通過自動化 git 工作流程中的任務,Hooks 非常有用。 例如,它們可以幫助我們根據某些特定規則驗證代碼庫的語法,或者在提交更改之前運行一些測試。
如何設置它們?
Git 鉤子是一個內置功能,這意味著只要初始化 git 存儲庫,我們就可以訪問它們並開始使用它們。 讓我們通過嘗試設置它們來更詳細地了解這意味著什麼。
使用您最喜歡的終端,創建一個新的 git 存儲庫。
mkdir my-new-repository && cd my-new-repository git init ls -la
您會注意到剛剛創建了一個新的隱藏目錄。 此文件夾.git
用於從 git 存儲存儲庫相關信息,例如版本控制哈希、有關提交的信息、遠程存儲庫地址等。 這也是 git .git/hooks
實際存在的鉤子的文件夾。 您可以找到一些在初始化期間自動創建的預填充示例腳本。 這些實際上是特定操作後將觸發的腳本。
ls .git/hooks
您可以找到的一些示例是:
-
pre-commit.sample
:在提交之前調用。 -
commit-msg.sample
:就地編輯消息文件。 -
post-receive.sample
:在遠程存儲庫更新後調用。
引擎蓋下
現在我們知道了在哪裡可以找到鉤子,讓我們退後一步來了解它們實際上是如何工作的。
Git hooks 是基於事件的,所以只要我們在開發流程中執行一個 git 命令,git 就會檢查 hooks 文件夾以查找是否有關聯的腳本可以運行。 其中一些腳本將在這些開發流程操作之前或之後運行。
對於我們來說,一個很好的例子是提交工作流,這是一個非常熟悉的用例,可以更具體地了解觸發鉤子的流程。
每當我們對代碼庫提交任何更改時,其中一些相關的鉤子都會按以下順序觸發:
-
pre-commit
:檢查即將提交的快照並驗證要提交的內容。 -
prepare-commit-msg
:允許您在提交作者看到之前編輯默認消息。 -
commit-msg
:將提交消息設置為模板。 -
post-commit
:在提交完成後運行一個動作,例如發送一個通知。
在上面的存儲庫中,現在讓我們嘗試添加一些自定義的提交前和提交後腳本,以進一步可視化 git 掛鉤的實際工作方式。
nano .git/hooks/pre-commit
添加以下代碼段:
#!/bin/sh echo Changes are about to be committed
確保我們的腳本是可執行的:
chmod +x .git/hooks/pre-commit
對post-commit
腳本重複上述過程:
nano .git/hooks/post-commit
#!/bin/sh echo Changes have been committed
chmod +x .git/hooks/post-commit
現在我們可以添加一個帶有小 HTML 片段的新文件nano index.html
,僅用於演示目的(無需讓 HTML 驗證器知道這一點)。
<h1>Hello world from our new repository!</h1>
我們將通過 staging 在我們的代碼庫中添加更改,然後提交:
git add . git commit
提交成功後,我們可以看到上面添加的兩個腳本的輸出如下:
Changes are about to be committed Changes have been committed
正如預期的那樣,git 在提交流程中觸發了鉤子。 添加的pre-commit
和post-commit
腳本正在運行,並將以正確的順序執行(基於我們前面提到的順序)。
這是一個簡單的演示,目的是了解提交工作流腳本的工作方式以及它們是如何執行的。 有關此工作流程的更多詳細信息,您可以在文檔中閱讀更多信息。
在上面的示例中,我們選擇用 bash 編寫這兩個腳本,但事實是 git 支持可以用我們想要的任何腳本語言編寫的鉤子。 Ruby、Python 或 JavaScript 是很好的選擇,只要我們在可執行腳本的第一行設置正確的 shebang。
例如,我們可以將pre-commit
鉤子重寫為 Node.js 腳本,如下所示:
#!/usr/bin/env node console.log("Changes are about to be commited")
本地和遠程掛鉤
鉤子在本地和遠程(或客戶端和服務器)之間是分開的。 雖然本地掛鉤在本地存儲庫上的特定操作之前或之後運行,但遠程掛鉤在推送到服務器之前或之後運行。 本地的不能用於執行策略,因為它們的性質使開發人員可以輕鬆地更改它們。 它們主要用於遵守我們希望在團隊中應用的一些特定準則。 如果我們想要更嚴格並為我們的存儲庫執行一些策略,我們將駐留在遠程掛鉤中。
本地掛鉤
pre-commit
-
prepare-commit-msg
-
commit-msg
-
post-commit
-
applypatch-msg
-
pre-applypatch
-
post-applypatch
-
pre-rebase
-
post-rewrite
-
post-checkout
-
post-merge
-
pre-push
遠程掛鉤
pre-receive
-
update
-
post-receive
共享掛鉤
Git 鉤子都是關於在團隊內共享它們。 這是它們存在的主要原因:促進更好的團隊協作,自動化有害流程,讓我們只關注代碼庫的重要部分。
如前所述, .git/hooks
是託管我們自定義掛鉤的文件夾,但是當我們需要在團隊中共享這些腳本時,這並沒有真正的幫助,因為 git 不會跟踪該文件夾。
解決這個問題的一個好方法是將我們所有的自定義鉤子添加到我們存儲庫中的一個單獨的文件夾中。 例如,我們可以添加一個.githooks
文件夾並將可執行腳本保存在那裡。 然後,在項目初始化時,我們可以將這些腳本顯式複製或符號鏈接到原始文件夾,以保留我們的鉤子.git/hooks
。
find .git/hooks -type l -exec rm {} \\; find .githooks -type f -exec ln -sf ../../{} .git/hooks/ \\;
或者,如果您使用的是最新的 git 版本( 2.9
及更高版本),我們可以直接將 git hooks 路徑配置到我們的自定義文件夾:
git config core.hooksPath .githooks
Git Hooks Made Easy(一個 JavaScript 代碼庫用例)
有一些工具可以幫助我們進一步將 git 鉤子集成到我們的代碼庫的需求中。 特別是對於 JavaScript 代碼庫,我們可以使用 Husky 通過配置輕鬆自定義 git 事件的操作。
例如,我們可以輕鬆地對代碼進行 lint 或在pre-commit
事件中運行一些測試,然後根據 linting、測試或兩者是否成功繼續提交。
這可以通過簡單地擴展package.json
配置來實現:
{ "scripts": { "test": "echo Running tests" }, "devDependencies": { "eslint": "5.16.0", }, "husky": { "hooks": { "pre-commit": "eslint . && npm test", } } }
結論
在本文中,我們發現對 git 存儲庫執行的不同操作可以選擇性地觸發自定義腳本運行。 這些腳本可以在本地由開發人員控制,也可以在遠程為團隊或項目更集中地管理。 我們還了解到,腳本通常用 bash 之類的 shell 腳本編寫,但實際上幾乎可以使用任何腳本語言,甚至是 JavaScript。
Git 掛鉤可以成為精心設計的工作流程中非常強大的一部分,我鼓勵您嘗試一下,看看您可以為自己的項目做些什麼。