Skip to content

LV160-GIT与SVN版本号

我们在写代码的时候经常会使用 GIT 或者 SVN 来管理工程,这样我们要是可以在 C 语言工程中添加版本号,这样出现 bug 的时候也能快速的找到当时开发的情况。

一、GIT 版本号

这里先准备一个 C 语言的版本库,有如下提交记录:

shell
sumu@virtual-machine:~/4nfs/openssl$ git mylog 
* [sumu] 86a7a3d : 加密解密扩展密钥独立开来、修复警告  (HEAD -> master, origin/master) (12 小时前)
* [sumu] 9973f45 : 支持读取并打印44字节WAV头信息  (2 天前)
* [qidaink] 6d034a0 : 修复一些小bug  (2 天前)
* [qidaink] eda907b : 编写音频WAV格式文件解密demo  (2 天前)
* [qidaink] 1b9cd78 : 添加aes_core.c源文件(openssl仓库提交记录:2f33265039cdbd0e4589c80970e02e208f3f94d2)  (2 天前)
* [qidaink] 8497f05 : 添加readme说明文件  (2 天前)

注意:这里的 git mylog 是自定义的命令,可以通过 git log 查看提交记录。

1. shell 获取 GIT 相关信息

1.1 判断是否为 git 仓库

shell
git rev-parse --is-inside-work-tree

若是 git 仓库则会输出 true,若不是,则输出 false。

1.2 获取 commit id

  • 获取全部详细的 commit id
shell
git rev-list HEAD

执行效果如下:

shell
sumu@virtual-machine:~/4nfs/openssl$ git rev-list HEAD
86a7a3d01ed683b468d5bf63e92ce95c03bffbe1
9973f4574ef0307435c1ff67f3ad070fd2b20e9e
6d034a0bf3c7c5bfaa9b757932139afca59c0d8c
eda907b1627beadf9572c11f6f8e828e2149d781
1b9cd78b0c38a59c2ce9b2414099ce83e0db8d80
8497f056c38ecff050428e20eb43739d8ff00eb4
  • 获取最新一次的 commit id
shell
git rev-list HEAD | awk 'NR==1'

执行效果如下:

shell
sumu@virtual-machine:~/4nfs/openssl$ git rev-list HEAD | awk 'NR==1'
86a7a3d01ed683b468d5bf63e92ce95c03bffbe1
  • 获取最新一次 commit id 的简短 commit id
shell
git rev-parse --short HEAD | awk 'NR==1'

执行效果如下:

shell
sumu@virtual-machine:~/4nfs/openssl$ git rev-parse --short HEAD | awk 'NR==1'
86a7a3d

1.3 获取提交总数

获取最新一次提交是整个管理历史中第几次提交的命令如下:

shell
git rev-list HEAD | wc -l

执行效果如下:

shell
sumu@virtual-machine:~/4nfs/openssl$ git rev-list HEAD | wc -l
6
sumu@virtual-machine:~/4nfs/openssl$ git mylog 
* [sumu] 86a7a3d : 加密解密扩展密钥独立开来、修复警告  (HEAD -> master, origin/master) (12 小时前)
* [sumu] 9973f45 : 支持读取并打印44字节WAV头信息  (2 天前)
* [qidaink] 6d034a0 : 修复一些小bug  (2 天前)
* [qidaink] eda907b : 编写音频WAV格式文件解密demo  (2 天前)
* [qidaink] 1b9cd78 : 添加aes_core.c源文件(openssl仓库提交记录:2f33265039cdbd0e4589c80970e02e208f3f94d2)  (2 天前)
* [qidaink] 8497f05 : 添加readme说明文件  (2 天前)

1.4 获取远程仓库信息

我们这里也可以通过 shell 命令获取 git 远程关联仓库的链接:

shell
git remote -v | awk 'NR==1' | sed 's/[()]//g' | sed 's/\t/ /g' |cut -d " " -f2

执行效果如下:

