And*_*dyL 76 c git version-control workflow
有没有一种简单的方法来编写可以访问其Git版本哈希的C代码?
我在C中编写软件以在实验室环境中收集科学数据.我的代码将它收集的数据记录在.yaml文件中以供以后分析.我的实验每天都在变化,我经常需要修改代码.为了跟踪修订,我使用了一个git存储库.
我希望能够在我的.yaml数据文件中包含Git版本哈希作为注释.这样,我可以查看.yaml文件并确切地知道用于生成该文件中显示的数据的代码.有一种简单的方法可以自动执行此操作吗?
ndy*_*yer 148
如果您使用的是基于make的构建,则可以将其放在Makefile中:
GIT_VERSION := "$(shell git describe --abbrev=4 --dirty --always --tags)"
Run Code Online (Sandbox Code Playgroud)
(参见man git describe,了解开关的用途)
然后将其添加到您的CFLAGS:
-DVERSION=\"$(GIT_VERSION)\"
Run Code Online (Sandbox Code Playgroud)
然后你可以直接在程序中引用该版本,就像它是#define一样:
printf("Version: %s\n", VERSION);
Run Code Online (Sandbox Code Playgroud)
默认情况下,这只会打印一个缩写的git commit id,但是您可以选择使用以下内容标记特定版本:
git tag -a v1.1 -m "Release v1.1"
Run Code Online (Sandbox Code Playgroud)
然后会打印出来:
Version: v1.1-2-g766d
Run Code Online (Sandbox Code Playgroud)
这意味着,2提交过v1.1,git commit id以"766d"开头.
如果树中存在未提交的更改,则会附加"-dirty".
没有依赖项扫描,因此您必须明确make clean
强制更新版本.然而,这可以解决.
优点是它很简单,不需要任何额外的构建依赖,如perl或awk.我已经在GNU automake和Android NDK版本中使用了这种方法.
小智 38
在我的程序中,我将git版本号和构建日期保存在一个名为的单独文件中,version.c
如下所示:
#include "version.h"
const char * build_date = "2009-11-10 11:09";
const char * build_git_sha = "6b54ea36e92d4907aba8b3fade7f2d58a921b6cd";
Run Code Online (Sandbox Code Playgroud)
还有一个头文件,如下所示:
#ifndef VERSION_H
#define VERSION_H
extern const char * build_date; /* 2009-11-10 11:09 */
extern const char * build_git_sha; /* 6b54ea36e92d4907aba8b3fade7f2d58a921b6cd */
#endif /* VERSION_H */
Run Code Online (Sandbox Code Playgroud)
头文件和C文件都是由Perl脚本生成的,如下所示:
my $git_sha = `git rev-parse HEAD`;
$git_sha =~ s/\s+//g;
# This contains all the build variables.
my %build;
$build{date} = make_date_time ();
$build{git_sha} = $git_sha;
hash_to_c_file ("version.c", \%build, "build_");
Run Code Online (Sandbox Code Playgroud)
这里hash_to_c_file
确实创造了所有的工作version.c
,并version.h
和make_date_time
使一个字符串,如图所示.
在主程序中,我有一个例程
#include "version.h"
// The name of this program.
const char * program_name = "magikruiser";
// The version of this program.
const char * version = "0.010";
/* Print an ID stamp for the program. */
static void _program_id_stamp (FILE * output)
{
fprintf (output, "%s / %s / %s / %s\n",
program_name, version,
build_date, build_git_sha);
}
Run Code Online (Sandbox Code Playgroud)
我对git知之甚少,所以如果有更好的方法,我会欢迎评论.
And*_*dyL 11
我最终使用的东西与@ Kinopiko的答案非常相似,但我用的是awk而不是perl.如果你坚持使用mingw性质而不是perl安装了awk的windows机器,这是很有用的.这是它的工作原理.
我的makefile中有一行调用git,date和awk来创建ac文件:
$(MyLibs)/version.c: FORCE
$(GIT) rev-parse HEAD | awk ' BEGIN {print "#include \"version.h\""} {print "const char * build_git_sha = \"" $$0"\";"} END {}' > $(MyLibs)/version.c
date | awk 'BEGIN {} {print "const char * build_git_time = \""$$0"\";"} END {} ' >> $(MyLibs)/version.c
Run Code Online (Sandbox Code Playgroud)
每次编译我的代码时,awk命令都会生成一个如下所示的version.c文件:
/* version.c */
#include "version.h"
const char * build_git_sha = "ac5bffc90f0034df9e091a7b3aa12d150df26a0e";
const char * build_git_time = "Thu Dec 3 18:03:58 EST 2009";
Run Code Online (Sandbox Code Playgroud)
我有一个静态version.h文件,如下所示:
/*version.h*/
#ifndef VERSION_H_
#define VERSION_H_
extern const char * build_git_time;
extern const char * build_git_sha;
#endif /* VERSION_H_ */
Run Code Online (Sandbox Code Playgroud)
我的其余代码现在可以通过简单地包含version.h头来访问构建时和git哈希.为了将它全部包装起来,我告诉git通过在我的.gitignore文件中添加一行来忽略version.c. 这样git不会经常给我合并冲突.希望这可以帮助!
您的程序可以git describe
在运行时或作为构建过程的一部分进行shell .
你可以做两件事:
您可以让Git为您嵌入一些版本信息.
更简单的方法是使用ident
属性,这意味着放(例如)
*.yaml ident
Run Code Online (Sandbox Code Playgroud)
在.gitattributes
文件中,并$Id$
在适当的地方.它将自动扩展为文件内容的 SHA-1标识符(blob id):这不是文件版本,也不是最后一次提交.
Git以这种方式支持$ Id $关键字,以避免触摸在分支切换,倒带分支等期间未更改的文件.如果您真的希望Git将提交(版本)标识符或描述放在文件中,您可以(ab)使用filter
属性,使用clean/smudge过滤器在结帐时展开一些关键字(例如$ Revision $),并清理它以进行提交.
你可以让构建过程为你做这件事,比如Linux内核或Git本身.
看一下GIT-VERSION-GEN脚本及其在Git Makefile中的用法,或者例如这个Makefile如何在生成/配置gitweb/gitweb.cgi
文件期间嵌入版本信息.
GIT-VERSION-GEN使用git describe生成版本描述.它需要更好地标记(使用签名/注释标签)项目的发布/里程碑.
归档时间: |
|
查看次数: |
44011 次 |
最近记录: |