
背景
Git每次送出代碼都需要寫commit message,否則就不允許送出。一般來說,commit message應該清晰明了,說明本次送出的目的,具體做了什麼操作……但是在日常開發中,大家的commit message千奇百怪,中英文混合使用、fix bug等各種籠統的message司空見怪,這就導緻後續代碼維護成本特别大,有時自己都不知道自己的fix bug修改的是什麼問題。基于以上這些問題,我們希望通過某種方式來監控使用者的git commit message,讓規範更好的服務于品質,提高大家的研發效率。
規範建設
規範梳理
初期我們在網際網路上搜尋了大量有關git commit規範的資料,但隻有Angular規範是目前使用最廣的寫法,比較合理和系統化,并且有配套的工具(IDEA就有插件支援這種寫法)。最後綜合阿裡巴巴高德地圖相關部門已有的規範總結出了一套git commit規範。
commit message格式
<type>(<scope>): <subject>
type(必須)
用于說明git commit的類别,隻允許使用下面的辨別。
feat:新功能(feature)。
fix/to:修複bug,可以是QA發現的BUG,也可以是研發自己發現的BUG。
- fix:産生diff并自動修複此問題。适合于一次送出直接修複問題
- to:隻産生diff不自動修複此問題。适合于多次送出。最終修複問題送出時使用fix
docs:文檔(documentation)。
style:格式(不影響代碼運作的變動)。
refactor:重構(即不是新增功能,也不是修改bug的代碼變動)。
perf:優化相關,比如提升性能、體驗。
test:增加測試。
chore:建構過程或輔助工具的變動。
revert:復原到上一個版本。
merge:代碼合并。
sync:同步主線或分支的Bug。
scope(可選)
scope用于說明 commit 影響的範圍,比如資料層、控制層、視圖層等等,視項目不同而不同。
例如在Angular,可以是location,browser,compile,compile,rootScope, ngHref,ngClick,ngView等。如果你的修改影響了不止一個scope,你可以使用*代替。
subject(必須)
subject是commit目的的簡短描述,不超過50個字元。
建議使用中文(感覺中國人用中文描述問題能更清楚一些)。
- 結尾不加句号或其他标點符号。
- 根據以上規範git commit message将是如下的格式:
fix(DAO):使用者查詢缺少username屬性
feat(Controller):使用者查詢接口開發
以上就是我們梳理的git commit規範,那麼我們這樣規範git commit到底有哪些好處呢?
- 便于程式員對送出曆史進行追溯,了解發生了什麼情況。
- 一旦限制了commit message,意味着我們将慎重的進行每一次送出,不能再一股腦的把各種各樣的改動都放在一個git commit裡面,這樣一來整個代碼改動的曆史也将更加清晰。
- 格式化的commit message才可以用于自動化輸出Change log。
監控服務
通常提出一個規範之後,為了大家更好的執行規範,就需要進行一系列的拉通,比如分享給大家這種規範的優點、能帶來什麼收益等,在大家都認同的情況下最好有一些強制性的措施。當然git commit規範也一樣,前期我們分享完規範之後考慮從源頭進行強制攔截,隻要大家送出代碼的commit message不符合規範,直接不能送出。但由于代碼倉庫操作權限的問題,我們最終選擇了使用webhook通過發送警告的形式進行監控,督促大家按照規範執行代碼送出。除了監控git commit message的規範外,我們還加入了大代碼量送出監控和删除檔案監控,減少研發的代碼誤操作。
整體流程
- 服務注冊:服務注冊主要完成代碼庫相關資訊的添加。
- 重複校驗:防止merge request再走一遍驗證流程。
- 消息告警:對不符合規範以及大代碼量送出、删除檔案等操作發送告警消息。
- DB:存項目資訊和git commit資訊便于後續統計commit message規範率。
webhook是作用于代碼庫上的,使用者送出git commit,push到倉庫的時候就會觸發webhook,webhook從使用者的commit資訊裡面擷取到commit message,校驗其是否滿足git commit規範,如果不滿足就發送告警消息;如果滿足規範,調用gitlab API擷取送出的diff資訊,驗證送出代碼量,驗證是否有重命名檔案和删除檔案操作,如果存在以上操作還會發送告警消息,最後把所有記錄都入庫儲存。
以上就是我們整個監控服務的相關内容,告警資訊通過如下形式發送到對應的釘釘群裡:
我們也有整體git commit的統計,統計個人的送出次數、不規範次數、不規範率等如下圖:
未來思考
git hooks分為用戶端hook和服務端hook。用戶端hook又分為pre-commit、prepare-commit-msg、commit-msg、post-commit等,主要用于控制用戶端git的送出工作流。使用者可以在項目根目錄的.git目錄下面配置使用,也可以配置全局git template用于個人pc上的所有git項目使用。服務端hook又分為pre-receive、post-receive、update,主要在服務端接受送出對象時進行調用。
以上這種采用webhook的形式對git commit進行監控就是一種server端的hook,相當于post-receive。這種方式并不能阻止代碼的送出,它隻是通過告警的形式來限制使用者的行為,但最終不規範的commit message還是被送出到了伺服器,不利于後面change log的生成。由于公司代碼庫權限問題,我們目前隻能添加這種post-receive類型的webhook。如大家有更高的代碼庫權限,可以采用server端pre-receive類型的webhook,直接拒絕不規範的git commit message。隻要git commit規範了,我們甚至可以考慮把代碼和bug、需求關聯等等。
當然這塊我們也可以考慮用戶端的pre-commit,pre-commit在git add送出之後,然後執行git commit時執行,腳本執行沒錯就繼續送出,反之就會駁回。用戶端git hooks位于每個git項目下的隐藏檔案.git中的hooks檔案夾裡。我們可以通過修改這塊的配置檔案添加我們的規則校驗,直接阻止不規範message的送出,也可以通過用戶端commit-msg類型的hook進行攔截,把不規範扼殺在萌芽之中。修改每個git項目下面.git目錄中的hooks檔案大家肯定覺得浪費時間,其實這裡可以采用配置全局git template來完成。但是這又會涉及到hooks配置檔案同步的問題。hooks配置檔案在本地,如何讓hooks配置檔案的修改能同步到所有使用的項目又成為一個問題。是以使用服務端hook還是用戶端hook需要根據具體需求做适當的權衡。
git hook不光可以用來做規範限制,它還可以做更多有意義的事情。一次git commit送出的資訊量很大,有作者資訊、代碼庫資訊、commit等資訊。我們的監控服務就根據作者資訊做了git commit的統計,這樣不僅可以用來監控commit message的規範性,也可以用來監控大家的工作情況。我們也可以把git commit和相關的bug關聯起來,我們檢視bug時就可以檢視解決這個bug的代碼修改,很有利于相關問題的追溯。當然我們用同樣的方法也可以把git commit和相關的需求關聯起來,比如我們定義一種格式feat *786990(需求的ID),然後在git commit的時候按照這種格式送出,webhook就可以根據這種格式把需求和git commit進行關聯,也可以用來追溯某個需求的代碼量,當然這個例子不一定合适,但足以證明git hook功能之強大,可以給我們的流程規範帶來很大的便利。
總結
編碼規範、流程規範在軟體開發過程中是至關重要的,它可以使我們在開發過程中少走很多彎路。Git commit規範也是如此,确實也是很有必要的,幾乎不花費額外精力和時間,但在之後查找問題的效率卻很高。作為一名程式員,我們更應注重代碼和流程的規範性,永遠不要在品質上将就。