libvterm-gitupdate.cmake (12171B)
1 # Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 # file Copyright.txt or https://cmake.org/licensing for details. 3 4 cmake_minimum_required(VERSION 3.5) 5 6 function(do_fetch) 7 message(VERBOSE "Fetching latest from the remote origin") 8 execute_process( 9 COMMAND "/usr/bin/git" --git-dir=.git fetch --tags --force "origin" 10 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 11 COMMAND_ERROR_IS_FATAL LAST 12 ) 13 endfunction() 14 15 function(get_hash_for_ref ref out_var err_var) 16 execute_process( 17 COMMAND "/usr/bin/git" --git-dir=.git rev-parse "${ref}^0" 18 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 19 RESULT_VARIABLE error_code 20 OUTPUT_VARIABLE ref_hash 21 ERROR_VARIABLE error_msg 22 OUTPUT_STRIP_TRAILING_WHITESPACE 23 ) 24 if(error_code) 25 set(${out_var} "" PARENT_SCOPE) 26 else() 27 set(${out_var} "${ref_hash}" PARENT_SCOPE) 28 endif() 29 set(${err_var} "${error_msg}" PARENT_SCOPE) 30 endfunction() 31 32 get_hash_for_ref(HEAD head_sha error_msg) 33 if(head_sha STREQUAL "") 34 message(FATAL_ERROR "Failed to get the hash for HEAD:\n${error_msg}") 35 endif() 36 37 38 execute_process( 39 COMMAND "/usr/bin/git" --git-dir=.git show-ref "64f1775952dbe001e989f2ab679563b54f2fca55" 40 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 41 OUTPUT_VARIABLE show_ref_output 42 ) 43 if(show_ref_output MATCHES "^[a-z0-9]+[ \\t]+refs/remotes/") 44 # Given a full remote/branch-name and we know about it already. Since 45 # branches can move around, we should always fetch, if permitted. 46 if(can_fetch) 47 do_fetch() 48 endif() 49 set(checkout_name "64f1775952dbe001e989f2ab679563b54f2fca55") 50 51 elseif(show_ref_output MATCHES "^[a-z0-9]+[ \\t]+refs/tags/") 52 # Given a tag name that we already know about. We don't know if the tag we 53 # have matches the remote though (tags can move), so we should fetch. As a 54 # special case to preserve backward compatibility, if we are already at the 55 # same commit as the tag we hold locally, don't do a fetch and assume the tag 56 # hasn't moved on the remote. 57 # FIXME: We should provide an option to always fetch for this case 58 get_hash_for_ref("64f1775952dbe001e989f2ab679563b54f2fca55" tag_sha error_msg) 59 if(tag_sha STREQUAL head_sha) 60 message(VERBOSE "Already at requested tag: ${tag_sha}") 61 return() 62 endif() 63 64 if(can_fetch) 65 do_fetch() 66 endif() 67 set(checkout_name "64f1775952dbe001e989f2ab679563b54f2fca55") 68 69 elseif(show_ref_output MATCHES "^[a-z0-9]+[ \\t]+refs/heads/") 70 # Given a branch name without any remote and we already have a branch by that 71 # name. We might already have that branch checked out or it might be a 72 # different branch. It isn't fully safe to use a bare branch name without the 73 # remote, so do a fetch (if allowed) and replace the ref with one that 74 # includes the remote. 75 if(can_fetch) 76 do_fetch() 77 endif() 78 set(checkout_name "origin/64f1775952dbe001e989f2ab679563b54f2fca55") 79 80 else() 81 get_hash_for_ref("64f1775952dbe001e989f2ab679563b54f2fca55" tag_sha error_msg) 82 if(tag_sha STREQUAL head_sha) 83 # Have the right commit checked out already 84 message(VERBOSE "Already at requested ref: ${tag_sha}") 85 return() 86 87 elseif(tag_sha STREQUAL "") 88 # We don't know about this ref yet, so we have no choice but to fetch. 89 if(NOT can_fetch) 90 message(FATAL_ERROR 91 "Requested git ref \"64f1775952dbe001e989f2ab679563b54f2fca55\" is not present locally, and not " 92 "allowed to contact remote due to UPDATE_DISCONNECTED setting." 93 ) 94 endif() 95 96 # We deliberately swallow any error message at the default log level 97 # because it can be confusing for users to see a failed git command. 98 # That failure is being handled here, so it isn't an error. 99 if(NOT error_msg STREQUAL "") 100 message(VERBOSE "${error_msg}") 101 endif() 102 do_fetch() 103 set(checkout_name "64f1775952dbe001e989f2ab679563b54f2fca55") 104 105 else() 106 # We have the commit, so we know we were asked to find a commit hash 107 # (otherwise it would have been handled further above), but we don't 108 # have that commit checked out yet. We don't need to fetch from the remote. 109 set(checkout_name "64f1775952dbe001e989f2ab679563b54f2fca55") 110 if(NOT error_msg STREQUAL "") 111 message(WARNING "${error_msg}") 112 endif() 113 114 endif() 115 endif() 116 117 set(git_update_strategy "REBASE") 118 if(git_update_strategy STREQUAL "") 119 # Backward compatibility requires REBASE as the default behavior 120 set(git_update_strategy REBASE) 121 endif() 122 123 if(git_update_strategy MATCHES "^REBASE(_CHECKOUT)?$") 124 # Asked to potentially try to rebase first, maybe with fallback to checkout. 125 # We can't if we aren't already on a branch and we shouldn't if that local 126 # branch isn't tracking the one we want to checkout. 127 execute_process( 128 COMMAND "/usr/bin/git" --git-dir=.git symbolic-ref -q HEAD 129 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 130 OUTPUT_VARIABLE current_branch 131 OUTPUT_STRIP_TRAILING_WHITESPACE 132 # Don't test for an error. If this isn't a branch, we get a non-zero error 133 # code but empty output. 134 ) 135 136 if(current_branch STREQUAL "") 137 # Not on a branch, checkout is the only sensible option since any rebase 138 # would always fail (and backward compatibility requires us to checkout in 139 # this situation) 140 set(git_update_strategy CHECKOUT) 141 142 else() 143 execute_process( 144 COMMAND "/usr/bin/git" --git-dir=.git for-each-ref "--format=%(upstream:short)" "${current_branch}" 145 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 146 OUTPUT_VARIABLE upstream_branch 147 OUTPUT_STRIP_TRAILING_WHITESPACE 148 COMMAND_ERROR_IS_FATAL ANY # There is no error if no upstream is set 149 ) 150 if(NOT upstream_branch STREQUAL checkout_name) 151 # Not safe to rebase when asked to checkout a different branch to the one 152 # we are tracking. If we did rebase, we could end up with arbitrary 153 # commits added to the ref we were asked to checkout if the current local 154 # branch happens to be able to rebase onto the target branch. There would 155 # be no error message and the user wouldn't know this was occurring. 156 set(git_update_strategy CHECKOUT) 157 endif() 158 159 endif() 160 elseif(NOT git_update_strategy STREQUAL "CHECKOUT") 161 message(FATAL_ERROR "Unsupported git update strategy: ${git_update_strategy}") 162 endif() 163 164 165 # Check if stash is needed 166 execute_process( 167 COMMAND "/usr/bin/git" --git-dir=.git status --porcelain 168 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 169 RESULT_VARIABLE error_code 170 OUTPUT_VARIABLE repo_status 171 ) 172 if(error_code) 173 message(FATAL_ERROR "Failed to get the status") 174 endif() 175 string(LENGTH "${repo_status}" need_stash) 176 177 # If not in clean state, stash changes in order to be able to perform a 178 # rebase or checkout without losing those changes permanently 179 if(need_stash) 180 execute_process( 181 COMMAND "/usr/bin/git" --git-dir=.git stash save --quiet;--include-untracked 182 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 183 COMMAND_ERROR_IS_FATAL ANY 184 ) 185 endif() 186 187 if(git_update_strategy STREQUAL "CHECKOUT") 188 execute_process( 189 COMMAND "/usr/bin/git" --git-dir=.git checkout "${checkout_name}" 190 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 191 COMMAND_ERROR_IS_FATAL ANY 192 ) 193 else() 194 execute_process( 195 COMMAND "/usr/bin/git" --git-dir=.git rebase "${checkout_name}" 196 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 197 RESULT_VARIABLE error_code 198 OUTPUT_VARIABLE rebase_output 199 ERROR_VARIABLE rebase_output 200 ) 201 if(error_code) 202 # Rebase failed, undo the rebase attempt before continuing 203 execute_process( 204 COMMAND "/usr/bin/git" --git-dir=.git rebase --abort 205 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 206 ) 207 208 if(NOT git_update_strategy STREQUAL "REBASE_CHECKOUT") 209 # Not allowed to do a checkout as a fallback, so cannot proceed 210 if(need_stash) 211 execute_process( 212 COMMAND "/usr/bin/git" --git-dir=.git stash pop --index --quiet 213 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 214 ) 215 endif() 216 message(FATAL_ERROR "\nFailed to rebase in: '/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm'." 217 "\nOutput from the attempted rebase follows:" 218 "\n${rebase_output}" 219 "\n\nYou will have to resolve the conflicts manually") 220 endif() 221 222 # Fall back to checkout. We create an annotated tag so that the user 223 # can manually inspect the situation and revert if required. 224 # We can't log the failed rebase output because MSVC sees it and 225 # intervenes, causing the build to fail even though it completes. 226 # Write it to a file instead. 227 string(TIMESTAMP tag_timestamp "%Y%m%dT%H%M%S" UTC) 228 set(tag_name _cmake_ExternalProject_moved_from_here_${tag_timestamp}Z) 229 set(error_log_file ${CMAKE_CURRENT_LIST_DIR}/rebase_error_${tag_timestamp}Z.log) 230 file(WRITE ${error_log_file} "${rebase_output}") 231 message(WARNING "Rebase failed, output has been saved to ${error_log_file}" 232 "\nFalling back to checkout, previous commit tagged as ${tag_name}") 233 execute_process( 234 COMMAND "/usr/bin/git" --git-dir=.git tag -a 235 -m "ExternalProject attempting to move from here to ${checkout_name}" 236 ${tag_name} 237 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 238 COMMAND_ERROR_IS_FATAL ANY 239 ) 240 241 execute_process( 242 COMMAND "/usr/bin/git" --git-dir=.git checkout "${checkout_name}" 243 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 244 COMMAND_ERROR_IS_FATAL ANY 245 ) 246 endif() 247 endif() 248 249 if(need_stash) 250 # Put back the stashed changes 251 execute_process( 252 COMMAND "/usr/bin/git" --git-dir=.git stash pop --index --quiet 253 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 254 RESULT_VARIABLE error_code 255 ) 256 if(error_code) 257 # Stash pop --index failed: Try again dropping the index 258 execute_process( 259 COMMAND "/usr/bin/git" --git-dir=.git reset --hard --quiet 260 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 261 ) 262 execute_process( 263 COMMAND "/usr/bin/git" --git-dir=.git stash pop --quiet 264 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 265 RESULT_VARIABLE error_code 266 ) 267 if(error_code) 268 # Stash pop failed: Restore previous state. 269 execute_process( 270 COMMAND "/usr/bin/git" --git-dir=.git reset --hard --quiet ${head_sha} 271 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 272 ) 273 execute_process( 274 COMMAND "/usr/bin/git" --git-dir=.git stash pop --index --quiet 275 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 276 ) 277 message(FATAL_ERROR "\nFailed to unstash changes in: '/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm'." 278 "\nYou will have to resolve the conflicts manually") 279 endif() 280 endif() 281 endif() 282 283 set(init_submodules "TRUE") 284 if(init_submodules) 285 execute_process( 286 COMMAND "/usr/bin/git" 287 --git-dir=.git 288 submodule update --recursive --init 289 WORKING_DIRECTORY "/home/dwrz/.config/emacs/elpa/vterm-20240325.1551/build/libvterm-prefix/src/libvterm" 290 COMMAND_ERROR_IS_FATAL ANY 291 ) 292 endif()