shell
sumu@virtual-machine:~/4nfs/openssl$ git remote -v | awk 'NR==1' | sed 's/[()]//g' | sed 's/\t/ /g' |cut -d " " -f2
git@gitee.com:sumumm/openssl.git

2. Makefile 获取 GIT 相关信息

我们知道 Makefile 是可以执行 shell 命令的,所以我们可以在 Makefile 中使用如下命令获取 GIT 的相关版本信息

makefile
GIT_REPO_TEST = $(shell if git rev-parse --is-inside-work-tree >/dev/null 2>&1; \
					then echo "true"; \
					else echo "false"; fi ;)
ifeq ($(GIT_REPO_TEST),true)
GIT_SHA         = $(shell git rev-parse --short HEAD | awk 'NR==1')
GIT_SEQ         = $(shell git rev-list HEAD | wc -l)
GIT_VER_INFO    = $(GIT_SHA)-$(GIT_SEQ)
GIT_SVR_PATH    = $(shell git remote -v | awk 'NR==1' | sed 's/[()]//g' | sed 's/\t/ /g' |cut -d " " -f2)
else
GIT_SHA         = unknow
GIT_SEQ         = unknow
GIT_VER_INFO    = unknow
GIT_SVR_PATH    = unknow
endif

print:
	@echo GIT_SHA=$(GIT_SHA)
	@echo GIT_SEQ=$(GIT_SEQ)
	@echo GIT_VER_INFO=$(GIT_VER_INFO)
	@echo GIT_SVR_PATH=$(GIT_SVR_PATH)

执行效果如下:

shell
sumu@virtual-machine:~/4nfs/openssl$ make print 
GIT_SHA=86a7a3d
GIT_SEQ=6
GIT_VER_INFO=86a7a3d-6
GIT_SVR_PATH=git@gitee.com:sumumm/openssl.git

3. 将 GIT 信息传入 C 工程

3.1 Makefile

makefile
#GIT_SHA = $(shell git rev-list HEAD | awk 'NR==1')
GIT_REPO_TEST = $(shell if git rev-parse --is-inside-work-tree >/dev/null 2>&1; \
					then echo "true"; \
					else echo "false"; fi ;)
ifeq ($(GIT_REPO_TEST),true)
GIT_SHA         = $(shell git rev-parse --short HEAD | awk 'NR==1')
GIT_SEQ         = $(shell git rev-list HEAD | wc -l)
GIT_VER_INFO    = $(GIT_SHA)-$(GIT_SEQ)
GIT_SVR_PATH    = $(shell git remote -v | awk 'NR==1' | sed 's/[()]//g' | sed 's/\t/ /g' |cut -d " " -f2)
else
GIT_SHA         = unknow
GIT_SEQ         = unknow
GIT_VER_INFO    = unknow
GIT_SVR_PATH    = unknow
endif

ifneq ($(GIT_VER_INFO),)
	CFLAGS += -DGIT_VERSION=\"$(GIT_VER_INFO)\"
else
	CFLAGS += -DGIT_VERSION=\"unknown\"
endif

ifneq ($(GIT_SVR_PATH),)
	CFLAGS += -DGIT_PATH=\"$(GIT_SVR_PATH)\"
else
	CFLAGS += -DGIT_PATH=\"unknown\"
endif

3.2 C 语言工程

c
#include <stdio.h>
int main(int argc, const char *arhv[])
{
    printf("*** Build Time: %s %s,Git Version: %s Git Remote: ***\n", __DATE__, __TIME__, GIT_VER_INFO, GIT_SVR_PATH);
    return 0;
}

4. 使用实例

可以看这个仓库:在 C 工程中添加 Git 版本信息打印 · 1a7ff22 · 苏木/openssl - Gitee.com

二、SVN 版本号

由于 SVN 用的不多,这里就不详细写了,原理和 GIT 是一样的,都是通过 gcc 的-D 参数将宏传入工程。