这篇文章缘起在酷安上,neoFelhz 与我的对话。

经过了我的这个 APP 第三次 Release 之后,我突然觉得,自动版本控制还是很重要的,但是我觉得 SemVer 对于我的小项目过于繁琐,因此有了这篇文章。
会 git diff
的盆友,可以直接看这条 commit 快速 GET 这项技能。
https://github.com/Omico/CurrentActivity/commit/96af43e2b8b4cff53020889a6a91f40b0ceb32fe
自动版本号(versionCode)
关于自动版本号,我就像图片里说的,我认为用 commit id 的个数就能很好表达。
通过参考 git 文档,我得出以下命令:
1 2 3 4
| def getVersionCode() { def cmd = 'git rev-list HEAD --count' return cmd.execute().text.trim().toInteger() }
|
这样能通过统计所有 commit id 的个数来确定版本号。
自动版本名(versionName)
关于自动版本名,这个灵感来自一次无意间的思考,在我编译 Android 系统的时候,内核的版本号的生成让我比较好奇。
因此我翻阅了 kernel 的源码,在 <内核根目录>/scripts/setlocalversion
这个文件中,我发现了我要的,看到是由 git describe
这个命令实现的,于是我翻阅了 git 文档,经过一番探索,我得出了以下命令:
1 2 3 4
| def getVersionName() { def cmd = 'git describe --tags --dirty' return cmd.execute().text.trim() }
|
这样得到的版本名就是你的 Tag 名。
当你的工作区最后一次 commit id 与你的最新 Tag 的 commit id 相同时,你的版本名就会是<最后一个 Tag 名>
例如:
v1.0.8
当你的工作区最后一次 commit id 与你的最新 Tag 的 commit id 相同,但修改了项目工程时,你的版本名就会是<最后一个 Tag 名>-dirty
例如:
v1.0.8-dirty
当你的工作区没有提交新的 Tag ,但有新的 commit 时,你的版本名就会是<最后一个 Tag 名>-<在最后一个 Tag 之后,提交 commit 的个数>-g<commit id 的前七位>
例如:
v1.0.8-1-g96af43e
当你的工作区没有提交新的 Tag ,也没有新的 commit ,但修改了项目工程时,你的版本名就会是<最后一个 Tag 名>-<在最后一个 Tag 之后,提交 commit 的个数>-g<commit id 的前七位>-dirty
例如:
v1.0.8-1-g96af43e-dirty
在工程里应用
修改前:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { applicationId "me.omico.currentactivity" minSdkVersion 19 targetSdkVersion 25 versionCode 4 versionName "1.0.3" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.android.support:appcompat-v7:25.1.1' compile 'com.android.support:design:25.1.1' }
|
修改后:
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
| apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { applicationId "me.omico.currentactivity" minSdkVersion 19 targetSdkVersion 25 versionCode getVersionCode() versionName getVersionName() } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.android.support:appcompat-v7:25.1.1' compile 'com.android.support:design:25.1.1' }
def getVersionCode() { def cmd = 'git rev-list HEAD --first-parent --count' return cmd.execute().text.trim().toInteger() }
def getVersionName() { def cmd = 'git describe --tags --dirty' return cmd.execute().text.trim() }
|
参考链接:
https://git-scm.com/docs/git-rev-list
https://git-scm.com/docs/git-describe