问题的提出

不管是什么版本管理工具,每一条提交记录都会有一个对应的版本号,一般是一个整数,git是一个hash字符串。不管怎样,这个版本号是唯一的,有时候我们在程序运行的时候会在日志里面输出程序的版本号,或者在命令行运行的时候在控制台中输出当前程序的版本号。一般而言,如果我们程序输出的版本号,与版本控制系统源码对应的版本号有关联关系是最好不过的,这样当运行的程序出现问题的时候,可以通过程序的版本号,去源码的版本控制系统中找到对应的源码进行分析,也就是说我们知道当前运行的程序对应在版本控制系统中的源码。

通过git命令得到版本号

这里的使用环境是linux,我们的源码客户端是git,通过git命令我们可以得到当前最新版本库中的源码版本,使用git log 命令的格式化输出,可以得到每次提交结果中的各个部分,例如版本号,提交时间,提交日志。git log 命令默认情况下会输出所有提交记录的详细信息,通过使用其提供的--pretty选项我们可以指定git log 输出我们需要的部分,例如代表版本号的hash字符串部分。

git log --pretty=format:"%H" 

输出:

082472d159a9ccd72fe241319d120b1a3dd87283
59ab0468389b511d0949aaef4e5324277e1899ce
134cb39bbb64b203b146626776a56037bccb469f
395db26c60e2f3544ec85d62e6caef911e9b16df
a29c1f4b7d72bb636ea844fc2d2e70c6f49eb046

当然我们也可以只输出短hash即可,例如:

git log --pretty=format:"%h"

输出:

082472d
59ab046
134cb39
395db26
a29c1f4

同样我们的代码提交时候的时间可以通过下面的格式得到,仅仅是修改format参数即可:

git log --format="%ct" 

输出:

1499330142
1499245162
1499244031
1499237075
1498813631

这里输出的是所有提交记录的Unix时间戳,我们要得到最新的一条,只需要加上参数 -n  其中n为大于0的整数,表示输出log的前n次的提交记录,例如:

git log -1 --format="%ct"

输出:
1499330142

表示输出最新的一次提交的提交时间戳。既然有了这些信息,我们就可以得到当前最新的源码各个部分的信息,其实最重要就是提交时间,以及版本号码了,有了前面的命令使用,我们可以写出下面的shell代码:

#!/bin/sh
commit_ts=`git log -1 --format="%ct"`
commit_time=`date -d@$commit_ts +"%Y-%m-%d %H:%M:%S"`
current_time=`date +"%Y-%m-%d %H:%M:%S"`
git_version=`git log -1 --format="%h"`
sed s/MYVERSION/"version: $git_version commit: $commit_time build: $current_time"/g version.h.tmp > version.h
make clean
make

将脚本内容保存为 build.sh 每次提交源码之后,直接运行build.sh 脚本即会生成最新的头文件,该头文件被编译到程序中,我们看到版本信息包含了最新的版本号,提交时间,编译时间。其中我们有一个模版文件,version.h.tmp,其内容如下:

#ifndef _VERSION_
#define _VERSION_ "MYVERSION"
#endif

运行build.sh之后生成的version.h文件类似如下:

#ifndef _VERSION_
#define _VERSION_ "version: 082472d commit: 2017-07-06 16:35:42 build: 2017-07-11 21:01:31"
#endif

在我们的源文件中直接使用 _VERSION_ 宏就可以啦,在git提交版本的时候我们应该将version.h.tmp模版文件添加到版本控制系统中,而脚本生成的version.h由于每次build都会变化,可以忽略掉。

关于git log 命令的格式说明

我这里列出一份git log 更加全面的格式说明,供大家参考:

%H: commit hash
%h: 缩短的commit hash
%T: tree hash
%t: 缩短的 tree hash
%P: parent hashes
%p: 缩短的 parent hashes
%an: 作者名字
%aN: mailmap的作者名字 (.mailmap对应,详情参照git-shortlog(1)或者git-blame(1))
%ae: 作者邮箱
%aE: 作者邮箱 (.mailmap对应,详情参照git-shortlog(1)或者git-blame(1))
%ad: 日期 (--date= 制定的格式)
%aD: 日期, RFC2822格式
%ar: 日期, 相对格式(1 day ago)
%at: 日期, UNIX timestamp
%ai: 日期, ISO 8601 格式
%cn: 提交者名字
%cN: 提交者名字 (.mailmap对应,详情参照git-shortlog(1)或者git-blame(1))
%ce: 提交者 email
%cE: 提交者 email (.mailmap对应,详情参照git-shortlog(1)或者git-blame(1))
%cd: 提交日期 (--date= 制定的格式)
%cD: 提交日期, RFC2822格式
%cr: 提交日期, 相对格式(1 day ago)
%ct: 提交日期, UNIX timestamp
%ci: 提交日期, ISO 8601 格式
%d: ref名称
%e: encoding
%s: commit信息标题
%f: sanitized subject line, suitable for a filename
%b: commit信息内容
%N: commit notes
%gD: reflog selector, e.g., refs/stash@{1}
%gd: shortened reflog selector, e.g., stash@{1}
%gs: reflog subject
%Cred: 切换到红色
%Cgreen: 切换到绿色
%Cblue: 切换到蓝色
%Creset: 重设颜色
%C(...): 制定颜色, as described in color.branch.* config option
%m: left, right or boundary mark
%n: 换行
%%: a raw %
%x00: print a byte from a hex code
%w([[,[,]]]): switch line wrapping, like the -w option of git-shortlog(1).

