Skip to content

Commit ad27a66

Browse files
authored
Merge pull request #244 from aminya/git-checkout [skip ci]
fix: skip or protect all mutable git or vcpkg operations to allow parallel builds
2 parents 374335f + dda0abf commit ad27a66

3 files changed

Lines changed: 50 additions & 14 deletions

File tree

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ include(${_project_options_SOURCE_DIR}/Index.cmake)
7878
run_vcpkg(
7979
VCPKG_URL "https://github.com/microsoft/vcpkg.git"
8080
VCPKG_REV "0fa8459cf3a7caca7adc58f992bc32ff13630684"
81-
ENABLE_VCPKG_UPDATE
8281
)
8382
8483
# Set the project name and language

src/Git.cmake

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,18 @@ endfunction()
126126
127127
Pull the given repository
128128
129-
It will temporarily switch back to the previous branch if the head is detached for updating
129+
If ``TARGET_REVISION`` is given, the pull is skipped if the current revision is the same as the target revision.
130+
131+
It will temporarily switch back to the previous branch if the head is detached for updating.
130132
131133
Input variables:
132134
133135
- ``REPOSITORY_PATH``: The path to the repository
136+
- ``TARGET_REVISION``: if the current revision of the repository is the same as this given revision, the pull is skipped
134137
135138
]]
136139
function(git_pull)
137-
set(oneValueArgs REPOSITORY_PATH)
140+
set(oneValueArgs REPOSITORY_PATH TARGET_REVISION)
138141
cmake_parse_arguments(_fun "" "${oneValueArgs}" "" ${ARGN})
139142

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

150+
# skip the pull if the revision is the same
151+
if(NOT "${_fun_TARGET_REVISION}" STREQUAL "" AND "${REVISION}" STREQUAL "${_fun_TARGET_REVISION}")
152+
message(STATUS "Skipping pull of ${_fun_REPOSITORY_PATH} because it's already at ${REVISION}")
153+
return()
154+
else()
155+
# pull and restore it after the pull
156+
set(_fun_TARGET_REVISION "${REVISION}")
157+
endif()
158+
147159
git_switch_back(REPOSITORY_PATH "${_fun_REPOSITORY_PATH}")
148160

149161
message(STATUS "Updating ${_fun_REPOSITORY_PATH}")
150162
find_program(GIT_EXECUTABLE "git" REQUIRED)
151-
execute_process(COMMAND "${GIT_EXECUTABLE}" "pull" WORKING_DIRECTORY "${_fun_REPOSITORY_PATH}")
163+
164+
# wait for lock before pulling
165+
git_wait(REPOSITORY_PATH "${_fun_REPOSITORY_PATH}")
166+
167+
execute_process(
168+
COMMAND "${GIT_EXECUTABLE}" "pull" WORKING_DIRECTORY "${_fun_REPOSITORY_PATH}"
169+
COMMAND_ERROR_IS_FATAL LAST
170+
)
152171

153172
# restore the revision
154-
git_checkout(REPOSITORY_PATH "${_fun_REPOSITORY_PATH}" REVISION "${REVISION}")
173+
git_checkout(REPOSITORY_PATH "${_fun_REPOSITORY_PATH}" REVISION "${_fun_TARGET_REVISION}")
155174
endfunction()
156175

157176
#[[.rst:
@@ -192,6 +211,14 @@ function(git_checkout)
192211
message(FATAL_ERROR "REPOSITORY_PATH and REVISION are required")
193212
endif()
194213

