From e4137cc6cab189943a55e2cdc0576ad95623297c Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Mon, 4 Nov 2019 20:19:13 +0800 Subject: [PATCH] cmake: support git worktree Use rev-parse to get the HEAD directory instead of manually looking for it. This method works in the main repository, worktrees and submodules. Closes https://github.com/espressif/esp-idf/issues/4136 --- tools/ci/test_build_system_cmake.sh | 8 + .../GetGitRevisionDescription.cmake | 159 +++++++++--------- 2 files changed, 88 insertions(+), 79 deletions(-) diff --git a/tools/ci/test_build_system_cmake.sh b/tools/ci/test_build_system_cmake.sh index 4d391fe17..42f6ebf7a 100755 --- a/tools/ci/test_build_system_cmake.sh +++ b/tools/ci/test_build_system_cmake.sh @@ -554,6 +554,14 @@ endmenu\n" >> ${IDF_PATH}/Kconfig; mv CMakeLists.txt.bak CMakeLists.txt rm -rf CMakeLists.txt.bak + print_status "Supports git worktree" + clean_build_dir + git branch test_build_system + git worktree add ../esp-idf-template-test test_build_system + diff <(idf.py reconfigure | grep "Project version") <(cd ../esp-idf-template-test && idf.py reconfigure | grep "Project version") \ + || failure "Version on worktree should have been properly resolved" + git worktree remove ../esp-idf-template-test + print_status "All tests completed" if [ -n "${FAILURES}" ]; then echo "Some failures were detected:" diff --git a/tools/cmake/third_party/GetGitRevisionDescription.cmake b/tools/cmake/third_party/GetGitRevisionDescription.cmake index 1de63b362..ab048d643 100644 --- a/tools/cmake/third_party/GetGitRevisionDescription.cmake +++ b/tools/cmake/third_party/GetGitRevisionDescription.cmake @@ -34,7 +34,7 @@ # to get revision of other repositories if(__get_git_revision_description) - return() + return() endif() set(__get_git_revision_description YES) @@ -43,95 +43,96 @@ set(__get_git_revision_description YES) get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) function(get_git_head_revision _refspecvar _hashvar _repo_dir) - set(GIT_PARENT_DIR "${_repo_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: (.*)\n$" "\\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() + execute_process(COMMAND + "${GIT_EXECUTABLE}" + rev-parse + --git-dir + WORKING_DIRECTORY + ${_repo_dir} + RESULT_VARIABLE + res + OUTPUT_VARIABLE + GIT_DIR + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(NOT res EQUAL 0) + return() + endif() - if(NOT EXISTS "${GIT_DIR}/HEAD") - return() - endif() - set(HEAD_FILE "${GIT_DATA}/HEAD") - configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) + get_filename_component(GIT_DIR "${GIT_DIR}" ABSOLUTE BASE_DIR "${_repo_dir}") - configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" - "${GIT_DATA}/grabRef.cmake" - @ONLY) - include("${GIT_DATA}/grabRef.cmake") + set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") + if(NOT EXISTS "${GIT_DATA}") + file(MAKE_DIRECTORY "${GIT_DATA}") + endif() - set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) - set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) + 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 _repo_dir) - if(NOT GIT_FOUND) - find_package(Git QUIET) - endif() - get_git_head_revision(refspec hash "${_repo_dir}") - if(NOT GIT_FOUND) - set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) - return() - endif() - if(NOT hash) - set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) - return() - endif() + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash "${_repo_dir}") + 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() + # 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}") + #message(STATUS "Arguments to execute_process: ${ARGN}") - execute_process(COMMAND - "${GIT_EXECUTABLE}" - "-C" - ${_repo_dir} - describe - "--always" - "--tags" - "--dirty" - ${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() + execute_process(COMMAND + "${GIT_EXECUTABLE}" + "-C" + ${_repo_dir} + describe + "--always" + "--tags" + "--dirty" + ${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) + set(${_var} "${out}" PARENT_SCOPE) endfunction() function(git_get_exact_tag _var _repo_dir) - git_describe(out "${_repo_dir}" --exact-match ${ARGN}) - set(${_var} "${out}" PARENT_SCOPE) + git_describe(out "${_repo_dir}" --exact-match ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) endfunction()