| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- # file Copyright.txt or https://cmake.org/licensing for details.
- cmake_minimum_required(VERSION 3.5)
- execute_process(
- COMMAND "@git_EXECUTABLE@" rev-list --max-count=1 HEAD
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- OUTPUT_VARIABLE head_sha
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
- if(error_code)
- message(FATAL_ERROR "Failed to get the hash for HEAD")
- endif()
- execute_process(
- COMMAND "@git_EXECUTABLE@" show-ref "@git_tag@"
- WORKING_DIRECTORY "@work_dir@"
- OUTPUT_VARIABLE show_ref_output
- )
- # If a remote ref is asked for, which can possibly move around,
- # we must always do a fetch and checkout.
- if("${show_ref_output}" MATCHES "remotes")
- set(is_remote_ref 1)
- else()
- set(is_remote_ref 0)
- endif()
- # Tag is in the form <remote>/<tag> (i.e. origin/master) we must strip
- # the remote from the tag.
- if("${show_ref_output}" MATCHES "refs/remotes/@git_tag@")
- string(REGEX MATCH "^([^/]+)/(.+)$" _unused "@git_tag@")
- set(git_remote "${CMAKE_MATCH_1}")
- set(git_tag "${CMAKE_MATCH_2}")
- else()
- set(git_remote "@git_remote_name@")
- set(git_tag "@git_tag@")
- endif()
- # This will fail if the tag does not exist (it probably has not been fetched
- # yet).
- execute_process(
- COMMAND "@git_EXECUTABLE@" rev-list --max-count=1 "${git_tag}"
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- OUTPUT_VARIABLE tag_sha
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
- # Is the hash checkout out that we want?
- if(error_code OR is_remote_ref OR NOT ("${tag_sha}" STREQUAL "${head_sha}"))
- execute_process(
- COMMAND "@git_EXECUTABLE@" fetch
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- )
- if(error_code)
- message(FATAL_ERROR "Failed to fetch repository '@git_repository@'")
- endif()
- if(is_remote_ref)
- # Check if stash is needed
- execute_process(
- COMMAND "@git_EXECUTABLE@" status --porcelain
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- OUTPUT_VARIABLE repo_status
- )
- if(error_code)
- message(FATAL_ERROR "Failed to get the status")
- endif()
- string(LENGTH "${repo_status}" need_stash)
- # If not in clean state, stash changes in order to be able to perform a
- # rebase or checkout without losing those changes permanently
- if(need_stash)
- execute_process(
- COMMAND "@git_EXECUTABLE@" stash save @git_stash_save_options@
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- )
- if(error_code)
- message(FATAL_ERROR "Failed to stash changes")
- endif()
- endif()
- if("@git_update_strategy@" STREQUAL "CHECKOUT")
- execute_process(
- COMMAND "@git_EXECUTABLE@" checkout "${git_remote}/${git_tag}"
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- )
- if(error_code)
- message(FATAL_ERROR "Failed to checkout tag: '${git_remote}/${git_tag}'")
- endif()
- else()
- # Pull changes from the remote branch
- execute_process(
- COMMAND "@git_EXECUTABLE@" rebase "${git_remote}/${git_tag}"
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- OUTPUT_VARIABLE rebase_output
- ERROR_VARIABLE rebase_output
- )
- if(error_code)
- # Rebase failed, undo the rebase attempt before continuing
- execute_process(
- COMMAND "@git_EXECUTABLE@" rebase --abort
- WORKING_DIRECTORY "@work_dir@"
- )
- if(NOT "@git_update_strategy@" STREQUAL "REBASE_CHECKOUT")
- # Not allowed to do a checkout as a fallback, so cannot proceed
- if(need_stash)
- execute_process(
- COMMAND "@git_EXECUTABLE@" stash pop --index --quiet
- WORKING_DIRECTORY "@work_dir@"
- )
- endif()
- message(FATAL_ERROR "\nFailed to rebase in: '@work_dir@'."
- "\nOutput from the attempted rebase follows:"
- "\n${rebase_output}"
- "\n\nYou will have to resolve the conflicts manually")
- endif()
- # Fall back to checkout. We create an annotated tag so that the user
- # can manually inspect the situation and revert if required.
- # We can't log the failed rebase output because MSVC sees it and
- # intervenes, causing the build to fail even though it completes.
- # Write it to a file instead.
- string(TIMESTAMP tag_timestamp "%Y%m%dT%H%M%S" UTC)
- set(tag_name _cmake_ExternalProject_moved_from_here_${tag_timestamp}Z)
- set(error_log_file ${CMAKE_CURRENT_LIST_DIR}/rebase_error_${tag_timestamp}Z.log)
- file(WRITE ${error_log_file} "${rebase_output}")
- message(WARNING "Rebase failed, output has been saved to ${error_log_file}"
- "\nFalling back to checkout, previous commit tagged as ${tag_name}")
- execute_process(
- COMMAND "@git_EXECUTABLE@" tag -a
- -m "ExternalProject attempting to move from here to ${git_remote}/${git_tag}"
- ${tag_name}
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- )
- if(error_code)
- message(FATAL_ERROR "Failed to add marker tag")
- endif()
- execute_process(
- COMMAND "@git_EXECUTABLE@" checkout "${git_remote}/${git_tag}"
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- )
- if(error_code)
- message(FATAL_ERROR "Failed to checkout : '${git_remote}/${git_tag}'")
- endif()
- endif()
- endif()
- if(need_stash)
- execute_process(
- COMMAND "@git_EXECUTABLE@" stash pop --index --quiet
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- )
- if(error_code)
- # Stash pop --index failed: Try again dropping the index
- execute_process(
- COMMAND "@git_EXECUTABLE@" reset --hard --quiet
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- )
- execute_process(
- COMMAND "@git_EXECUTABLE@" stash pop --quiet
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- )
- if(error_code)
- # Stash pop failed: Restore previous state.
- execute_process(
- COMMAND "@git_EXECUTABLE@" reset --hard --quiet ${head_sha}
- WORKING_DIRECTORY "@work_dir@"
- )
- execute_process(
- COMMAND "@git_EXECUTABLE@" stash pop --index --quiet
- WORKING_DIRECTORY "@work_dir@"
- )
- message(FATAL_ERROR "\nFailed to unstash changes in: '@work_dir@'."
- "\nYou will have to resolve the conflicts manually")
- endif()
- endif()
- endif()
- else()
- execute_process(
- COMMAND "@git_EXECUTABLE@" checkout "${git_tag}"
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- )
- if(error_code)
- message(FATAL_ERROR "Failed to checkout tag: '${git_tag}'")
- endif()
- endif()
- set(init_submodules "@init_submodules@")
- if(init_submodules)
- execute_process(
- COMMAND "@git_EXECUTABLE@" submodule update @git_submodules_recurse@ --init @git_submodules@
- WORKING_DIRECTORY "@work_dir@"
- RESULT_VARIABLE error_code
- )
- endif()
- if(error_code)
- message(FATAL_ERROR "Failed to update submodules in: '@work_dir@'")
- endif()
- endif()
|