1# $Id$ 2# vim:et:ft=sh:sts=2:sw=2 3# 4# git-flow -- A collection of Git extensions to provide high-level 5# repository operations for Vincent Driessen's branching model. 6# 7# A blog post presenting this model is found at: 8# http://blog.avirtualhome.com/development-workflow-using-git/ 9# 10# Feel free to contribute to this project at: 11# http://github.com/petervanderdoes/gitflow 12# 13# Authors: 14# Copyright 2012-2019 Peter van der Does. All rights reserved. 15# 16# Original Author: 17# Copyright 2010 Vincent Driessen. All rights reserved. 18# 19# Redistribution and use in source and binary forms, with or without 20# modification, are permitted provided that the following conditions are met: 21# 22# 1. Redistributions of source code must retain the above copyright notice, this 23# list of conditions and the following disclaimer. 24# 2. Redistributions in binary form must reproduce the above copyright notice, 25# this list of conditions and the following disclaimer in the documentation 26# and/or other materials provided with the distribution. 27# 28# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 29# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 30# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 31# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 32# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 33# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 34# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 35# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 37# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38# 39 40initialize() { 41 require_git_repo 42 require_gitflow_initialized 43 git config --get gitflow.prefix.hotfix >/dev/null 2>&1 || die "Hotfix prefix not set. Please run 'git flow init'." 44 gitflow_load_settings 45 VERSION_PREFIX=$(git config --get gitflow.prefix.versiontag) 46 PREFIX=$(git config --get gitflow.prefix.hotfix) 47} 48 49usage() { 50 OPTIONS_SPEC="\ 51git flow hotfix [list] 52git flow hotfix start 53git flow hotfix finish 54git flow hotfix publish 55git flow hotfix delete 56 57Manage your hotfix branches. 58 59For more specific help type the command followed by --help 60-- 61" 62 flags_help 63} 64 65cmd_default() { 66 cmd_list "$@" 67} 68 69cmd_list() { 70 OPTIONS_SPEC="\ 71git flow hotfix [list] [-h] [-v] 72 73Lists all local hotfix branches 74-- 75h,help! Show this help 76v,verbose! Verbose (more) output 77" 78 local hotfix_branches current_branch width branch len 79 local base master_sha branch_sha 80 81 # Define flags 82 DEFINE_boolean 'verbose' false 'verbose (more) output' v 83 84 # Parse arguments 85 parse_args "$@" 86 87 hotfix_branches=$(git_local_branches_prefixed "$PREFIX") 88 if [ -z "$hotfix_branches" ]; then 89 warn "No hotfix branches exist." 90 warn "" 91 warn "You can start a new hotfix branch:" 92 warn "" 93 warn " git flow hotfix start <version> [<base>]" 94 warn "" 95 exit 0 96 fi 97 current_branch=$(git_current_branch) 98 99 # Determine column width first 100 width=0 101 for branch in $hotfix_branches; do 102 len=${#branch} 103 width=$(max $width $len) 104 done 105 width=$(($width+3-${#PREFIX})) 106 107 for branch in $hotfix_branches; do 108 base=$(git merge-base "$branch" "$MASTER_BRANCH") 109 master_sha=$(git rev-parse "$MASTER_BRANCH") 110 branch_sha=$(git rev-parse "$branch") 111 if [ "$branch" = "$current_branch" ]; then 112 printf "* " 113 else 114 printf " " 115 fi 116 if flag verbose; then 117 printf "%-${width}s" "${branch#$PREFIX}" 118 if [ "$branch_sha" = "$master_sha" ]; then 119 printf "(no commits yet)" 120 else 121 local tagname=$(git name-rev --tags --no-undefined --name-only "$base") 122 local nicename 123 if [ "$tagname" != "" ]; then 124 nicename=$tagname 125 else 126 nicename=$(git rev-parse --short "$base") 127 fi 128 printf "(based on $nicename)" 129 fi 130 else 131 printf "%s" "${branch#$PREFIX}" 132 fi 133 echo 134 done 135} 136 137cmd_help() { 138 usage 139 exit 0 140} 141 142# Parse arguments and set common variables 143parse_args() { 144 FLAGS "$@" || exit $? 145 eval set -- "${FLAGS_ARGV}" 146 147 # Read arguments into global variables 148 if [ -z $1 ]; then 149 VERSION='' 150 else 151 VERSION=$1 152 fi 153 BRANCH=$PREFIX$VERSION 154} 155 156require_no_existing_hotfix_branches() { 157 local hotfix_branches first_branch 158 159 hotfix_branches=$(git_local_branches_prefixed "$PREFIX") 160 first_branch=$(echo ${hotfix_branches} | head -n1) 161 162 first_branch=${first_branch#$PREFIX} 163 [ -z "$hotfix_branches" ] || die "There is an existing hotfix branch '$first_branch'. Finish that one first." 164} 165 166cmd_start() { 167 OPTIONS_SPEC="\ 168git flow hotfix start [-h] [-F] <version> [<base>] 169 170Start new hotfix branch named <version>, optionally base it on <base> instead of the <master> branch 171-- 172h,help! Show this help 173showcommands! Show git commands while executing them 174F,[no]fetch Fetch from origin before performing local operation 175" 176 local base 177 178 # Define flags 179 DEFINE_boolean 'fetch' false "fetch from $ORIGIN before performing finish" F 180 181 # Override defaults with values from config 182 gitflow_override_flag_boolean "hotfix.start.fetch" "fetch" 183 184 # Parse arguments 185 parse_args "$@" 186 eval set -- "${FLAGS_ARGV}" 187 base=${2:-$MASTER_BRANCH} 188 189 # No need to continue if not clean 190 require_base_is_local_branch "$base" 191 git_config_bool_exists "gitflow.allowdirty" || require_clean_working_tree 192 193 # Update the local repo with remote changes, if asked 194 if flag fetch; then 195 git_fetch_branch "$ORIGIN" "$base" 196 fi 197 198 # Run filter on the version 199 VERSION=$(run_filter_hook hotfix-start-version $VERSION) 200 if [ $? -eq 127 ]; then 201 die $VERSION 202 fi 203 204 # As VERSION might have changed reset BRANCH with new VERSION 205 BRANCH=$PREFIX$VERSION 206 207 gitflow_require_version_arg 208 if ! $(git config --bool --get gitflow.multi-hotfix 2>&1); then 209 require_no_existing_hotfix_branches 210 fi 211 212 # Sanity checks 213 require_branch_absent "$BRANCH" 214 require_tag_absent "$VERSION_PREFIX$VERSION" 215 if git_remote_branch_exists "$ORIGIN/$base"; then 216 require_branches_equal "$base" "$ORIGIN/$base" 217 fi 218 219 run_pre_hook "$VERSION_PREFIX$VERSION" "$ORIGIN" "$BRANCH" "$base" 220 221 gitflow_config_set_base_branch $base $BRANCH 222 223 # Create branch 224 git_do checkout -b "$BRANCH" "$base" || die "Could not create hotfix branch '$BRANCH'." 225 226 run_post_hook "$VERSION_PREFIX$VERSION" "$ORIGIN" "$BRANCH" "$base" 227 228 echo 229 echo "Summary of actions:" 230 echo "- A new branch '$BRANCH' was created, based on '$base'" 231 echo "- You are now on branch '$(git_current_branch)'" 232 echo 233 echo "Follow-up actions:" 234 echo "- Start committing your hot fixes" 235 echo "- Bump the version number now!" 236 echo "- When done, run:" 237 echo 238 echo " git flow hotfix finish '$VERSION'" 239 echo 240} 241 242cmd_publish() { 243 OPTIONS_SPEC="\ 244git flow hotfix publish [-h] <version> 245 246Start sharing hotfix <name> on $ORIGIN 247-- 248h,help! Show this help 249showcommands! Show git commands while executing them 250" 251 # Parse arguments 252 parse_args "$@" 253 254 # Use current branch if no version is given 255 if [ "$VERSION" = "" ]; then 256 gitflow_use_current_branch_version 257 fi 258 259 # Sanity checks 260 require_clean_working_tree 261 require_branch "$BRANCH" 262 git_do fetch -q "$ORIGIN" || die "Could not fetch branch '$BRANCH' from remote '$ORIGIN'." 263 require_branch_absent "$ORIGIN/$BRANCH" 264 265 run_pre_hook "$VERSION_PREFIX$VERSION" "$ORIGIN" "$BRANCH" 266 267 # Create remote branch with remote tracking 268 git_do push -u "$ORIGIN" "$BRANCH:$BRANCH" 269 git_do fetch -q "$ORIGIN" "$BRANCH" || die "Could not fetch branch '$BRANCH' from remote '$ORIGIN'." 270 git_do checkout "$BRANCH" || die "Could not check out branch '$BRANCH'." 271 272 run_post_hook "$VERSION_PREFIX$VERSION" "$ORIGIN" "$BRANCH" 273 274 echo 275 echo "Summary of actions:" 276 echo "- The remote branch '$BRANCH' was created or updated" 277 echo "- The local branch '$BRANCH' was configured to track the remote branch" 278 echo "- You are now on branch '$(git_current_branch)'" 279 echo 280} 281 282cmd_rebase() { 283 OPTIONS_SPEC="\ 284git flow hotfix rebase [-h] [-i] [-p] [<name|nameprefix>] 285 286Rebase <name> on <base_branch> 287-- 288h,help! Show this help 289showcommands! Show git commands while executing them 290i,[no]interactive Do an interactive rebase 291p,[no]preserve-merges Preserve merges 292" 293 local opts 294 295 # Define flags 296 DEFINE_boolean 'interactive' false 'do an interactive rebase' i 297 DEFINE_boolean 'preserve-merges' false 'try to recreate merges' p 298 299 # Override defaults with values from config 300 gitflow_override_flag_boolean "hotfix.rebase.interactive" "interactive" 301 gitflow_override_flag_boolean "hotfix.rebase.preserve-merges" "preserve_merges" 302 303 # Parse arguments 304 parse_args "$@" 305 306 # Use current branch if no version is given 307 if [ "$VERSION" = "" ]; then 308 gitflow_use_current_branch_version 309 fi 310 311 BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH) 312 BASE_BRANCH=${BASE_BRANCH:-$DEVELOP_BRANCH} 313 314 warn "Will try to rebase '$NAME' which is based on '$BASE_BRANCH'..." 315 if ! git_config_bool_exists "rebase.autostash"; then 316 require_clean_working_tree 317 fi 318 require_branch "$BRANCH" 319 320 git_local_branch_exists "$BASE_BRANCH" || die "The base '$BASE_BRANCH' doesn't exists locally or is not a branch. Can't rebase the hotfixe branch '$BRANCH'." 321 322 git_do checkout -q "$BRANCH" || die "Could not check out branch '$BRANCH'." 323 if flag interactive; then 324 opts="$opts -i" 325 fi 326 if flag preserve_merges; then 327 opts="$opts -p" 328 fi 329 git_do rebase $opts "$BASE_BRANCH" 330} 331 332cmd_track() { 333 OPTIONS_SPEC="\ 334git flow hotfix track [-h] <version> 335 336Create a tracking hotfix branch from $ORIGIN 337-- 338h,help! Show this help 339showcommands! Show git commands while executing them 340" 341 # Parse arguments 342 parse_args "$@" 343 344 gitflow_require_version_arg 345 346 # Sanity checks 347 require_clean_working_tree 348 require_branch_absent "$BRANCH" 349 git_do fetch -q "$ORIGIN" 350 require_branch "$ORIGIN/$BRANCH" 351 352 # Create tracking branch 353 git_do checkout -b "$BRANCH" "$ORIGIN/$BRANCH" 354 355 echo 356 echo "Summary of actions:" 357 echo "- A new remote tracking branch '$BRANCH' was created" 358 echo "- You are now on branch '$BRANCH'" 359 echo 360} 361 362cmd_finish() { 363 OPTIONS_SPEC="\ 364git flow hotfix finish [-h] [-F] [-s] [-u] [-m | -f ] [-p] [-k] [-n] [-b] [-S] <version> 365 366Finish hotfix branch <version> 367-- 368h,help! Show this help 369showcommands! Show git commands while executing them 370F,[no]fetch Fetch from origin before performing finish 371s,[no]sign Sign the release tag cryptographically 372u,[no]signingkey Use the given GPG-key for the digital signature (implies -s) 373m,[no]message Use the given tag message 374f,[no]messagefile= Use the contents of the given file as tag message 375p,[no]push Push to origin after performing finish 376k,[no]keep Keep branch after performing finish 377[no]keepremote Keep the remote branch 378[no]keeplocal Keep the local branch 379D,[no]force_delete Force delete hotfix branch after finish 380n,[no]notag Don't tag this hotfix 381b,[no]nobackmerge Don't back-merge master, or tag if applicable, in develop 382S,[no]squash Squash hotfix during merge 383T,tagname! Use given tag name 384" 385 local opts commit keepmsg remotebranchdeleted localbranchdeleted 386 387 # Define flags 388 DEFINE_boolean 'fetch' false "fetch from $ORIGIN before performing finish" F 389 DEFINE_boolean 'sign' false "sign the release tag cryptographically" s 390 DEFINE_string 'signingkey' "" "use the given GPG-key for the digital signature (implies -s)" u 391 DEFINE_string 'message' "" "use the given tag message" m 392 DEFINE_string 'messagefile' "" "use the contents of the given file as tag message" f 393 DEFINE_boolean 'push' false "push to $ORIGIN after performing finish" p 394 DEFINE_boolean 'keep' false "keep branch after performing finish" k 395 DEFINE_boolean 'keepremote' false "keep the remote branch" 396 DEFINE_boolean 'keeplocal' false "keep the local branch" 397 DEFINE_boolean 'force_delete' false "force delete hotfix branch after finish" D 398 DEFINE_boolean 'notag' false "don't tag this hotfix" n 399 DEFINE_boolean 'nobackmerge' false "don't back-merge $MASTER_BRANCH, or tag if applicable, in $DEVELOP_BRANCH " b 400 DEFINE_boolean 'squash' false "squash release during merge" S 401 DEFINE_boolean 'squash-info' false "add branch info during squash" 402 DEFINE_string 'tagname' "" "use the given tag name" T 403 404 # Override defaults with values from config 405 gitflow_override_flag_boolean "hotfix.finish.fetch" "fetch" 406 gitflow_override_flag_boolean "hotfix.finish.sign" "sign" 407 gitflow_override_flag_boolean "hotfix.finish.push" "push" 408 gitflow_override_flag_boolean "hotfix.finish.keep" "keep" 409 gitflow_override_flag_boolean "hotfix.finish.keepremote" "keepremote" 410 gitflow_override_flag_boolean "hotfix.finish.keeplocal" "keeplocal" 411 gitflow_override_flag_boolean "hotfix.finish.force-delete" "force_delete" 412 gitflow_override_flag_boolean "hotfix.finish.notag" "notag" 413 gitflow_override_flag_boolean "hotfix.finish.nobackmerge" "nobackmerge" 414 gitflow_override_flag_boolean "hotfix.finish.squash" "squash" 415 gitflow_override_flag_boolean "hotfix.finish.squash-info" "squash_info" 416 gitflow_override_flag_string "hotfix.finish.signingkey" "signingkey" 417 gitflow_override_flag_string "hotfix.finish.message" "message" 418 gitflow_override_flag_string "hotfix.finish.messagefile" "messagefile" 419 420 # Parse arguments 421 parse_args "$@" 422 423 # Use current branch if no version is given 424 if [ "$VERSION" = "" ]; then 425 gitflow_use_current_branch_version 426 fi 427 428 # Use branch name if no tag name is given 429 if [ "$FLAGS_tagname" != "" ]; then 430 TAGNAME=$FLAGS_tagname 431 else 432 TAGNAME=$VERSION 433 fi 434 435 remotebranchdeleted=$FLAGS_FALSE 436 localbranchdeleted=$FLAGS_FALSE 437 438 # Handle flags that imply other flags 439 if [ "$FLAGS_signingkey" != "" ]; then 440 FLAGS_sign=$FLAGS_TRUE 441 fi 442 443 # Keeping both branches implies the --keep flag to be true. 444 if flag keepremote && flag keeplocal; then 445 FLAGS_keep=$FLAGS_TRUE 446 fi 447 448 # Sanity checks 449 require_branch "$BRANCH" 450 require_clean_working_tree 451 452 BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH) 453 BASE_BRANCH=${BASE_BRANCH:-$MASTER_BRANCH} 454 git_local_branch_exists "$BASE_BRANCH" || die "The base '$BASE_BRANCH' doesn't exists locally or is not a branch. Can't finish the hotfix branch '$BRANCH'." 455 456 # We always fetch the Branch from Origin 457 # This is done to avoid possible commits on the remote that are not 458 # merged into the local branch 459 if git_remote_branch_exists "$ORIGIN/$BRANCH"; then 460 git_fetch_branch "$ORIGIN" "$BRANCH" 461 fi 462 463 # Update local branches with remote branches 464 if flag fetch; then 465 git_fetch_branch "$ORIGIN" "$BASE_BRANCH" 466 [ "$BASE_BRANCH" = "$MASTER_BRANCH" ] && git_fetch_branch "$ORIGIN" "$DEVELOP_BRANCH" 467 fi 468 469 # Check if the local branches have all the commits from the remote branches 470 if git_remote_branch_exists "$ORIGIN/$BRANCH"; then 471 require_branches_equal "$BRANCH" "$ORIGIN/$BRANCH" 472 fi 473 if git_remote_branch_exists "$ORIGIN/$BASE_BRANCH"; then 474 require_branches_equal "$BASE_BRANCH" "$ORIGIN/$BASE_BRANCH" 475 fi 476 if [ "$BASE_BRANCH" = "$MASTER_BRANCH" ]; then 477 if git_remote_branch_exists "$ORIGIN/$DEVELOP_BRANCH"; then 478 require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH" 479 fi 480 fi 481 482 # If the branch is already merged there is no need to check the hotfix branch 483 # This can happen when the merge in develop fails and we rerun the finish. 484 if ! git_is_branch_merged_into "$BRANCH" "$BASE_BRANCH"; then 485 # Check if the hotfix branch: 486 # - has commits: No reason to finish a hotfix without commits 487 # - Is ahead of the BASE: If it's not a good idea to merge 488 # - Can be merged: If there's no common ancestor we can't merge the hotfix 489 git_compare_refs "$BRANCH" "$BASE_BRANCH" 490 case $? in 491 0) 492 die "You need some commits in the hotfix branch '$BRANCH'" 493 ;; 494 1) 495 die "The hotfix branch '$BRANCH' is not ahead of branch '$BASE_BRANCH'" 496 ;; 497 4) 498 die "The hotfix branch '$BRANCH' has no common ancestor with branch '$BASE_BRANCH'" 499 ;; 500 *) 501 ;; 502 esac 503 fi 504 505 if noflag notag; then 506 # We ask for a tag, be sure it does not exists or 507 # points to the latest hotfix commit 508 if git_tag_exists "$VERSION_PREFIX$TAGNAME"; then 509 git_compare_refs "$BRANCH" "$VERSION_PREFIX$TAGNAME"^2 2>/dev/null 510 [ $? -eq 0 ] || die "Tag already exists and does not point to hotfix branch '$BRANCH'" 511 fi 512 fi 513 514 run_pre_hook "$VERSION_PREFIX$TAGNAME" "$ORIGIN" "$BRANCH" 515 516 # Try to merge into BASE. 517 # In case a previous attempt to finish this release branch has failed, 518 # but the merge into BASE was successful, we skip it now 519 if ! git_is_branch_merged_into "$BRANCH" "$BASE_BRANCH"; then 520 git_do checkout "$BASE_BRANCH" || die "Could not check out branch '$BASE_BRANCH'." 521 if noflag squash; then 522 git_do merge --no-ff "$BRANCH" || die "There were merge conflicts." # TODO: What do we do now? 523 else 524 git_do merge --squash "$BRANCH" || die "There were merge conflicts." # TODO: What do we do now? 525 flag squash_info && gitflow_create_squash_message "Merged hotfix branch '$BRANCH'" "$BASE_BRANCH" "$BRANCH" > "$DOT_GIT_DIR/SQUASH_MSG" 526 git_do commit 527 fi 528 fi 529 530 if noflag notag; then 531 # Try to tag the release. 532 # In case a previous attempt to finish this release branch has failed, 533 # but the tag was set successful, we skip it now 534 if ! git_tag_exists "$VERSION_PREFIX$TAGNAME"; then 535 if [ "$FLAGS_message" != "" ] && [ "$FLAGS_messagefile" != "" ]; then 536 die "Use either -m,--message or -f,--messagefile. Can not use both options at the same time" 537 fi 538 opts="-a" 539 flag sign && opts="$opts -s" 540 [ "$FLAGS_signingkey" != "" ] && opts="$opts -u '$FLAGS_signingkey'" 541 if [ "$FLAGS_message" != "" ]; then 542 # Run filter on the tag message 543 FLAGS_message=$(run_filter_hook hotfix-finish-tag-message "${FLAGS_message}" "$VERSION_PREFIX$TAGNAME") 544 opts="$opts -m '$FLAGS_message'" 545 fi 546 [ "$FLAGS_messagefile" != "" ] && opts="$opts -F '$FLAGS_messagefile'" 547 eval git_do tag $opts "$VERSION_PREFIX$TAGNAME" || die "Tagging failed. Please run finish again to retry." 548 fi 549 fi 550 551 if [ "$BASE_BRANCH" = "$MASTER_BRANCH" ]; then 552 # By default we back-merge the $MASTER_BRANCH unless the user explicitly 553 # stated not to do a back-merge, in that case we use the $BRANCH. 554 if noflag nobackmerge; then 555 MERGE_BRANCH="$BASE_BRANCH" 556 else 557 MERGE_BRANCH="$BRANCH" 558 fi 559 560 # Try to merge into develop. 561 # In case a previous attempt to finish this release branch has failed, 562 # but the merge into develop was successful, we skip it now 563 if ! git_is_branch_merged_into "$MERGE_BRANCH" "$DEVELOP_BRANCH"; then 564 git_do checkout "$DEVELOP_BRANCH" || die "Could not check out branch '$DEVELOP_BRANCH'." 565 566 if noflag nobackmerge; then 567 # Accounting for 'git describe', if a release is tagged 568 # we use the tag commit instead of the branch. 569 if noflag notag; then 570 commit="$VERSION_PREFIX$TAGNAME" 571 else 572 commit="$BASE_BRANCH" 573 fi 574 else 575 commit="$BRANCH" 576 fi 577 578 git_do merge --no-ff "$commit" || die "There were merge conflicts." 579 # TODO: What do we do now? 580 fi 581 fi 582 583 run_post_hook "$VERSION_PREFIX$TAGNAME" "$ORIGIN" "$BRANCH" 584 585 if flag push; then 586 if [ "$BASE_BRANCH" = "$MASTER_BRANCH" ]; then 587 git_do push "$ORIGIN" "$DEVELOP_BRANCH" || die "Could not push branch '$DEVELOP_BRANCH' to remote '$ORIGIN'." 588 fi 589 git_do push "$ORIGIN" "$BASE_BRANCH" || die "Could not push branch '$BASE_BRANCH' to remote '$ORIGIN'." 590 if noflag notag; then 591 git_do push --tags "$ORIGIN" || die "Could not push tags to remote '$ORIGIN'." 592 fi 593 fi 594 595 # Delete branch 596 if noflag keep; then 597 598 # Always delete remote first 599 if noflag keepremote;then 600 if git_remote_branch_exists "$ORIGIN/$BRANCH"; then 601 git_remote_branch_delete "$BRANCH" && remotebranchdeleted=$FLAGS_TRUE 602 fi 603 fi 604 605 # Delete local after remote to avoid warnings 606 if noflag keeplocal; then 607 if [ "$BRANCH" = "$(git_current_branch)" ]; then 608 git_do checkout "$DEVELOP_BRANCH" || die "Could not check out branch '$DEVELOP_BRANCH'." 609 fi 610 if flag force_delete; then 611 git_do branch -D "$BRANCH" && localbranchdeleted=$FLAGS_TRUE 612 else 613 git_do branch -d "$BRANCH" && localbranchdeleted=$FLAGS_TRUE 614 fi 615 fi 616 617 # no more branches: we can safely remove config section 618 if ! git_remote_branch_exists "$ORIGIN/$BRANCH" -a ! git_local_branch_exists "$BRANCH"; then 619 gitflow_config_remove_base_section "$BRANCH" 620 fi 621 622 fi 623 624 echo 625 echo "Summary of actions:" 626 if flag fetch; then 627 echo "- Latest objects have been fetched from '$ORIGIN'" 628 fi 629 echo "- Hotfix branch '$BRANCH' has been merged into '$BASE_BRANCH'" 630 if noflag notag; then 631 echo "- The hotfix was tagged '$VERSION_PREFIX$TAGNAME'" 632 fi 633 if [ "$BASE_BRANCH" = "$MASTER_BRANCH" ]; then 634 [ "$commit" = "$BASE_BRANCH" ] && echo "- Master branch '$BASE_BRANCH' has been back-merged into '$DEVELOP_BRANCH'" 635 [ "$commit" = "$VERSION_PREFIX$TAGNAME" ] && echo "- Hotfix tag '$VERSION_PREFIX$TAGNAME' has been back-merged into '$DEVELOP_BRANCH'" 636 [ "$commit" = "$BRANCH" ] && echo "- Hotfix branch '$BRANCH' has been merged into '$DEVELOP_BRANCH'" 637 fi 638 if noflag keep; then 639 if [ $localbranchdeleted -eq $FLAGS_TRUE ]; then 640 keepmsg="has been locally deleted" 641 else 642 keepmsg="is still locally available" 643 fi 644 if [ $remotebranchdeleted -eq $FLAGS_TRUE ]; then 645 keepmsg=$keepmsg"; it has been remotely deleted from '$ORIGIN'" 646 elif git_remote_branch_exists "$ORIGIN/$BRANCH"; then 647 keepmsg=$keepmsg"; it is still remotely available on '$ORIGIN'" 648 fi 649 else 650 keepmsg="is still locally available" 651 if git_remote_branch_exists "$ORIGIN/$BRANCH"; then 652 keepmsg=$keepmsg"; it is still remotely available on '$ORIGIN'" 653 fi 654 fi 655 echo "- Hotfix branch '$BRANCH' "$keepmsg 656 if flag push; then 657 if [ "$BASE_BRANCH" = "$MASTER_BRANCH" ]; then 658 echo "- '$DEVELOP_BRANCH', '$BASE_BRANCH' and tags have been pushed to '$ORIGIN'" 659 else 660 echo "- '$BASE_BRANCH' and tags have been pushed to '$ORIGIN'" 661 fi 662 fi 663 echo "- You are now on branch '$(git_current_branch)'" 664 echo 665 666} 667 668cmd_delete() { 669 OPTIONS_SPEC="\ 670git flow hotfix delete [-h] [-f] [-r] <name> 671 672Delete the given hotfix branch 673-- 674h,help! Show this help 675showcommands! Show git commands while executing them 676f,[no]force Force deletion 677r,[no]remote Delete remote branch 678" 679 local current_branch 680 681 # Define flags 682 DEFINE_boolean 'force' false "force deletion" f 683 DEFINE_boolean 'remote' false "delete remote branch" r 684 685 # Override defaults with values from config 686 gitflow_override_flag_boolean "hotfix.delete.force" "force" 687 gitflow_override_flag_boolean "hotfix.finish.remote" "remote" 688 689 # Parse arguments 690 parse_args "$@" 691 692 gitflow_require_version_arg 693 694 # Sanity checks 695 require_branch "$BRANCH" 696 697 run_pre_hook "$VERSION" "$ORIGIN" "$BRANCH" 698 699 current_branch=$(git_current_branch) 700 # We can't delete a branch we are on, switch to the master branch. 701 if [ "$BRANCH" = "$current_branch" ]; then 702 require_clean_working_tree 703 git_do checkout "$MASTER_BRANCH" || die "Could not check out branch '$MASTER_BRANCH'." 704 fi 705 706 if ( git_is_branch_merged_into "$BRANCH" "$MASTER_BRANCH" && git_is_branch_merged_into "$BRANCH" "$DEVELOP_BRANCH" ); then 707 git_do branch -d "$BRANCH" || die "Could not delete the $BRANCH." 708 if flag remote; then 709 git_remote_branch_delete "$BRANCH" 710 fi 711 else 712 if flag force; then 713 git_do branch -D "$BRANCH" || die "Could not delete the $BRANCH." 714 if flag remote; then 715 git_remote_branch_delete "$BRANCH" 716 fi 717 else 718 die "Hotfix branch '$BRANCH' has been not been merged in branch '$MASTER_BRANCH' and/or branch '$DEVELOP_BRANCH'. Use -f to force the deletion." 719 fi 720 fi 721 722 gitflow_config_remove_base_section "$BRANCH" 723 run_post_hook "$VERSION" "$ORIGIN" "$BRANCH" 724 725 echo 726 echo "Summary of actions:" 727 echo "- Hotfix branch '$BRANCH' has been deleted." 728 flag remote && echo "- Hotfix branch '$BRANCH' in '$ORIGIN' has been deleted." 729 echo "- You are now on branch '$(git_current_branch)'" 730 echo 731} 732 733cmd_rename() { 734 OPTIONS_SPEC="\ 735git flow hotfix rename <new_name> [<new_name>] 736 737Rename a given hotfix branch 738-- 739h,help! Show this help 740showcommands! Show git commands while executing them 741" 742 gitflow_rename_branch "$@" 743} 744