在 Android app 內顯示 Git commit hash

有些 Android app 除了顯示版本號碼之外,還會有該版本的 Git commit hash。如果有好幾部測試機做測試的話,可能會在開發時先後在不同的機安裝過不同版本的 app。但就沒有每次都更新版本號碼。加了 commit hash 就容易分辨 app 的實際版本。其實要顯示 commit hash 的做法不太難,不需要每次人手更改的。只需要改一下 appbuild.gradle 就可以了。

build.gradleGist
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.util.regex.Pattern

apply plugin: 'com.android.application'

/**
* Extract Git commit hash of HEAD with number of changed files
*/

def getGitHashVersionName = {
try {
def hashOutput = new ByteArrayOutputStream()
def changeOutput = new ByteArrayOutputStream()
def gitVersionName
exec {
commandLine 'git', 'rev-list', '--max-count=1', 'HEAD'
standardOutput = hashOutput
}
exec {
commandLine 'git', 'diff-index', '--shortstat', 'HEAD'
standardOutput = changeOutput
}
gitVersionName = hashOutput.toString().trim().substring(0, 7);
if (!changeOutput.toString().trim().empty) {
def pattern = Pattern.compile("\\d+");
def matcher = pattern.matcher(changeOutput.toString().trim())
if (matcher.find()) {
gitVersionName += "-" + matcher.group()
}
}
return gitVersionName
} catch (ignored) {
return "UNKNOWN";
}
}

android {
// Skip the other items...

buildTypes {
debug {
debuggable true
minifyEnabled false
signingConfig signingConfigs.debug
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
applicationIdSuffix debug_application_id_suffex
buildConfigField "String", "GIT_VERSION_NAME", "\"${getGitHashVersionName()}\""
}
release {
minifyEnabled true
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField "String", "GIT_VERSION_NAME", "\"${getGitHashVersionName()}\""
}
}
}

上面的 getGitHashVersionName function 就是用 git getGitHashVersionNamegit diff-index 取得 commit hash 和未 commit 的檔案數目。如果有未 commit 的檔案的話,commit hash 後面就會補上檔案數目,方便分辨。

buildTypes 內的 buildConfigField 就是為 Gradle 每次 build 都會自動產生的 BuildConfig class 加入一個 public static final 的 field。只需要在 app 的 source code 直接用 BuildConfig.GIT_VERSION_NAME 就能拿到 Git commit hash。