ExternalProject: gitupdate erroneously fallback on CHECKOUT strategy
Starting with CMake 3.20, as introduced by ac6a4d48, the update step in a git-based external project will check whether the local branch matches the reference branch given to the ExternalProject_Add command (the check is here).
However, the upstream branch is obtained via this execute_process:
execute_process(
COMMAND "@git_EXECUTABLE@" for-each-ref "--format='%(upstream:short)'" "${current_branch}"
WORKING_DIRECTORY "@work_dir@"
OUTPUT_VARIABLE upstream_branch
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL ANY # There is no error if no upstream is set
)
Strangely (I cannot get git for-each-ref
to output this in a shell...) upstream_branch
will have surrounding quotes (e.g. 'origin/main'
instead of origin/main
). Then it will not compare equal to the expected name and it will fallback to the CHECKOUT strategy which will discard any local changes.
This can be fixed in two ways:
- change the command to
"@git_EXECUTABLE@" for-each-ref "--format=%(upstream:short)" "${current_branch}"
(drop the'
around the format) - change the check to
if(NOT upstream_branch STREQUAL checkout_name AND NOT upstream_branch STREQUAL "'${checkout_name}'")
Finally, regardless of the issue, I think the fallback is surprising as the documentation does not say it might happen. The REBASE
strategy documentation says that it will fail the build if the rebase fails but it does not say the rebase will not be attempted in the first place if the branches name do not match. If the behavior is kept it would be nice to have a way to opt out.