引言
本文所說的『規(guī)范』包含兩個部分
git commit 是注釋的規(guī)范
git commit 時對代碼規(guī)范的檢查
在 AndroidStudio 中 git 提交失敗的信息可以在右下角的 Event Log 窗口查看
技術(shù)支持
- .git 目錄下面有一個 hooks 目錄,里面可以存放一些 hook 文件,對 git 操作進行 hook 。

其中 commit-msg 文件是我們用來檢測 commit 注釋的 hook ,pre-commit 可
以在 commit 之前做一次攔截 。這兩個文件需要手動添加 。但是 git 提
供了一系列 sample 文件,就是上圖里面的 xxx.sample ,去掉這些文件的后綴名
即可體驗 git hook 。Linux 環(huán)境下,需要給這些 git hook 文件增加權(quán)限。(例如
chmod +x commit-msg)。
git hook 文件里面內(nèi)容是一些腳本,可以是 shell 、perl 、bat 、groovy 。只要
你的電腦支持的腳本,都可以在這個文件里面使用。
- checkStyle 插件可以幫我們對 Java 編碼進行檢查,在 AndroidStudio 之中配置也特別方便。
開始實戰(zhàn)
選取腳本
因為小組成員使用了 windows 和 mac 兩種操作系統(tǒng),所以排除 bat 、shell 腳本。在 Python 、per 、groovy 中選擇了 groovy 腳本。畢竟 AndroidStudio 是使用 gradle 構(gòu)建項目,gradle 使用的是 groovy 。
下載 groovy配置環(huán)境變量(如何配置環(huán)境變量這里省略)
hook git commit 的注釋
復制 commit-msg.sample 文件,刪除后綴名,賦予權(quán)限執(zhí)行 chmod +x commit-msg(Windows 環(huán)境不需要),編輯文件刪除內(nèi)容,添加內(nèi)容如下
#!/usr/bin/env groovy
import static java.lang.System.exit
println "commit-msg"
// First argument is the name of the
// temporary commit message file.COMMIT_EDITMSG
def msgFileName = args[0]
// Get the commit message file.
def msgFile = new File(msgFileName)
// Read commit message from file.
def commitMessage = msgFile.text
/**
* 提交規(guī)范
* 必須包含 header 、body、footer 使用兩個換行區(qū)分
* 其中 header 必須,body 和 footer 可選
*
* 每個部分不得超過 70 個字
* header 必須包含兩個部分 type:subject 使用冒號區(qū)分
* type 必須是以下類型的一種
* --feat: 新功能
* --fix:修復bug
* --style:格式變動,不影響代碼運行
* --refactor:重構(gòu)
* --perf:新能優(yōu)化
* --test:增加測試
* subject 是對 commit 的描述
*
*/
def inputs = commitMessage.split("\n\n")
def template = "提交格式錯誤\n" +
"{Type}:{Subject}\n\n" +
"{Body} \n\n" +
"{Footer} \n\n" +
"-------參數(shù)說明------ \n"+
"每個部分不得超過70個字 \n" +
"{Type},{Subject} 不能為空 \n" +
"Type 必須是以下類型\n" +
" --feat: 新功能\n" +
" --fix:修復bug\n" +
" --style:格式變動,不影響代碼運行\(zhòng)n" +
" --refactor:重構(gòu)\n" +
" --perf:新能優(yōu)化\n" +
" --test:增加測試\n" +
"Subject 是對 commit 的描述,不能為空"
if (inputs.length > 3) {
println template
exit 1
}
inputs.any {
if (it.length() > 70)
exit 1
}
def head =inputs[0].split(":")
if(head.length!=2){
println template
exit 1
}
def type = head[0]
def subject = head[1]
def types = ["feat","fix","style","refactor","perf","test"]
if(subject.isEmpty()||!types.contains(type)){
println template
exit 1
}
exit 0
第一行聲明使用的腳本類型,必須保證當前環(huán)境變量中存在該腳本 bin 目錄。
git commit 注釋的內(nèi)容會存到 .git 目錄的 COMMIT_EDITMSG 文件中,文件會被當做一個 參數(shù)傳遞給 commit-msg 腳本(即存儲在 args[0] 之中)。
上面的腳本對 commit 的注釋做了一寫格式判斷,不符合判斷的注釋會導致提交失敗。
使用 checkStyle
在 AndroidStudio 中配置 checkStyle 的 task。
checkStyle 配置在 Android 工程最外層 build.gradle 之中。

在Android 工程最外層防止一個 checkStyle.xml 文件,該文件來自華為 checkStyle
配置完成以后,我們可以在 AndroidStudio 的 Terminal 窗口執(zhí)行 ./gradle checkStyle
進行 checkStyle 檢查。(比如故意把變量設(shè)置為 aaa_bbb)

在 windows 環(huán)境先可能出現(xiàn)中文亂碼
是因為 windows 環(huán)境的 cmd 默認是 gbk 編碼,可以執(zhí)行
chcp 65001
把 cmd 設(shè)置為 utf-8 編碼 參考資料
checkStyle 命令有一個 bug
第一次檢測出 Java 規(guī)范問題以后,再次執(zhí)行就會檢測到。需要在每次 checkStyle 之前執(zhí)行一次 clean 命令 。完善后的 checkStyle 命令為
./gradle clean checkStyle
git hook 調(diào)用 checkStyle
在 pre-commit 的hook 中用 gradle 調(diào)用對應(yīng)的 task 如果檢測不通過,提交失敗。(pre-commit 的創(chuàng)建參考上面內(nèi)容),內(nèi)容如下
#!/usr/bin/env groovy
import static java.lang.System.exit
def command = " ./gradlew clean checkstyle "
if (System.properties['os.name'].toLowerCase().contains('windows')) {
println "it's Windows"
command = "cmd /c gradlew clean checkstyle "
} else {
println "it's not Windows"
}
def proc = command.execute()
proc.waitFor()
// Obtain status and output
//println "return code: ${ proc.exitValue()}"
//println "stdout: ${proc.in.text}"
//println "stdout: ${proc.text}"
//println "stderr: ${proc.err.text}"
def result = proc.err.text
if(result.isEmpty()){
exit 0
}else{
println result
exit 1
}
在 Windows 環(huán)境下,groovy 調(diào)用 cmd 需要在 命令之前增加 "cmd /c" 否則 git 會報錯找不到gradlew 命令
最后說幾點
- .git 目錄不會提交到遠程倉庫,所以需要客戶端自己把 hook 文件放到 .git/hooks 目錄下面。
可以在項目中增加一個 gitHooks 目錄存放這些 hooks 文件。 - git hook 可以繞過,所以最好在 git 的服務(wù)端也配置 hook ,針對 git push 請求進行攔截。
以上就是『使用 git hook 規(guī)范 Android 項目』 全部調(diào)研。
參考資料
Android項目git+gradle實現(xiàn)commit時checkstyle檢查
Android Studio項目gradle+Git Hooks 實現(xiàn)提交時對提交日志和代碼(checkStyle)的檢查