how to include git commit-number into a c++ executable?

i use git as a version tracker for my c++ project.

sometimes i need to repeat a calculation and i would like to know which version of the program i used.

what would be a good way to put a # of the commit into the main executable? in other words. i'd like the program to tell me the # of the current commit in an introductory message as i run the program.

one way i can think of is to make the c++ program lunch "git log" from shell and extract the commit # but i'm not sure how to do it during make.

(I use linux)


Probably the easiest way to do this would be to add to your makefile a rule to generate a .c file with the current git commit ID:

gitversion.c: .git/HEAD .git/index
    echo "const char *gitversion = \"$(shell git rev-parse HEAD)\";" > $@

Now simply add gitversion.c to your build process as normal. Make sure to remove it on make clean, and add it to .gitignore so it's not added to the git repository accidentally. Add an extern const char *gitversion; to a header somewhere, and you can access it like that.


I do the following in 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)

So the git rev-parse --short HEAD's output is good to build in the binary.


I use git describe to get a version which either uses a tag or commit number. This usually gives nice versions like: v0.1-1-g787c667 if the tip of the branch has additional commits above the 'v0.1' tag.

The git command I use is: git describe --tags --always. I usually use it with the SCons build system and define it as a constant, relevant parts of the 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 (....)

In the C or C++ program I can now access GIT_DESC as a string-constant:

# include <iostream>

using namespace std;

int main (int argc, char ** argv) {
  cout << "Version: " << GIT_DESC << endl;
  return 42;
}

note: the --abbrev=N argument to git describe might be useful to achieve consistent version output independent of a users git configuration.


If you're using Qt, put this in your project's .pro file:

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)\\"'

Then use GIT_REVISION in your code as in the other answers - it behaves as const char *.

(Thanks to Alexander Barthel, who I plundered this tip from.)