将git版本号编译进程序

问题的提出

不管是什么版本管理工具,每一条提交记录都会有一个对应的版本号,一般是一个整数,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 [email protected]$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/[email protected]{1}
%gd: shortened reflog selector, e.g., [email protected]{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

其输出效果如下:
 

时间: 2024-08-08 01:24:03

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

怎么把wifidog直接编译进openwrt

怎么把wifidog直接编译进openwrt,让生成的bin文件就带有wifidog,省得再去装ipk文件? openwrt 根目录make menuconfig 搜索 Captive portal/ 看下有没有wifidog选项,如果没有 ./scripts/feeds update -a ./scripts/feeds install -a make menuconfig 还不行的话,在项目下终端: vim feeds.conf.default 增加这一行: src-git wifidog

【嵌入式开发】gcc 学习笔记(一) - 编译C程序 及 编译过程

一. C程序编译过程 编译过程简单介绍 : C语言的源文件 编译成 可运行文件须要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (assembly) 得到机器码, 连接 (linking) 得到可运行文件; -- 查看每一个步骤的编译细节 : "-E" 相应 预处理, "-S" 相应 编译, "-c" 相应 汇编, "-O" 相应 连接; -- 每一个步骤

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

cc -mno-cygwin foo.c 1.$ ps PS的相关用法: QuoteUsage ps [-aefl] [-u uid]-f = show process uids, ppids-l = show process uids, ppids, pgids, winpids-u uid = list processes owned by uid-a, -e = show processes of all users-s = show process summary-W = show wi

Android开发Git版本号控制,究竟哪些文件不要提交

安卓开发的小伙伴们.想必大家在创建项目的时候,都有为project的哪些文件须要提交的git的版本号控制而犯愁过吧.深怕有些文件提交了影响团队其它成员的更新使用.尤其是把一些暂时的编译构建文件给提交了,被Team Leader骂的不要不要的. 下面就是不须要经过git版本号控制来提交的文件和文件夹,详细代码能够查看project的.gitignore文件: IntelliJ IDEA(IDE相关的设置) .idea *.iml *.ipr *.iws Gradle(gradle相关的) .gra

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

原文网址:http://blog.chinaunix.net/uid-29287950-id-4573481.html BQ27501驱动编译进内核 一.       驱动程序编译进内核的步骤 在 linux 内核中增加程序需要完成以下三项工作: 1. 将编写的源代码复制到 Linux 内核源代码的相应目录: 2. 在目录的 Kconfig 文件中增加新源代码对应项目的编译配置选项: 3. 在目录的 Makefile 文件中增加对新源代码的编译条目. bq27501驱动编译到内核中具体步骤如下:

C/C++编译的程序内存组成:

#include int main(){int a[1000000];//局部变量return 0;} 编译运行后发现溢出错误. #include int a[1000000];//全局变量int main(){return 0;} 编译运行后正常. 在解释原因前我们先看一下一个由C/C++编译的程序占用的内存分为几个部分: 1. 栈区(stack sagment):由编译器自动分配释放,存放函数的参数的值,局部变量的值等.在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区 域

gcc编译C++程序

gcc编译C++程序 单个源文件生成可执行程序下面是一个保存在文件 helloworld.cpp 中一个简单的 C++ 程序的代码: /* helloworld.cpp */#include <iostream>int main(int argc,char *argv[]){    std::cout << "hello, world" << std::endl;    return(0);}程序使用定义在头文件 iostream 中的 cout,向

Git算不算程序员的必备技能?

点击关注 异步图书,置顶公众号 每天与你分享 IT好书 技术干货 职场知识 参与文末话题讨论,每日赠送异步图书. --异步小编 Git的背后有着一个非常精彩的成功故事.2005年4月,Linus Torvalds因不满当时任何一个可用的开源版本控制系统,就亲自着手实现了Git. 时至今日,如果我们在Google中搜索"git version control"这几个关键词,都会看到数以百万计的返回结果.Git已经俨然成为了新型开源项目的一个标准.许多大型的开源项目都已经或正在计划迁移到G

使用gcc编译C程序

GCC 全称"GNU C Compiler",不过自从面世后,增加了多种语言的支持,不过用的最多的是还是编译C或C++程序(另外有个工具叫做G++).GCC是一种多目标编译器,通过可交互的后端处理器,为多种计算机架构生成可执行程序. 话说回来,什么是编译器呢? 编译器并不是一个单一的程序,它们通常由六七个稍小的程序组成,这些程序由一个叫做"编译器驱动器(Compiler driver)"的控制程序调用. 编译器一般由以下几部分组成: 预处理器(preprocesso