Skip to content

Commit

Permalink
Merge pull request #244 from aminya/git-checkout [skip ci]
Browse files Browse the repository at this point in the history
fix: skip or protect all mutable git or vcpkg operations to allow parallel builds
  • Loading branch information
aminya committed Jan 17, 2024
2 parents 374335f + dda0abf commit ad27a66
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 14 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ include(${_project_options_SOURCE_DIR}/Index.cmake)
run_vcpkg(
VCPKG_URL "https://github.com/microsoft/vcpkg.git"
VCPKG_REV "0fa8459cf3a7caca7adc58f992bc32ff13630684"
ENABLE_VCPKG_UPDATE
)
# Set the project name and language
Expand Down
60 changes: 49 additions & 11 deletions src/Git.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,18 @@ endfunction()

Pull the given repository

It will temporarily switch back to the previous branch if the head is detached for updating
If ``TARGET_REVISION`` is given, the pull is skipped if the current revision is the same as the target revision.

It will temporarily switch back to the previous branch if the head is detached for updating.

Input variables:

- ``REPOSITORY_PATH``: The path to the repository
- ``TARGET_REVISION``: if the current revision of the repository is the same as this given revision, the pull is skipped

]]
function(git_pull)
set(oneValueArgs REPOSITORY_PATH)
set(oneValueArgs REPOSITORY_PATH TARGET_REVISION)
cmake_parse_arguments(_fun "" "${oneValueArgs}" "" ${ARGN})

if("${_fun_REPOSITORY_PATH}" STREQUAL "")
Expand All @@ -144,14 +147,30 @@ function(git_pull)
# store the current revision
git_revision(REVISION REPOSITORY_PATH "${_fun_REPOSITORY_PATH}")

# skip the pull if the revision is the same
if(NOT "${_fun_TARGET_REVISION}" STREQUAL "" AND "${REVISION}" STREQUAL "${_fun_TARGET_REVISION}")
message(STATUS "Skipping pull of ${_fun_REPOSITORY_PATH} because it's already at ${REVISION}")
return()
else()
# pull and restore it after the pull
set(_fun_TARGET_REVISION "${REVISION}")
endif()

git_switch_back(REPOSITORY_PATH "${_fun_REPOSITORY_PATH}")

message(STATUS "Updating ${_fun_REPOSITORY_PATH}")
find_program(GIT_EXECUTABLE "git" REQUIRED)
execute_process(COMMAND "${GIT_EXECUTABLE}" "pull" WORKING_DIRECTORY "${_fun_REPOSITORY_PATH}")

# wait for lock before pulling
git_wait(REPOSITORY_PATH "${_fun_REPOSITORY_PATH}")

execute_process(
COMMAND "${GIT_EXECUTABLE}" "pull" WORKING_DIRECTORY "${_fun_REPOSITORY_PATH}"
COMMAND_ERROR_IS_FATAL LAST
)

# restore the revision
git_checkout(REPOSITORY_PATH "${_fun_REPOSITORY_PATH}" REVISION "${REVISION}")
git_checkout(REPOSITORY_PATH "${_fun_REPOSITORY_PATH}" REVISION "${_fun_TARGET_REVISION}")
endfunction()

#[[.rst:
Expand Down Expand Up @@ -192,6 +211,14 @@ function(git_checkout)
message(FATAL_ERROR "REPOSITORY_PATH and REVISION are required")
endif()

git_revision(REVISION REPOSITORY_PATH "${_fun_REPOSITORY_PATH}")
if("${REVISION}" STREQUAL "${_fun_REVISION}")
return()
endif()

# wait for lock before checking out
git_wait(REPOSITORY_PATH "${_fun_REPOSITORY_PATH}")

