zoukankan      html  css  js  c++  java
  • 给程序添加git commit信息

       遇到了一个客户程序出问题,自己这边始终无法重现的bug。为了检查问题,查到了一个添加git的commit信息到程序中的方法,感觉对程序版本控制十分好用。

     一,项目中添加如下文件

    文件结构:

    GitVersion
    
      |--GetGitRevisionDescription.cmake
    
      |--GetGitRevisionDescription.cmake.in
    
      |--gitrevision.cpp.in
    
      |--gitrevision.hpp

    各文件内容如下:

    GetGitRevisionDescription.cmake:

    # - Returns a version string from Git
    #
    # These functions force a re-configure on each git commit so that you can
    # trust the values of the variables in your build system.
    #
    #  get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
    #
    # Returns the refspec and sha hash of the current head revision
    #
    #  git_describe(<var> [<additional arguments to git describe> ...])
    #
    # Returns the results of git describe on the source tree, and adjusting
    # the output so that it tests false if an error occurs.
    #
    #  git_get_exact_tag(<var> [<additional arguments to git describe> ...])
    #
    # Returns the results of git describe --exact-match on the source tree,
    # and adjusting the output so that it tests false if there was no exact
    # matching tag.
    #
    # Requires CMake 2.6 or newer (uses the 'function' command)
    #
    # Original Author:
    # 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
    # http://academic.cleardefinition.com
    # Iowa State University HCI Graduate Program/VRAC
    #
    # Copyright Iowa State University 2009-2010.
    # Distributed under the Boost Software License, Version 1.0.
    # (See accompanying file LICENSE_1_0.txt or copy at
    # http://www.boost.org/LICENSE_1_0.txt)
    
    if(__get_git_revision_description)
        return()
    endif()
    set(__get_git_revision_description YES)
    
    # We must run the following at "include" time, not at function call time,
    # to find the path to this module rather than the path to a calling list file
    get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
    
    function(get_git_head_revision _refspecvar _hashvar)
        set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
        set(GIT_DIR "${GIT_PARENT_DIR}/.git")
        while(NOT EXISTS "${GIT_DIR}")    # .git dir not found, search parent directories
            set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
            get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
            if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
                # We have reached the root directory, we are not in git
                set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
                set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
                return()
            endif()
            set(GIT_DIR "${GIT_PARENT_DIR}/.git")
        endwhile()
        # check if this is a submodule
        if(NOT IS_DIRECTORY ${GIT_DIR})
            file(READ ${GIT_DIR} submodule)
            string(REGEX REPLACE "gitdir: (.*)
    $" "\1" GIT_DIR_RELATIVE ${submodule})
            get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
            get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
        endif()
        set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
        if(NOT EXISTS "${GIT_DATA}")
            file(MAKE_DIRECTORY "${GIT_DATA}")
        endif()
    
        if(NOT EXISTS "${GIT_DIR}/HEAD")
            return()
        endif()
        set(HEAD_FILE "${GIT_DATA}/HEAD")
        configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
    
        configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
            "${GIT_DATA}/grabRef.cmake"
            @ONLY)
        include("${GIT_DATA}/grabRef.cmake")
    
        set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
        set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
    endfunction()
    
    function(git_describe _var)
        if(NOT GIT_FOUND)
            find_package(Git QUIET)
        endif()
        get_git_head_revision(refspec hash)
        if(NOT GIT_FOUND)
            set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
            return()
        endif()
        if(NOT hash)
            set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
            return()
        endif()
    
        # TODO sanitize
        #if((${ARGN}" MATCHES "&&") OR
        #    (ARGN MATCHES "||") OR
        #    (ARGN MATCHES "\;"))
        #    message("Please report the following error to the project!")
        #    message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
        #endif()
    
        #message(STATUS "Arguments to execute_process: ${ARGN}")
    
        execute_process(COMMAND
            "${GIT_EXECUTABLE}"
            describe
            ${hash}
            ${ARGN}
            WORKING_DIRECTORY
            "${CMAKE_SOURCE_DIR}"
            RESULT_VARIABLE
            res
            OUTPUT_VARIABLE
            out
            ERROR_QUIET
            OUTPUT_STRIP_TRAILING_WHITESPACE)
        if(NOT res EQUAL 0)
            set(out "${out}-${res}-NOTFOUND")
        endif()
    
        set(${_var} "${out}" PARENT_SCOPE)
    endfunction()
    
    function(get_git_unix_timestamp _var)
        if(NOT GIT_FOUND)
            find_package(Git QUIET)
        endif()
        get_git_head_revision(refspec hash)
        if(NOT GIT_FOUND)
            set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
            return()
        endif()
        if(NOT hash)
            set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
            return()
        endif()
    
        # TODO sanitize
        #if((${ARGN}" MATCHES "&&") OR
        #    (ARGN MATCHES "||") OR
        #    (ARGN MATCHES "\;"))
        #    message("Please report the following error to the project!")
        #    message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
        #endif()
    
        # message(STATUS "Arguments to execute_process: ${ARGN}")
    
        execute_process(COMMAND
            "${GIT_EXECUTABLE}"
            "show"
                    "-s"
                    "--format=%ct"
            ${hash}
            ${ARGN}
            WORKING_DIRECTORY
            "${CMAKE_CURRENT_SOURCE_DIR}"
            RESULT_VARIABLE
            res
            OUTPUT_VARIABLE
            out
            ERROR_QUIET
            OUTPUT_STRIP_TRAILING_WHITESPACE)
        if(NOT res EQUAL 0)
            set(out "${out}-${res}-NOTFOUND")
        endif()
    
        set(${_var} "${out}" PARENT_SCOPE)
    endfunction()
    
    function(git_get_exact_tag _var)
        git_describe(out --exact-match ${ARGN})
        set(${_var} "${out}" PARENT_SCOPE)
    endfunction()

    GetGitRevisionDescription.cmake.in:

    # 
    # Internal file for GetGitRevisionDescription.cmake
    #
    # Requires CMake 2.6 or newer (uses the 'function' command)
    #
    # Original Author:
    # 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
    # http://academic.cleardefinition.com
    # Iowa State University HCI Graduate Program/VRAC
    #
    # Copyright Iowa State University 2009-2010.
    # Distributed under the Boost Software License, Version 1.0.
    # (See accompanying file LICENSE_1_0.txt or copy at
    # http://www.boost.org/LICENSE_1_0.txt)
    
    set(HEAD_HASH)
    
    file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
    
    string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
    if(HEAD_CONTENTS MATCHES "ref")
        # named branch
        string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
        if(EXISTS "@GIT_DIR@/${HEAD_REF}")
            configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
        elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}")
            configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
            set(HEAD_HASH "${HEAD_REF}")
        endif()
    else()
        # detached HEAD
        configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
    endif()
    
    if(NOT HEAD_HASH)
        file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
        string(STRIP "${HEAD_HASH}" HEAD_HASH)
    endif()

    gitrevision.cpp.in

    #include "gitrevision.hpp"
    
    #define GIT_REVISION_SHA "@GIT_REVISION_SHA@"
    #define GIT_REVISION_UNIX_TIMESTAMP @GIT_REVISION_UNIX_TIMESTAMP@
    
    namespace git { 
    
    const char* const git_revision_sha = GIT_REVISION_SHA;
    const uint32_t git_revision_unix_timestamp = GIT_REVISION_UNIX_TIMESTAMP;
    
    } // end namespace git

    gitrevision.hpp

    #pragma once
    #include <stdint.h>
    
    namespace git{
    extern const char* const git_revision_sha;
    extern const uint32_t git_revision_unix_timestamp;
    } // end namespace git

    二,项目的cmakelist文件添加如下内容

      list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/GitVersion")
      include( GetGitRevisionDescription )
      get_git_head_revision(GIT_REFSPEC GIT_REVISION_SHA)
      get_git_unix_timestamp(GIT_REVISION_UNIX_TIMESTAMP)
      configure_file("${CMAKE_CURRENT_SOURCE_DIR}/GitVersion/gitrevision.cpp.in" "${CMAKE_CURRENT_SOURCE_DIR}/GitVersion/gitrevision.cpp" @ONLY)

    待项目cmake完成之后,会在GitVersion目录下生成带有当前git commit的hash, time的 gitrevision.cpp 文件。

    即文件中的 git_revision_sha 以及 git_revision_unix_timestamp 

    三,将gitrevision.cpp和gitrevision.hpp文件添加到项目程序环境中

    一般将程序的git commit信息写在日志文件中,或者在程序启动,异常结束的地方

  • 相关阅读:
    封装、继承、多态的意义等。
    php中类与对象的区别和关系是什么?
    MySQL数据库中InnoDB和MyISAM两种数据引擎的差别
    什么是索引? 索引的定义与用法等。
    什么是正则表达式?
    字符串—strcpy
    排序
    虚函数
    优先队列(堆)
    因子个数_错排公式
  • 原文地址:https://www.cnblogs.com/tyche116/p/11898474.html
Copyright © 2011-2022 走看看