最后分享一个比较好的git log 格式输出:

git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %cn %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative

其输出效果如下:
 

将git版本号编译进程序的更多相关文章

  1. 使用objcopy实现将文件编译进执行程序

    一.简介  工作中可能遇到将一个文件编译进执行程序的需求,例如bin文件.jpg文件等等.实现的方法可以使用脚本来将文件内容写入一个新的C源文件数组,达成编译进程序的目的. 现在介绍一种简单.快捷的方 ...

  2. win10 uwp 使用 msbuild 命令行编译 UWP 程序

    原文:win10 uwp 使用 msbuild 命令行编译 UWP 程序 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http:// ...

  3. linux设备驱动程序——将驱动程序编译进内核

    linux驱动程序--将驱动程序编译进内核 模块的加载 通常来说,在驱动模块的开发阶段,一般是将模块编译成.ko文件,再使用 sudo insmod module.ko 或者 depmod -a mo ...

  4. 【转】Linux驱动模块编译进内核中

    原文网址:http://blog.chinaunix.net/uid-29287950-id-4573481.html BQ27501驱动编译进内核 一.       驱动程序编译进内核的步骤 在 l ...

  5. Linux编译安装程序(使用configure、make、 make install)

    以安装vim为例. (vim 是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面). 1.获取源文件 首先进入/usr/local下(只是为了方便处理安装文件,位置随意) 用git ...

  6. Cygwin下编译的程序不使用Cygwin.dll即可运行的命令 及常用命令简介

    cc -mno-cygwin foo.c 1.$ ps PS的相关用法: QuoteUsage ps [-aefl] [-u uid]-f = show process uids, ppids-l = ...

  7. Ubuntu16.04.2 LTS下使用编译安装程序(使用configure、make、 make install)

    以安装vim为例. (vim 是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面). 1.获取源文件 首先进入/usr/local下(只是为了方便处理安装文件,位置随意) 用git ...

  8. 超具体Windows版本号编译执行React Native官方实例UIExplorer项目(多图慎入)

    ),React Native技术交流4群(458982758).请不要反复加群! 欢迎各位大牛,React Native技术爱好者加入交流!同一时候博客右側欢迎微信扫描关注订阅号,移动技术干货,精彩文 ...

  9. QT编译发布程序后报错如缺少dll、“应用程序无法正常启动(0xc000007b)”的可能解决方法

    QT编译发布程序后报错如缺少dll.“应用程序无法正常启动(0xc000007b)”的可能解决方法 最近项目要用qt,因为初学没有经验,遇到些小问题常常没什么头绪,也查不到解决方法,刚刚还因为低端错误 ...

随机推荐

  1. kafka 自定义分区器

    package cn.xiaojf.kafka.producer; import org.apache.kafka.clients.producer.Partitioner; import org.a ...

  2. python unittest 测试笔记(二):使用Requests

    1. Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用.[Python Requests快速入门 :]http://cn.python-requests.org/z ...

  3. android studio 2.32躺坑记

    按说这是没啥记录意义的.不过作为一个偶尔用一下ADT开发安卓程序的跨界老码农,遇到一个尴尬事,现在手机已经用上安卓6了,而电脑里的ADT里SDK还是18,19.越来越多的项目是android stud ...

  4. 移动端页面开发适配 rem布局原理

    主题 HTML移动端页面开发适配 rem布局原理 什么是适配,为什么要适配 我们拿到的设计图一般是以640,750,1080分辨率为基准设计的,而现在的手机终端各式各样,分辨率不同,逻辑像素不同 ,适 ...

  5. 活动页怎么切图photoshop

    一 切固定大小的单个图片 1.用pc打开图像 2.按ctrl+A(全选) 3.点击 选择 ->变换选区 ->拉参考线(把参考线放到最中央)->按回车 ->ctrl+d(取消全选 ...

  6. [0] 分析 EntityName 时出错。 行 2,位置 *。

    1. 报错内容“若要在加载设计器前避免可能发生的数据丢失,必须纠正以下错误: ”   “分析 EntityName 时出错. 行 2,位置 *.” 2. 如图: 3. 解决方案:查看项目全路径,是否有 ...

  7. [USACO4.2]草地排水Drainage Ditches

    题目背景 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草 要继续生长还要花相当长一段时间.因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹 ...

  8. Swift基础语法

    简介 特点 (1)优于OC,快速,安全 (2)取消了预编译指令包括宏定义(OC用的太多了) (3)取消了OC指针和不安全访问的使用(看不到星星了) (4)舍弃 Objective-C 早期应用 Sma ...

  9. c#中foreach的一种用法

    以下定义的MyClass类中的addnum方法使用了一个数组型参数b: public class MyClass { ; public void addnum(ref int sum, params ...

  10. phpstorm注册码

    用户名:Learn Programming License key:(包括LICENSE BEGIN和LICENSE END部分) ===== LICENSE BEGIN =====63758-120 ...