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