find_program(GIT_EXECUTABLE "git" REQUIRED)
execute_process(
COMMAND "${GIT_EXECUTABLE}" "-c" "advice.detachedHead=false" "checkout" "${_fun_REVISION}"
Expand Down Expand Up @@ -356,7 +383,7 @@ function(git_revision REVISION)
COMMAND "${GIT_EXECUTABLE}" "rev-parse" "HEAD"
OUTPUT_VARIABLE _git_revision
WORKING_DIRECTORY "${_fun_REPOSITORY_PATH}"
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL LAST
)
set(${REVISION} ${_git_revision} PARENT_SCOPE)
endfunction()
Expand Down Expand Up @@ -391,7 +418,7 @@ function(git_is_detached IS_DETACHED)
COMMAND "${GIT_EXECUTABLE}" "rev-parse" "--abbrev-ref" "--symbolic-full-name" "HEAD"
OUTPUT_VARIABLE _git_status
WORKING_DIRECTORY "${_fun_REPOSITORY_PATH}"
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL LAST
)
if("${_git_status}" STREQUAL "HEAD")
set(${IS_DETACHED} TRUE PARENT_SCOPE)
Expand Down Expand Up @@ -424,9 +451,23 @@ function(git_switch_back)

if(${IS_DETACHED})
message(STATUS "Switch back ${_fun_REPOSITORY_PATH}")

# wait for lock before switching back
git_wait(REPOSITORY_PATH "${_fun_REPOSITORY_PATH}")

execute_process(
COMMAND "${GIT_EXECUTABLE}" "switch" "-" WORKING_DIRECTORY "${_fun_REPOSITORY_PATH}"
RESULT_VARIABLE _switch_back_result
)

# if the switch back failed, try to checkout the previous branch
if(NOT ${_switch_back_result} EQUAL 0)
message(STATUS "Switch back failed. Trying to checkout previous branch")
execute_process(
COMMAND "${GIT_EXECUTABLE}" "checkout" "-" WORKING_DIRECTORY "${_fun_REPOSITORY_PATH}"
COMMAND_ERROR_IS_FATAL LAST
)
endif()
endif()
endfunction()

Expand Down Expand Up @@ -457,20 +498,17 @@ function(git_wait)

set(counter 0)

message(STATUS "Waiting for git lock file...[${counter}/${_fun_TIMEOUT_COUNTER}]")

# wait until .git/index is present (in case a parallel clone is running)
while(NOT EXISTS "${_fun_REPOSITORY_PATH}/.git/index"
OR EXISTS "${_fun_REPOSITORY_PATH}/.git/index.lock"
)
execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 0.5)
message(STATUS "Waiting for git lock file...[${counter}/${_fun_TIMEOUT_COUNTER}]")
execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 0.5 COMMAND_ERROR_IS_FATAL LAST)

math(EXPR counter "${counter} + 1")
if(${counter} GREATER ${_fun_TIMEOUT_COUNTER})
message(STATUS "Timeout waiting for git lock file. Continuing...")
return()
else()
message(STATUS "Waiting for git lock file...[${counter}/${_fun_TIMEOUT_COUNTER}]")
endif()
endwhile()
endfunction()
3 changes: 1 addition & 2 deletions src/Vcpkg.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ endmacro()

macro(_update_vcpkg_repository)
if(${_vcpkg_args_ENABLE_VCPKG_UPDATE})
git_pull(REPOSITORY_PATH "${_vcpkg_args_VCPKG_DIR}")
git_pull(REPOSITORY_PATH "${_vcpkg_args_VCPKG_DIR}" TARGET_REVISION "${_vcpkg_args_VCPKG_REV}")
endif()
endmacro()

Expand Down Expand Up @@ -94,7 +94,6 @@ endmacro()

macro(_checkout_vcpkg_repository)
if(NOT "${_vcpkg_args_VCPKG_REV}" STREQUAL "")

git_checkout(REPOSITORY_PATH "${_vcpkg_args_VCPKG_DIR}" REVISION "${_vcpkg_args_VCPKG_REV}")
endif()
endmacro()
Expand Down

0 comments on commit ad27a66

Please sign in to comment.