function(git_version version revision version_release)
    set(${version}         "" CACHE STRING "Latest Git Tag Version"  FORCE)
    set(${revision}        "" CACHE STRING "Latest Git Tag Revision" FORCE)
    set(${version_release} 0  CACHE STRING "Is this a versioned release without revision" FORCE)

    find_package(Git)
    if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
        # get latest version from tag history
        execute_process(COMMAND "${GIT_EXECUTABLE}" tag "--format=%(align:width=20)%(refname:short)%(end)%(if)%(*objectname)%(then)%(*objectname)%(else)%(objectname)%(end)" --sort=-v:refname OUTPUT_VARIABLE tags OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")

        # if no tags (e.g. shallow clone) do nothing
        if(tags STREQUAL "")
            return()
        endif()

        # convert to list of the form [tag0, ref0, tag1, ref1, ...]
        string(REGEX REPLACE "[ \n]+" ";" tags "${tags}")

        execute_process(COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD OUTPUT_VARIABLE current_ref OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")

        # if cannot get current ref, do nothing
        if(current_ref STREQUAL "")
            return()
        endif()

        list(LENGTH tags cnt)
        set(i 0)
        set(j 1)

        while(i LESS cnt AND "${${version}}" STREQUAL "")
            list(GET tags ${i} tag)
            list(GET tags ${j} ref)

            # tag is a version number with or without a "-revision"
            if(tag MATCHES "^v?(([0-9]+\\.?)*[0-9]*)(-(.*))?$")
                set(${version} "${CMAKE_MATCH_1}" CACHE STRING "Latest Git Tag Version" FORCE)

                if(i EQUAL 0)
                    if(NOT "${CMAKE_MATCH_4}" STREQUAL "")
                        set(${revision} "${CMAKE_MATCH_4}" CACHE STRING "Latest Git Tag Revision" FORCE)
                    elseif(ref STREQUAL current_ref)
                        set(${version_release} 1 CACHE STRING "Is this a versioned release without revision" FORCE)
                    endif()
                endif()
            elseif(i EQUAL 0 AND ref STREQUAL current_ref)
                # revision name tagged
                set(${revision} "${tag}" CACHE STRING "Latest Git Tag Revision" FORCE)
            endif()

            math(EXPR i "${i} + 2")
            math(EXPR j "${j} + 2")
        endwhile()

        if(NOT "${${version_release}}" AND "${${revision}}" STREQUAL "")
            # dev version, use short sha for ref
            execute_process(COMMAND "${GIT_EXECUTABLE}" rev-parse --short HEAD OUTPUT_VARIABLE short_sha OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
            set(${revision} "${short_sha}" CACHE STRING "Latest Git Tag Revision" FORCE)
        endif()
    endif()
endfunction()
