How can the status of a git repository be determined at compile time?

I’m working on a simulation system written in C++ that is managed by git. I use GNU make as build tool. To make simulation results reproducible git is very useful as you can go back to the exact version of the simulation program the results have been created with.

Currently the status and SHA1 of the git repository are determined programmaticaly at run time and written to a file together with the results. However, if the sources have been changed since compilation of the program, the status in my log file will not reflect the actual version of the program. Thus I’m looking for a way to determine the git status at compile time. Is there any chance to accomplish this?

  • Visual Studio: Git Team Explorer does not show any changes
  • How can I do a git clone operation using Cake
  • x86 assembly instruction execution count
  • What files of my project should I put in repo
  • Get files modified/added/removed from a commit in LibGit2Sharp
  • Versioning with Visual Studio 2010 and HG
  • How to remove unused objects from a git repository?
  • How to remove selected commit log entries from a Git repository while keeping their changes?
  • Only build feature/* branches
  • How do I find the next commit in git?
  • how to know the depth of a git's shallow clone?
  • msysGit un-install runtime error 18:1292 could not call proc
  • 2 Solutions collect form web for “How can the status of a git repository be determined at compile time?”

    One solution is to have your build system extract the value and have it generate some C++ header (or source file) with this value inside it.

    For example, if using CMake, you can use the FindGit module to do something like:

    project(...)
    
    # load module.
    find_package(Git)
    
    # create "${GIT_HEAD_HASH}" variable that contains
    # the SHA-1 of the current tree.  This assumes that the
    # root CMakeLists is in the root of the Git repository.
    git_tree_info(${CMAKE_SOURCE_DIR} GIT_HEAD)
    
    # generate a 'version.h' file based on the 'version.h.in'
    # file.  replace all @...@ strings with variables in the
    # current scope.
    configure_file(
        ${CMAKE_CURRENT_SOURCE_DIR}/version.h.in
        ${CMAKE_CURRENT_SOURCE_DIR}/version.h
        @ONLY
    )
    

    Then, add the following version.h.in file:

    #ifndef _version_h__
    #define _version_h__
    
    static const char VERSION[] = "@GIT_HEAD_HASH@";
    
    #endif
    

    CMake will replace the @GIT_HEAD_HASH@ string with the value it extracted using get_tree_info().

    Then, from your regular code:

    #include "version.h"
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    
    int main(int argc, char ** argv)
    {
        if ((argc == 2) && (std::strcmp(argv[1],"--version") == 0))
        {
            std::cerr
                << VERSION
                << std::endl;
            return (EXIT_FAILURE);
        }
    
        // ...
    }
    

    This is a simplified and absolutely untested example. If you take a look at the sources of the FindGit CMake module, you’ll see that it just runs an execute_process() command at build time to extract the information. You can modify it to extract anything based on invocation of the Git command-line interface.

    Since you are already using Makefile, you can check the status there.

    If you want to keep track of what commit was the HEAD at that time, you can use git rev-parse HEAD to get the sha1 of the commit. You may store it in a file if you need it at runtime.

    Git Baby is a git and github fan, let's start git clone.