214+
git_revision(REVISION REPOSITORY_PATH "${_fun_REPOSITORY_PATH}")
215+
if("${REVISION}" STREQUAL "${_fun_REVISION}")
216+
return()
217+
endif()
218+
219+
# wait for lock before checking out
220+
git_wait(REPOSITORY_PATH "${_fun_REPOSITORY_PATH}")
221+
195222
find_program(GIT_EXECUTABLE "git" REQUIRED)
196223
execute_process(
197224
COMMAND "${GIT_EXECUTABLE}" "-c" "advice.detachedHead=false" "checkout" "${_fun_REVISION}"
@@ -356,7 +383,7 @@ function(git_revision REVISION)
356383
COMMAND "${GIT_EXECUTABLE}" "rev-parse" "HEAD"
357384
OUTPUT_VARIABLE _git_revision
358385
WORKING_DIRECTORY "${_fun_REPOSITORY_PATH}"
359-
OUTPUT_STRIP_TRAILING_WHITESPACE
386+
OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL LAST
360387
)
361388
set(${REVISION} ${_git_revision} PARENT_SCOPE)
362389
endfunction()
@@ -391,7 +418,7 @@ function(git_is_detached IS_DETACHED)
391418
COMMAND "${GIT_EXECUTABLE}" "rev-parse" "--abbrev-ref" "--symbolic-full-name" "HEAD"
392419
OUTPUT_VARIABLE _git_status
393420
WORKING_DIRECTORY "${_fun_REPOSITORY_PATH}"
394-
OUTPUT_STRIP_TRAILING_WHITESPACE
421+
OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL LAST
395422
)
396423
if("${_git_status}" STREQUAL "HEAD")
397424
set(${IS_DETACHED} TRUE PARENT_SCOPE)
@@ -424,9 +451,23 @@ function(git_switch_back)
424451

425452
if(${IS_DETACHED})
426453
message(STATUS "Switch back ${_fun_REPOSITORY_PATH}")
454+
455+
# wait for lock before switching back
456+
git_wait(REPOSITORY_PATH "${_fun_REPOSITORY_PATH}")
457+
427458
execute_process(
428459
COMMAND "${GIT_EXECUTABLE}" "switch" "-" WORKING_DIRECTORY "${_fun_REPOSITORY_PATH}"
460+
RESULT_VARIABLE _switch_back_result
429461
)
462+
463+
# if the switch back failed, try to checkout the previous branch
464+
if(NOT ${_switch_back_result} EQUAL 0)
465+
message(STATUS "Switch back failed. Trying to checkout previous branch")
466+
execute_process(
467+
COMMAND "${GIT_EXECUTABLE}" "checkout" "-" WORKING_DIRECTORY "${_fun_REPOSITORY_PATH}"
468+
COMMAND_ERROR_IS_FATAL LAST
469+
)
470+
endif()
430471
endif()
431472
endfunction()
432473

@@ -457,20 +498,17 @@ function(git_wait)
457498

458499
set(counter 0)
459500

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

468508
math(EXPR counter "${counter} + 1")
469509
if(${counter} GREATER ${_fun_TIMEOUT_COUNTER})
470510
message(STATUS "Timeout waiting for git lock file. Continuing...")
471511
return()
472-
else()
473-
message(STATUS "Waiting for git lock file...[${counter}/${_fun_TIMEOUT_COUNTER}]")
474512
endif()
475513
endwhile()
476514
endfunction()

src/Vcpkg.cmake

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ endmacro()
2929

3030
macro(_update_vcpkg_repository)
3131
if(${_vcpkg_args_ENABLE_VCPKG_UPDATE})
32-
git_pull(REPOSITORY_PATH "${_vcpkg_args_VCPKG_DIR}")
32+
git_pull(REPOSITORY_PATH "${_vcpkg_args_VCPKG_DIR}" TARGET_REVISION "${_vcpkg_args_VCPKG_REV}")
3333
endif()
3434
endmacro()
3535

@@ -94,7 +94,6 @@ endmacro()
9494

9595
macro(_checkout_vcpkg_repository)
9696
if(NOT "${_vcpkg_args_VCPKG_REV}" STREQUAL "")
97-
9897
git_checkout(REPOSITORY_PATH "${_vcpkg_args_VCPKG_DIR}" REVISION "${_vcpkg_args_VCPKG_REV}")
9998
endif()
10099
endmacro()

0 commit comments

Comments
 (0)