| OLD | NEW |
| (Empty) |
| 1 #!/bin/bash | |
| 2 # Copyright 2012 the V8 project authors. All rights reserved. | |
| 3 # Redistribution and use in source and binary forms, with or without | |
| 4 # modification, are permitted provided that the following conditions are | |
| 5 # met: | |
| 6 # | |
| 7 # * Redistributions of source code must retain the above copyright | |
| 8 # notice, this list of conditions and the following disclaimer. | |
| 9 # * Redistributions in binary form must reproduce the above | |
| 10 # copyright notice, this list of conditions and the following | |
| 11 # disclaimer in the documentation and/or other materials provided | |
| 12 # with the distribution. | |
| 13 # * Neither the name of Google Inc. nor the names of its | |
| 14 # contributors may be used to endorse or promote products derived | |
| 15 # from this software without specific prior written permission. | |
| 16 # | |
| 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 28 | |
| 29 ########## Global variable definitions | |
| 30 | |
| 31 BRANCHNAME=prepare-merge | |
| 32 PERSISTFILE_BASENAME=/tmp/v8-merge-to-branch-tempfile | |
| 33 ALREADY_MERGING_SENTINEL_FILE="$PERSISTFILE_BASENAME-already-merging" | |
| 34 COMMIT_HASHES_FILE="$PERSISTFILE_BASENAME-PATCH_COMMIT_HASHES" | |
| 35 TEMPORARY_PATCH_FILE="$PERSISTFILE_BASENAME-temporary-patch" | |
| 36 | |
| 37 ########## Function definitions | |
| 38 | |
| 39 source $(dirname $BASH_SOURCE)/common-includes.sh | |
| 40 | |
| 41 usage() { | |
| 42 cat << EOF | |
| 43 usage: $0 [OPTIONS]... [BRANCH] [REVISION]... | |
| 44 | |
| 45 Performs the necessary steps to merge revisions from bleeding_edge | |
| 46 to other branches, including trunk. | |
| 47 | |
| 48 OPTIONS: | |
| 49 -h Show this message | |
| 50 -s Specify the step where to start work. Default: 0. | |
| 51 -p Specify a patch file to apply as part of the merge | |
| 52 -m Specify a commit message for the patch | |
| 53 -r Reverse specified patches | |
| 54 EOF | |
| 55 } | |
| 56 | |
| 57 persist_patch_commit_hashes() { | |
| 58 echo "PATCH_COMMIT_HASHES=( ${PATCH_COMMIT_HASHES[@]} )" > $COMMIT_HASHES_FILE | |
| 59 } | |
| 60 | |
| 61 restore_patch_commit_hashes() { | |
| 62 source $COMMIT_HASHES_FILE | |
| 63 } | |
| 64 | |
| 65 restore_patch_commit_hashes_if_unset() { | |
| 66 [[ "${#PATCH_COMMIT_HASHES[@]}" == 0 ]] && restore_patch_commit_hashes | |
| 67 [[ "${#PATCH_COMMIT_HASHES[@]}" == 0 ]] && [[ -z "$EXTRA_PATCH" ]] && \ | |
| 68 die "Variable PATCH_COMMIT_HASHES could not be restored." | |
| 69 } | |
| 70 | |
| 71 ########## Option parsing | |
| 72 REVERT_FROM_BLEEDING_EDGE=0 | |
| 73 | |
| 74 while getopts ":hs:fp:rm:R" OPTION ; do | |
| 75 case $OPTION in | |
| 76 h) usage | |
| 77 exit 0 | |
| 78 ;; | |
| 79 p) EXTRA_PATCH=$OPTARG | |
| 80 ;; | |
| 81 f) rm -f "$ALREADY_MERGING_SENTINEL_FILE" | |
| 82 ;; | |
| 83 r) REVERSE_PATCH="--reverse" | |
| 84 ;; | |
| 85 m) NEW_COMMIT_MSG=$OPTARG | |
| 86 ;; | |
| 87 s) START_STEP=$OPTARG | |
| 88 ;; | |
| 89 R) REVERSE_PATCH="--reverse" | |
| 90 REVERT_FROM_BLEEDING_EDGE=1 | |
| 91 ;; | |
| 92 ?) echo "Illegal option: -$OPTARG" | |
| 93 usage | |
| 94 exit 1 | |
| 95 ;; | |
| 96 esac | |
| 97 done | |
| 98 let OPTION_COUNT=$OPTIND-1 | |
| 99 shift $OPTION_COUNT | |
| 100 | |
| 101 ########## Regular workflow | |
| 102 | |
| 103 # If there is a merge in progress, abort. | |
| 104 [[ -e "$ALREADY_MERGING_SENTINEL_FILE" ]] && [[ $START_STEP -eq 0 ]] \ | |
| 105 && die "A merge is already in progress" | |
| 106 touch "$ALREADY_MERGING_SENTINEL_FILE" | |
| 107 | |
| 108 initial_environment_checks | |
| 109 | |
| 110 if [ $START_STEP -le $CURRENT_STEP ] ; then | |
| 111 let MIN_EXPECTED_ARGS=2-$REVERT_FROM_BLEEDING_EDGE | |
| 112 if [ ${#@} -lt $MIN_EXPECTED_ARGS ] ; then | |
| 113 if [ -z "$EXTRA_PATCH" ] ; then | |
| 114 die "Either a patch file or revision numbers must be specified" | |
| 115 fi | |
| 116 if [ -z "$NEW_COMMIT_MSG" ] ; then | |
| 117 die "You must specify a merge comment if no patches are specified" | |
| 118 fi | |
| 119 fi | |
| 120 echo ">>> Step $CURRENT_STEP: Preparation" | |
| 121 if [ $REVERT_FROM_BLEEDING_EDGE -eq 1 ] ; then | |
| 122 MERGE_TO_BRANCH="bleeding_edge" | |
| 123 else | |
| 124 MERGE_TO_BRANCH=$1 | |
| 125 [[ -n "$MERGE_TO_BRANCH" ]] || die "Please specify a branch to merge to" | |
| 126 shift | |
| 127 fi | |
| 128 persist "MERGE_TO_BRANCH" | |
| 129 common_prepare | |
| 130 fi | |
| 131 | |
| 132 let CURRENT_STEP+=1 | |
| 133 if [ $START_STEP -le $CURRENT_STEP ] ; then | |
| 134 echo ">>> Step $CURRENT_STEP: Create a fresh branch for the patch." | |
| 135 restore_if_unset "MERGE_TO_BRANCH" | |
| 136 git checkout -b $BRANCHNAME svn/$MERGE_TO_BRANCH \ | |
| 137 || die "Creating branch $BRANCHNAME failed." | |
| 138 fi | |
| 139 | |
| 140 let CURRENT_STEP+=1 | |
| 141 if [ $START_STEP -le $CURRENT_STEP ] ; then | |
| 142 echo ">>> Step $CURRENT_STEP: Search for corresponding architecture ports." | |
| 143 for REVISION in "$@" ; do | |
| 144 # Add the revision to the array if it isn't already added. | |
| 145 if [[ ! "${FULL_REVISION_LIST[@]}" =~ (^| )$REVISION($| ) ]] ; then | |
| 146 FULL_REVISION_LIST=("${FULL_REVISION_LIST[@]}" "$REVISION") | |
| 147 fi | |
| 148 # Search for commits which matches the "Port rXXX" pattern. | |
| 149 GIT_HASHES=$(git log svn/bleeding_edge --reverse \ | |
| 150 --format=%H --grep="Port r$REVISION") | |
| 151 if [ -n "$GIT_HASHES" ]; then | |
| 152 while read -r NEXT_GIT_HASH; do | |
| 153 NEXT_SVN_REVISION=$(git svn find-rev $NEXT_GIT_HASH svn/bleeding_edge) | |
| 154 [[ -n "$NEXT_SVN_REVISION" ]] \ | |
| 155 || die "Cannot determine svn revision for $NEXT_GIT_HASH" | |
| 156 FULL_REVISION_LIST=("${FULL_REVISION_LIST[@]}" "$NEXT_SVN_REVISION") | |
| 157 REVISION_TITLE=$(git log -1 --format=%s $NEXT_GIT_HASH) | |
| 158 # Is this revision included in the original revision list? | |
| 159 if [[ $@ =~ (^| )$NEXT_SVN_REVISION($| ) ]] ; then | |
| 160 echo "Found port of r$REVISION -> \ | |
| 161 r$NEXT_SVN_REVISION (already included): $REVISION_TITLE" | |
| 162 else | |
| 163 echo "Found port of r$REVISION -> \ | |
| 164 r$NEXT_SVN_REVISION: $REVISION_TITLE" | |
| 165 PORT_REVISION_LIST=("${PORT_REVISION_LIST[@]}" "$NEXT_SVN_REVISION") | |
| 166 fi | |
| 167 done <<< "$GIT_HASHES" | |
| 168 fi | |
| 169 done | |
| 170 # Next step expects a list, not an array. | |
| 171 FULL_REVISION_LIST="${FULL_REVISION_LIST[@]}" | |
| 172 # Do we find any port? | |
| 173 if [ ${#PORT_REVISION_LIST[@]} -ne 0 ] ; then | |
| 174 confirm "Automatically add corresponding ports (${PORT_REVISION_LIST[*]})?" | |
| 175 #: 'n': Restore the original revision list. | |
| 176 if [ $? -ne 0 ] ; then | |
| 177 FULL_REVISION_LIST="$@" | |
| 178 fi | |
| 179 fi | |
| 180 persist "FULL_REVISION_LIST" | |
| 181 fi | |
| 182 | |
| 183 let CURRENT_STEP+=1 | |
| 184 if [ $START_STEP -le $CURRENT_STEP ] ; then | |
| 185 echo ">>> Step $CURRENT_STEP: Find the git \ | |
| 186 revisions associated with the patches." | |
| 187 restore_if_unset "FULL_REVISION_LIST" | |
| 188 current=0 | |
| 189 for REVISION in $FULL_REVISION_LIST ; do | |
| 190 NEXT_HASH=$(git svn find-rev "r$REVISION" svn/bleeding_edge) | |
| 191 [[ -n "$NEXT_HASH" ]] \ | |
| 192 || die "Cannot determine git hash for r$REVISION" | |
| 193 PATCH_COMMIT_HASHES[$current]="$NEXT_HASH" | |
| 194 [[ -n "$REVISION_LIST" ]] && REVISION_LIST="$REVISION_LIST," | |
| 195 REVISION_LIST="$REVISION_LIST r$REVISION" | |
| 196 let current+=1 | |
| 197 done | |
| 198 if [ -n "$REVISION_LIST" ] ; then | |
| 199 if [ -n "$REVERSE_PATCH" ] ; then | |
| 200 if [ $REVERT_FROM_BLEEDING_EDGE -eq 0 ] ; then | |
| 201 NEW_COMMIT_MSG="Rollback of$REVISION_LIST in $MERGE_TO_BRANCH branch." | |
| 202 else | |
| 203 NEW_COMMIT_MSG="Revert$REVISION_LIST." | |
| 204 fi | |
| 205 else | |
| 206 NEW_COMMIT_MSG="Merged$REVISION_LIST into $MERGE_TO_BRANCH branch." | |
| 207 fi; | |
| 208 fi; | |
| 209 | |
| 210 echo "$NEW_COMMIT_MSG" > $COMMITMSG_FILE | |
| 211 echo "" >> $COMMITMSG_FILE | |
| 212 for HASH in ${PATCH_COMMIT_HASHES[@]} ; do | |
| 213 PATCH_MERGE_DESCRIPTION=$(git log -1 --format=%s $HASH) | |
| 214 echo "$PATCH_MERGE_DESCRIPTION" >> $COMMITMSG_FILE | |
| 215 echo "" >> $COMMITMSG_FILE | |
| 216 done | |
| 217 for HASH in ${PATCH_COMMIT_HASHES[@]} ; do | |
| 218 BUG=$(git log -1 $HASH | grep "BUG=" | awk -F '=' '{print $NF}') | |
| 219 if [ -n "$BUG" ] ; then | |
| 220 [[ -n "$BUG_AGGREGATE" ]] && BUG_AGGREGATE="$BUG_AGGREGATE," | |
| 221 BUG_AGGREGATE="$BUG_AGGREGATE$BUG" | |
| 222 fi | |
| 223 done | |
| 224 if [ -n "$BUG_AGGREGATE" ] ; then | |
| 225 echo "BUG=$BUG_AGGREGATE" >> $COMMITMSG_FILE | |
| 226 echo "LOG=N" >> $COMMITMSG_FILE | |
| 227 fi | |
| 228 persist "NEW_COMMIT_MSG" | |
| 229 persist "REVISION_LIST" | |
| 230 persist_patch_commit_hashes | |
| 231 fi | |
| 232 | |
| 233 let CURRENT_STEP+=1 | |
| 234 if [ $START_STEP -le $CURRENT_STEP ] ; then | |
| 235 echo ">>> Step $CURRENT_STEP: Apply patches for selected revisions." | |
| 236 restore_if_unset "MERGE_TO_BRANCH" | |
| 237 restore_patch_commit_hashes_if_unset "PATCH_COMMIT_HASHES" | |
| 238 for HASH in ${PATCH_COMMIT_HASHES[@]} ; do | |
| 239 echo "Applying patch for $HASH to $MERGE_TO_BRANCH..." | |
| 240 git log -1 -p $HASH > "$TEMPORARY_PATCH_FILE" | |
| 241 apply_patch "$TEMPORARY_PATCH_FILE" | |
| 242 done | |
| 243 if [ -n "$EXTRA_PATCH" ] ; then | |
| 244 apply_patch "$EXTRA_PATCH" | |
| 245 fi | |
| 246 fi | |
| 247 | |
| 248 let CURRENT_STEP+=1 | |
| 249 if [ $START_STEP -le $CURRENT_STEP ] && [ $REVERT_FROM_BLEEDING_EDGE -eq 0 ] ; t
hen | |
| 250 echo ">>> Step $CURRENT_STEP: Prepare $VERSION_FILE." | |
| 251 # These version numbers are used again for creating the tag | |
| 252 read_and_persist_version | |
| 253 fi | |
| 254 | |
| 255 let CURRENT_STEP+=1 | |
| 256 if [ $START_STEP -le $CURRENT_STEP ] && [ $REVERT_FROM_BLEEDING_EDGE -eq 0 ] ; t
hen | |
| 257 echo ">>> Step $CURRENT_STEP: Increment version number." | |
| 258 restore_if_unset "PATCH" | |
| 259 NEWPATCH=$(($PATCH + 1)) | |
| 260 confirm "Automatically increment PATCH_LEVEL? (Saying 'n' will fire up \ | |
| 261 your EDITOR on $VERSION_FILE so you can make arbitrary changes. When \ | |
| 262 you're done, save the file and exit your EDITOR.)" | |
| 263 if [ $? -eq 0 ] ; then | |
| 264 echo $NEWPATCH $VERSION_FILE | |
| 265 sed -e "/#define PATCH_LEVEL/s/[0-9]*$/$NEWPATCH/" \ | |
| 266 -i.bak "$VERSION_FILE" || die "Could not increment patch level" | |
| 267 else | |
| 268 $EDITOR "$VERSION_FILE" | |
| 269 fi | |
| 270 read_and_persist_version "NEW" | |
| 271 fi | |
| 272 | |
| 273 let CURRENT_STEP+=1 | |
| 274 if [ $START_STEP -le $CURRENT_STEP ] ; then | |
| 275 echo ">>> Step $CURRENT_STEP: Commit to local branch." | |
| 276 git commit -a -F "$COMMITMSG_FILE" \ | |
| 277 || die "'git commit -a' failed." | |
| 278 fi | |
| 279 | |
| 280 upload_step | |
| 281 | |
| 282 let CURRENT_STEP+=1 | |
| 283 if [ $START_STEP -le $CURRENT_STEP ] ; then | |
| 284 echo ">>> Step $CURRENT_STEP: Commit to the repository." | |
| 285 restore_if_unset "MERGE_TO_BRANCH" | |
| 286 git checkout $BRANCHNAME \ | |
| 287 || die "cannot ensure that the current branch is $BRANCHNAME" | |
| 288 wait_for_lgtm | |
| 289 PRESUBMIT_TREE_CHECK="skip" git cl presubmit \ | |
| 290 || die "presubmit failed" | |
| 291 PRESUBMIT_TREE_CHECK="skip" git cl dcommit --bypass-hooks \ | |
| 292 || die "failed to commit to $MERGE_TO_BRANCH" | |
| 293 fi | |
| 294 | |
| 295 let CURRENT_STEP+=1 | |
| 296 if [ $START_STEP -le $CURRENT_STEP ] && [ $REVERT_FROM_BLEEDING_EDGE -eq 0 ] ; t
hen | |
| 297 echo ">>> Step $CURRENT_STEP: Determine svn commit revision" | |
| 298 restore_if_unset "NEW_COMMIT_MSG" | |
| 299 restore_if_unset "MERGE_TO_BRANCH" | |
| 300 git svn fetch || die "'git svn fetch' failed." | |
| 301 COMMIT_HASH=$(git log -1 --format=%H --grep="$NEW_COMMIT_MSG" \ | |
| 302 svn/$MERGE_TO_BRANCH) | |
| 303 [[ -z "$COMMIT_HASH" ]] && die "Unable to map git commit to svn revision" | |
| 304 SVN_REVISION=$(git svn find-rev $COMMIT_HASH) | |
| 305 echo "subversion revision number is r$SVN_REVISION" | |
| 306 persist "SVN_REVISION" | |
| 307 fi | |
| 308 | |
| 309 let CURRENT_STEP+=1 | |
| 310 if [ $START_STEP -le $CURRENT_STEP ] && [ $REVERT_FROM_BLEEDING_EDGE -eq 0 ] ; t
hen | |
| 311 echo ">>> Step $CURRENT_STEP: Create the tag." | |
| 312 restore_if_unset "SVN_REVISION" | |
| 313 restore_version_if_unset "NEW" | |
| 314 echo "Creating tag svn/tags/$NEWMAJOR.$NEWMINOR.$NEWBUILD.$NEWPATCH" | |
| 315 if [ "$MERGE_TO_BRANCH" == "trunk" ] ; then | |
| 316 TO_URL="$MERGE_TO_BRANCH" | |
| 317 else | |
| 318 TO_URL="branches/$MERGE_TO_BRANCH" | |
| 319 fi | |
| 320 svn copy -r $SVN_REVISION \ | |
| 321 https://v8.googlecode.com/svn/$TO_URL \ | |
| 322 https://v8.googlecode.com/svn/tags/$NEWMAJOR.$NEWMINOR.$NEWBUILD.$NEWPATCH \ | |
| 323 -m "Tagging version $NEWMAJOR.$NEWMINOR.$NEWBUILD.$NEWPATCH" | |
| 324 persist "TO_URL" | |
| 325 fi | |
| 326 | |
| 327 let CURRENT_STEP+=1 | |
| 328 if [ $START_STEP -le $CURRENT_STEP ] ; then | |
| 329 echo ">>> Step $CURRENT_STEP: Cleanup." | |
| 330 restore_if_unset "SVN_REVISION" | |
| 331 restore_if_unset "TO_URL" | |
| 332 restore_if_unset "REVISION_LIST" | |
| 333 restore_version_if_unset "NEW" | |
| 334 common_cleanup | |
| 335 if [ $REVERT_FROM_BLEEDING_EDGE==0 ] ; then | |
| 336 echo "*** SUMMARY ***" | |
| 337 echo "version: $NEWMAJOR.$NEWMINOR.$NEWBUILD.$NEWPATCH" | |
| 338 echo "branch: $TO_URL" | |
| 339 echo "svn revision: $SVN_REVISION" | |
| 340 [[ -n "$REVISION_LIST" ]] && echo "patches:$REVISION_LIST" | |
| 341 fi | |
| 342 fi | |
| OLD | NEW |