隨着OPPO互聯網業務快速增加,團隊規模的不斷擴大,對代碼質量的要求也在不斷地提升,而現有的代碼審查工具GitLab和Gerrit已經沒法知足咱們的評審需求,主要凸顯如下幾個問題:git
咱們迫切須要一款高效、簡潔的代碼審查工具來輔助咱們作代碼評審。算法
若是隻作一個評審工具,缺乏代碼管理功能,須要頻繁在代碼評審工具和代碼託管工具之間切換,用戶體驗不友好。數據庫
代碼審覈和代碼管理最好在一個系統中,但要開發一個二者兼備的工具系統存在兩個問題:服務器
第1、要實現具有代碼管理功能的代碼評審系統,須要開發一套較爲完善的代碼管理系統,而已有的代碼託管平臺自己已比較成熟,再另外開發其難度和工做量都比較大。架構
第2、項目風險高,開發出來的系統穩定性和可靠性存在必定的挑戰。工具
是否能夠存在一種方法:既不用開發代碼管理系統但又能實現Code Review的簡單解決方案。在進行深度調研以後,咱們發如今GitLab之上開發Code Review具備可行性,通過幾月的研發,咱們的Code Review系統火眼就這麼誕生了。post
火眼是OPPO互聯網自研的代碼審查工具,它融合了Gerrit的評審功能和GitLab代碼管理功能,其主要功能包括:spa
火眼相較於其餘代碼評審工具,主要有如下特色:命令行
爲了方便你們理解後文,這裏對火眼原理作一個簡單的介紹。火眼主要利用了Git的refs命名空間的特性,下圖是某一個Git倉庫在服務器存儲的目錄結構:代理
這個結構主要包含如下幾個部分:
火眼在實現Code Review利用的就是將對分支refs/heads/{Branch}的提交,改成指向到refs/changes/{ChangeId}/{Branch},其中ChangeId是指的某個特性,Branch是相應的開發分支,經過這個特性來存儲待評審的Commit內容,當評審經過時,將refs/changes/{ChangeId}/{Branch}合併到原先正常的分支中。以開發dev分支爲例,提交的模型以下:
對於每一個特性(ChangeId),都獨立的產生評審,當評審完成以後再合併到其對應的分支。當初咱們的隔離維度是分支維度,相同分支產生的評審存儲在一塊兒。當咱們發現這些評審存儲在一塊兒後,評審的代碼會相互干擾,影響評審的獨立性,因此才產生了現有的以特性爲隔離維度的評審模式。
下圖展現了火眼系統目前的架構:
火眼RPC是一個Dubbo實現的代理服務,其主要完成如下Git操做:
火眼Web調用火眼RPC來完成對Git倉庫的操做。火眼RPC的核心處理Git底層數據是採用JGit(一款開源的Java操做Git的工具)實現,火眼RPC在JGit基礎上實現了全部的Git查看操做,可是JGit並無提供基於裸庫(服務端存儲Git文件的形式)的合併方法。咱們就基於JGit提供的底層的原子方法,通過封裝、改造獲得了咱們想要的基於裸庫的合併算法。
火眼Web是一個 Web工程,其主要處理如下內容:
在用戶提交了評審以後,評審人會收到評審邀請連接,點擊後便可進行評審。對於評論咱們設置了一個標記爲解決的狀態,方便評審人或評審發起者跟蹤問題。
爲了使評審功能更加完善,咱們將GitLab的Merge Request模式移植了過來,並作了一些改進。其中一個特別的改進點是:鎖定提交。 當用戶在選擇鎖定提交的時候,合入分支的後續提交將在本次Merge Request不會被合入。咱們認爲這點在多人開發的時候很重要,保證了須要被合併的代碼就只包含發起Merge Request時的代碼。
以往其餘團隊在使用Gerrit作評審的時候的一個比較大的痛點是:在評審流程走完以後合併代碼的時候發現被評審的代碼與已經合入到倉庫裏面的代碼有衝突,這個時候又不得再也不次合併代碼,從新發起評審流程。火眼特別解決了這個問題,在用戶作評審時,將被評審的代碼和將要合入分支在內存中合併一次,若是發生了衝突就在評審界面醒目的提示發生衝突,並告知解決衝突方案。
像主流的代碼託管工具同樣咱們在界面上提供了可視化操做Git基本數據的功能。經過火眼RPC目前實現瞭如下功能:分支管理、文件管理、標籤管理、提交歷史查看、對比等。
咱們並未在火眼系統中單獨開發一套權限系統,整個系統是複用的GitLab權限,每隔一段時間或GitLab權限發生改變時,火眼會拉取一遍GitLab的權限數據,主要包括:項目,組,項目與人的關係,組與人的關係。
火眼Git鉤子是火眼系統實現的兩個Git服務端兩個鉤子:提交前鉤子(pre-receive)和提交後鉤子(post-receive)。提交前鉤子用於提交代碼用戶選擇普通提交併開啓強制評審時,系統拒絕本次提交。提交後鉤子用於當評審代碼已成功提交,調用火眼平臺,生成評審任務。下圖展現了兩個鉤子在提交代碼過程當中各自的功能:
火眼命令行是火眼用於提交評審的客戶端命令行。由於若是須要提交評審任務,須要執行git push HEAD:refs/changes/{ ChangeId } /{Branch}命令,該命令太長,使用者體驗不友好,上手難度高,因此咱們決定使用客戶端命令行的方式來簡化提交過程,並下降使用成本。
爲了讓各個平臺(Linux/Windows/Mac)都能使用火眼命令行,火眼命令行用Go語言編寫,並編譯成各個平臺的二進制文件。
準備工做:安裝火眼命令行,下列爲具體使用步驟:
在開發流程上和平常開發差別不大,只是用火眼的提交命令替代了Git的提交命令。
Code Review能解決業務人工評審問題,但部分代碼bug或smell(代碼臭味)能夠經過代碼掃描工具提早發現,所以後續咱們將引入自研的自動化掃描工具,並在評審流程中嵌入此過程,以輔助評審。
自由評審模式相較提交後即自動發起評審模式,區別在於其可以評審任意提交,該模式適用於代碼開發完畢回顧或審查代碼,但不涉及到合併代碼的場景,如代碼評審會議。
火眼系統是基於GitLab提交代碼的過程作攔截,現有GitLab用戶能夠在很低的使用成本上使用火眼。火眼系統靈活的評審模式、多樣化的評審規則以及靈活的評審分支選擇能夠很好的輔助團隊作好代碼評審工做,達到了該系統開發的預期效果。