【发布时间】:2011-09-25 11:15:08
【问题描述】:
我使用 git 作为我的 c++ 项目的版本跟踪器。
有时我需要重复计算,我想知道我使用的是哪个版本的程序。
将 # 的提交放入主可执行文件的好方法是什么?换一种说法。我希望程序在我运行程序时在介绍性消息中告诉我当前提交的 #。
我能想到的一种方法是从 shell 中使 c++ 程序午餐“git log”并提取提交 # 但我不确定在制作期间如何做。
(我用的是linux)
【问题讨论】:
我使用 git 作为我的 c++ 项目的版本跟踪器。
有时我需要重复计算,我想知道我使用的是哪个版本的程序。
将 # 的提交放入主可执行文件的好方法是什么?换一种说法。我希望程序在我运行程序时在介绍性消息中告诉我当前提交的 #。
我能想到的一种方法是从 shell 中使 c++ 程序午餐“git log”并提取提交 # 但我不确定在制作期间如何做。
(我用的是linux)
【问题讨论】:
可能最简单的方法是在您的 makefile 中添加一条规则,以生成具有当前 git 提交 ID 的 .c 文件:
gitversion.c: .git/HEAD .git/index
echo "const char *gitversion = \"$(shell git rev-parse HEAD)\";" > $@
现在只需像往常一样将gitversion.c 添加到您的构建过程中。确保在 make clean 上将其删除,并将其添加到 .gitignore,这样它就不会意外添加到 git 存储库中。将extern const char *gitversion; 添加到某处的标题中,您就可以这样访问它。
【讨论】:
gitversion.c:后面列出的文件是它所依赖的文件。 .git 是隐藏目录; HEAD 是其中的一个文件。因此,当.git/HEAD或.git/index发生变化时,使用下一行的命令重建gitversion.c:。
我在 CMakeLists.txt 中执行以下操作:
IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
FIND_PACKAGE(Git)
IF(GIT_FOUND)
EXECUTE_PROCESS(
COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE "kml2maps_BUILD_VERSION"
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
MESSAGE( STATUS "Git version: ${kml2maps_BUILD_VERSION}" )
ELSE(GIT_FOUND)
SET(kml2maps_BUILD_VERSION 0)
ENDIF(GIT_FOUND)
ENDIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/kml2mapsVersion.h.in ${CMAKE_CURRENT_BINARY_DIR}/kml2mapsVersion.h @ONLY)
所以git rev-parse --short HEAD 的输出可以很好地构建在二进制文件中。
【讨论】:
#define GIT_REVISION "@kml2maps_BUILD_VERSION@" in kml2mapsVersion.h.in。
我使用git describe 来获取使用标签或提交号的版本。这通常会给出很好的版本,例如:v0.1-1-g787c667 如果分支的尖端在 'v0.1' 标记之上有额外的提交。
我使用的 git 命令是:git describe --tags --always。我通常将它与 SCons 构建系统一起使用,并将其定义为 SConstruct 的常量相关部分:
import os, sys
from subprocess import *
def getGitDesc():
return Popen('git describe --tags --always', stdout=PIPE, shell=True).stdout.read ().strip ()
GIT_DESC = getGitDesc ()
print "Building " + getGitDesc () + ".."
env = Environment ()
# set up environment
env.Append (CPPDEFINES = { 'GIT_DESC' : ('\\"%s\\"' % GIT_DESC) } )
# build your program
env.Program (....)
在 C 或 C++ 程序中,我现在可以将 GIT_DESC 作为字符串常量访问:
# include <iostream>
using namespace std;
int main (int argc, char ** argv) {
cout << "Version: " << GIT_DESC << endl;
return 42;
}
注意:git describe 的 --abbrev=N 参数可能有助于实现独立于用户 git 配置的一致版本输出。
【讨论】:
如果您使用的是 Qt,请将其放入项目的 .pro 文件中:
win32:DEFINES += GIT_BIN='C:\\Git\\bin\\git'
# or 'C:\\Progra~1\\Git\\bin\\git' - ymmv with putting spaces in here
win32:DEFINES += GIT_REVISION='\\"$$system($${GIT_BIN} rev-parse --short HEAD)\\"'
unix:DEFINES += GIT_REVISION='\\"$$system(git rev-parse --short HEAD)\\"'
然后在您的代码中使用 GIT_REVISION,就像在其他答案中一样 - 它的行为类似于 const char *。
(感谢 Alexander Barthel,我从他那里得到了这个提示。)
【讨论】:
-D 标志添加到编译器标志列表中会更容易:QMAKE_CXXFLAGS += -DGIT_COMMIT=\"$(shell git describe --abbrev=4 --dirty --always --tags)\"