# $Id$ # vim:et:ft=sh:sts=2:sw=2 # # git-flow -- A collection of Git extensions to provide high-level # repository operations for Vincent Driessen's branching model. # # A blog post presenting this model is found at: # http://blog.avirtualhome.com/development-workflow-using-git/ # # Feel free to contribute to this project at: # http://github.com/petervanderdoes/gitflow # # Authors: # Copyright 2012-2019 Peter van der Does. All rights reserved. # # Original Author: # Copyright 2010 Vincent Driessen. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # initialize() { require_git_repo require_gitflow_initialized git config --get gitflow.prefix.hotfix >/dev/null 2>&1 || die "Hotfix prefix not set. Please run 'git flow init'." gitflow_load_settings VERSION_PREFIX=$(git config --get gitflow.prefix.versiontag) PREFIX=$(git config --get gitflow.prefix.hotfix) } usage() { OPTIONS_SPEC="\ git flow hotfix [list] git flow hotfix start git flow hotfix finish git flow hotfix publish git flow hotfix delete Manage your hotfix branches. For more specific help type the command followed by --help -- " flags_help } cmd_default() { cmd_list "$@" } cmd_list() { OPTIONS_SPEC="\ git flow hotfix [list] [-h] [-v] Lists all local hotfix branches -- h,help! Show this help v,verbose! Verbose (more) output " local hotfix_branches current_branch width branch len local base master_sha branch_sha # Define flags DEFINE_boolean 'verbose' false 'verbose (more) output' v # Parse arguments parse_args "$@" hotfix_branches=$(git_local_branches_prefixed "$PREFIX") if [ -z "$hotfix_branches" ]; then warn "No hotfix branches exist." warn "" warn "You can start a new hotfix branch:" warn "" warn " git flow hotfix start []" warn "" exit 0 fi current_branch=$(git_current_branch) # Determine column width first width=0 for branch in $hotfix_branches; do len=${#branch} width=$(max $width $len) done width=$(($width+3-${#PREFIX})) for branch in $hotfix_branches; do base=$(git merge-base "$branch" "$MASTER_BRANCH") master_sha=$(git rev-parse "$MASTER_BRANCH") branch_sha=$(git rev-parse "$branch") if [ "$branch" = "$current_branch" ]; then printf "* " else printf " " fi if flag verbose; then printf "%-${width}s" "${branch#$PREFIX}" if [ "$branch_sha" = "$master_sha" ]; then printf "(no commits yet)" else local tagname=$(git name-rev --tags --no-undefined --name-only "$base") local nicename if [ "$tagname" != "" ]; then nicename=$tagname else nicename=$(git rev-parse --short "$base") fi printf "(based on $nicename)" fi else printf "%s" "${branch#$PREFIX}" fi echo done } cmd_help() { usage exit 0 } # Parse arguments and set common variables parse_args() { FLAGS "$@" || exit $? eval set -- "${FLAGS_ARGV}" # Read arguments into global variables if [ -z $1 ]; then VERSION='' else VERSION=$1 fi BRANCH=$PREFIX$VERSION } require_no_existing_hotfix_branches() { local hotfix_branches first_branch hotfix_branches=$(git_local_branches_prefixed "$PREFIX") first_branch=$(echo ${hotfix_branches} | head -n1) first_branch=${first_branch#$PREFIX} [ -z "$hotfix_branches" ] || die "There is an existing hotfix branch '$first_branch'. Finish that one first." } cmd_start() { OPTIONS_SPEC="\ git flow hotfix start [-h] [-F] [] Start new hotfix branch named , optionally base it on instead of the branch -- h,help! Show this help showcommands! Show git commands while executing them F,[no]fetch Fetch from origin before performing local operation " local base # Define flags DEFINE_boolean 'fetch' false "fetch from $ORIGIN before performing finish" F # Override defaults with values from config gitflow_override_flag_boolean "hotfix.start.fetch" "fetch" # Parse arguments parse_args "$@" eval set -- "${FLAGS_ARGV}" base=${2:-$MASTER_BRANCH} # No need to continue if not clean require_base_is_local_branch "$base" git_config_bool_exists "gitflow.allowdirty" || require_clean_working_tree # Update the local repo with remote changes, if asked if flag fetch; then git_fetch_branch "$ORIGIN" "$base" fi # Run filter on the version VERSION=$(run_filter_hook hotfix-start-version $VERSION) if [ $? -eq 127 ]; then die $VERSION fi # As VERSION might have changed reset BRANCH with new VERSION BRANCH=$PREFIX$VERSION gitflow_require_version_arg if ! $(git config --bool --get gitflow.multi-hotfix 2>&1); then require_no_existing_hotfix_branches fi # Sanity checks require_branch_absent "$BRANCH" require_tag_absent "$VERSION_PREFIX$VERSION" if git_remote_branch_exists "$ORIGIN/$base"; then require_branches_equal "$base" "$ORIGIN/$base" fi run_pre_hook "$VERSION_PREFIX$VERSION" "$ORIGIN" "$BRANCH" "$base" gitflow_config_set_base_branch $base $BRANCH # Create branch git_do checkout -b "$BRANCH" "$base" || die "Could not create hotfix branch '$BRANCH'." run_post_hook "$VERSION_PREFIX$VERSION" "$ORIGIN" "$BRANCH" "$base" echo echo "Summary of actions:" echo "- A new branch '$BRANCH' was created, based on '$base'" echo "- You are now on branch '$(git_current_branch)'" echo echo "Follow-up actions:" echo "- Start committing your hot fixes" echo "- Bump the version number now!" echo "- When done, run:" echo echo " git flow hotfix finish '$VERSION'" echo } cmd_publish() { OPTIONS_SPEC="\ git flow hotfix publish [-h] Start sharing hotfix on $ORIGIN -- h,help! Show this help showcommands! Show git commands while executing them " # Parse arguments parse_args "$@" # Use current branch if no version is given if [ "$VERSION" = "" ]; then gitflow_use_current_branch_version fi # Sanity checks require_clean_working_tree require_branch "$BRANCH" git_do fetch -q "$ORIGIN" || die "Could not fetch branch '$BRANCH' from remote '$ORIGIN'." require_branch_absent "$ORIGIN/$BRANCH" run_pre_hook "$VERSION_PREFIX$VERSION" "$ORIGIN" "$BRANCH" # Create remote branch with remote tracking git_do push -u "$ORIGIN" "$BRANCH:$BRANCH" git_do fetch -q "$ORIGIN" "$BRANCH" || die "Could not fetch branch '$BRANCH' from remote '$ORIGIN'." git_do checkout "$BRANCH" || die "Could not check out branch '$BRANCH'." run_post_hook "$VERSION_PREFIX$VERSION" "$ORIGIN" "$BRANCH" echo echo "Summary of actions:" echo "- The remote branch '$BRANCH' was created or updated" echo "- The local branch '$BRANCH' was configured to track the remote branch" echo "- You are now on branch '$(git_current_branch)'" echo } cmd_rebase() { OPTIONS_SPEC="\ git flow hotfix rebase [-h] [-i] [-p] [] Rebase on -- h,help! Show this help showcommands! Show git commands while executing them i,[no]interactive Do an interactive rebase p,[no]preserve-merges Preserve merges " local opts # Define flags DEFINE_boolean 'interactive' false 'do an interactive rebase' i DEFINE_boolean 'preserve-merges' false 'try to recreate merges' p # Override defaults with values from config gitflow_override_flag_boolean "hotfix.rebase.interactive" "interactive" gitflow_override_flag_boolean "hotfix.rebase.preserve-merges" "preserve_merges" # Parse arguments parse_args "$@" # Use current branch if no version is given if [ "$VERSION" = "" ]; then gitflow_use_current_branch_version fi BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH) BASE_BRANCH=${BASE_BRANCH:-$DEVELOP_BRANCH} warn "Will try to rebase '$NAME' which is based on '$BASE_BRANCH'..." if ! git_config_bool_exists "rebase.autostash"; then require_clean_working_tree fi require_branch "$BRANCH" 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'." git_do checkout -q "$BRANCH" || die "Could not check out branch '$BRANCH'." if flag interactive; then opts="$opts -i" fi if flag preserve_merges; then opts="$opts -p" fi git_do rebase $opts "$BASE_BRANCH" } cmd_track() { OPTIONS_SPEC="\ git flow hotfix track [-h] Create a tracking hotfix branch from $ORIGIN -- h,help! Show this help showcommands! Show git commands while executing them " # Parse arguments parse_args "$@" gitflow_require_version_arg # Sanity checks require_clean_working_tree require_branch_absent "$BRANCH" git_do fetch -q "$ORIGIN" require_branch "$ORIGIN/$BRANCH" # Create tracking branch git_do checkout -b "$BRANCH" "$ORIGIN/$BRANCH" echo echo "Summary of actions:" echo "- A new remote tracking branch '$BRANCH' was created" echo "- You are now on branch '$BRANCH'" echo } cmd_finish() { OPTIONS_SPEC="\ git flow hotfix finish [-h] [-F] [-s] [-u] [-m | -f ] [-p] [-k] [-n] [-b] [-S] Finish hotfix branch -- h,help! Show this help showcommands! Show git commands while executing them F,[no]fetch Fetch from origin before performing finish s,[no]sign Sign the release tag cryptographically u,[no]signingkey Use the given GPG-key for the digital signature (implies -s) m,[no]message Use the given tag message f,[no]messagefile= Use the contents of the given file as tag message p,[no]push Push to origin after performing finish k,[no]keep Keep branch after performing finish [no]keepremote Keep the remote branch [no]keeplocal Keep the local branch D,[no]force_delete Force delete hotfix branch after finish n,[no]notag Don't tag this hotfix b,[no]nobackmerge Don't back-merge master, or tag if applicable, in develop S,[no]squash Squash hotfix during merge T,tagname! Use given tag name " local opts commit keepmsg remotebranchdeleted localbranchdeleted # Define flags DEFINE_boolean 'fetch' false "fetch from $ORIGIN before performing finish" F DEFINE_boolean 'sign' false "sign the release tag cryptographically" s DEFINE_string 'signingkey' "" "use the given GPG-key for the digital signature (implies -s)" u DEFINE_string 'message' "" "use the given tag message" m DEFINE_string 'messagefile' "" "use the contents of the given file as tag message" f DEFINE_boolean 'push' false "push to $ORIGIN after performing finish" p DEFINE_boolean 'keep' false "keep branch after performing finish" k DEFINE_boolean 'keepremote' false "keep the remote branch" DEFINE_boolean 'keeplocal' false "keep the local branch" DEFINE_boolean 'force_delete' false "force delete hotfix branch after finish" D DEFINE_boolean 'notag' false "don't tag this hotfix" n DEFINE_boolean 'nobackmerge' false "don't back-merge $MASTER_BRANCH, or tag if applicable, in $DEVELOP_BRANCH " b DEFINE_boolean 'squash' false "squash release during merge" S DEFINE_boolean 'squash-info' false "add branch info during squash" DEFINE_string 'tagname' "" "use the given tag name" T # Override defaults with values from config gitflow_override_flag_boolean "hotfix.finish.fetch" "fetch" gitflow_override_flag_boolean "hotfix.finish.sign" "sign" gitflow_override_flag_boolean "hotfix.finish.push" "push" gitflow_override_flag_boolean "hotfix.finish.keep" "keep" gitflow_override_flag_boolean "hotfix.finish.keepremote" "keepremote" gitflow_override_flag_boolean "hotfix.finish.keeplocal" "keeplocal" gitflow_override_flag_boolean "hotfix.finish.force-delete" "force_delete" gitflow_override_flag_boolean "hotfix.finish.notag" "notag" gitflow_override_flag_boolean "hotfix.finish.nobackmerge" "nobackmerge" gitflow_override_flag_boolean "hotfix.finish.squash" "squash" gitflow_override_flag_boolean "hotfix.finish.squash-info" "squash_info" gitflow_override_flag_string "hotfix.finish.signingkey" "signingkey" gitflow_override_flag_string "hotfix.finish.message" "message" gitflow_override_flag_string "hotfix.finish.messagefile" "messagefile" # Parse arguments parse_args "$@" # Use current branch if no version is given if [ "$VERSION" = "" ]; then gitflow_use_current_branch_version fi # Use branch name if no tag name is given if [ "$FLAGS_tagname" != "" ]; then TAGNAME=$FLAGS_tagname else TAGNAME=$VERSION fi remotebranchdeleted=$FLAGS_FALSE localbranchdeleted=$FLAGS_FALSE # Handle flags that imply other flags if [ "$FLAGS_signingkey" != "" ]; then FLAGS_sign=$FLAGS_TRUE fi # Keeping both branches implies the --keep flag to be true. if flag keepremote && flag keeplocal; then FLAGS_keep=$FLAGS_TRUE fi # Sanity checks require_branch "$BRANCH" require_clean_working_tree BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH) BASE_BRANCH=${BASE_BRANCH:-$MASTER_BRANCH} 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'." # We always fetch the Branch from Origin # This is done to avoid possible commits on the remote that are not # merged into the local branch if git_remote_branch_exists "$ORIGIN/$BRANCH"; then git_fetch_branch "$ORIGIN" "$BRANCH" fi # Update local branches with remote branches if flag fetch; then git_fetch_branch "$ORIGIN" "$BASE_BRANCH" [ "$BASE_BRANCH" = "$MASTER_BRANCH" ] && git_fetch_branch "$ORIGIN" "$DEVELOP_BRANCH" fi # Check if the local branches have all the commits from the remote branches if git_remote_branch_exists "$ORIGIN/$BRANCH"; then require_branches_equal "$BRANCH" "$ORIGIN/$BRANCH" fi if git_remote_branch_exists "$ORIGIN/$BASE_BRANCH"; then require_branches_equal "$BASE_BRANCH" "$ORIGIN/$BASE_BRANCH" fi if [ "$BASE_BRANCH" = "$MASTER_BRANCH" ]; then if git_remote_branch_exists "$ORIGIN/$DEVELOP_BRANCH"; then require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH" fi fi # If the branch is already merged there is no need to check the hotfix branch # This can happen when the merge in develop fails and we rerun the finish. if ! git_is_branch_merged_into "$BRANCH" "$BASE_BRANCH"; then # Check if the hotfix branch: # - has commits: No reason to finish a hotfix without commits # - Is ahead of the BASE: If it's not a good idea to merge # - Can be merged: If there's no common ancestor we can't merge the hotfix git_compare_refs "$BRANCH" "$BASE_BRANCH" case $? in 0) die "You need some commits in the hotfix branch '$BRANCH'" ;; 1) die "The hotfix branch '$BRANCH' is not ahead of branch '$BASE_BRANCH'" ;; 4) die "The hotfix branch '$BRANCH' has no common ancestor with branch '$BASE_BRANCH'" ;; *) ;; esac fi if noflag notag; then # We ask for a tag, be sure it does not exists or # points to the latest hotfix commit if git_tag_exists "$VERSION_PREFIX$TAGNAME"; then git_compare_refs "$BRANCH" "$VERSION_PREFIX$TAGNAME"^2 2>/dev/null [ $? -eq 0 ] || die "Tag already exists and does not point to hotfix branch '$BRANCH'" fi fi run_pre_hook "$VERSION_PREFIX$TAGNAME" "$ORIGIN" "$BRANCH" # Try to merge into BASE. # In case a previous attempt to finish this release branch has failed, # but the merge into BASE was successful, we skip it now if ! git_is_branch_merged_into "$BRANCH" "$BASE_BRANCH"; then git_do checkout "$BASE_BRANCH" || die "Could not check out branch '$BASE_BRANCH'." if noflag squash; then git_do merge --no-ff "$BRANCH" || die "There were merge conflicts." # TODO: What do we do now? else git_do merge --squash "$BRANCH" || die "There were merge conflicts." # TODO: What do we do now? flag squash_info && gitflow_create_squash_message "Merged hotfix branch '$BRANCH'" "$BASE_BRANCH" "$BRANCH" > "$DOT_GIT_DIR/SQUASH_MSG" git_do commit fi fi if noflag notag; then # Try to tag the release. # In case a previous attempt to finish this release branch has failed, # but the tag was set successful, we skip it now if ! git_tag_exists "$VERSION_PREFIX$TAGNAME"; then if [ "$FLAGS_message" != "" ] && [ "$FLAGS_messagefile" != "" ]; then die "Use either -m,--message or -f,--messagefile. Can not use both options at the same time" fi opts="-a" flag sign && opts="$opts -s" [ "$FLAGS_signingkey" != "" ] && opts="$opts -u '$FLAGS_signingkey'" if [ "$FLAGS_message" != "" ]; then # Run filter on the tag message FLAGS_message=$(run_filter_hook hotfix-finish-tag-message "${FLAGS_message}" "$VERSION_PREFIX$TAGNAME") opts="$opts -m '$FLAGS_message'" fi [ "$FLAGS_messagefile" != "" ] && opts="$opts -F '$FLAGS_messagefile'" eval git_do tag $opts "$VERSION_PREFIX$TAGNAME" || die "Tagging failed. Please run finish again to retry." fi fi if [ "$BASE_BRANCH" = "$MASTER_BRANCH" ]; then # By default we back-merge the $MASTER_BRANCH unless the user explicitly # stated not to do a back-merge, in that case we use the $BRANCH. if noflag nobackmerge; then MERGE_BRANCH="$BASE_BRANCH" else MERGE_BRANCH="$BRANCH" fi # Try to merge into develop. # In case a previous attempt to finish this release branch has failed, # but the merge into develop was successful, we skip it now if ! git_is_branch_merged_into "$MERGE_BRANCH" "$DEVELOP_BRANCH"; then git_do checkout "$DEVELOP_BRANCH" || die "Could not check out branch '$DEVELOP_BRANCH'." if noflag nobackmerge; then # Accounting for 'git describe', if a release is tagged # we use the tag commit instead of the branch. if noflag notag; then commit="$VERSION_PREFIX$TAGNAME" else commit="$BASE_BRANCH" fi else commit="$BRANCH" fi git_do merge --no-ff "$commit" || die "There were merge conflicts." # TODO: What do we do now? fi fi run_post_hook "$VERSION_PREFIX$TAGNAME" "$ORIGIN" "$BRANCH" if flag push; then if [ "$BASE_BRANCH" = "$MASTER_BRANCH" ]; then git_do push "$ORIGIN" "$DEVELOP_BRANCH" || die "Could not push branch '$DEVELOP_BRANCH' to remote '$ORIGIN'." fi git_do push "$ORIGIN" "$BASE_BRANCH" || die "Could not push branch '$BASE_BRANCH' to remote '$ORIGIN'." if noflag notag; then git_do push --tags "$ORIGIN" || die "Could not push tags to remote '$ORIGIN'." fi fi # Delete branch if noflag keep; then # Always delete remote first if noflag keepremote;then if git_remote_branch_exists "$ORIGIN/$BRANCH"; then git_remote_branch_delete "$BRANCH" && remotebranchdeleted=$FLAGS_TRUE fi fi # Delete local after remote to avoid warnings if noflag keeplocal; then if [ "$BRANCH" = "$(git_current_branch)" ]; then git_do checkout "$DEVELOP_BRANCH" || die "Could not check out branch '$DEVELOP_BRANCH'." fi if flag force_delete; then git_do branch -D "$BRANCH" && localbranchdeleted=$FLAGS_TRUE else git_do branch -d "$BRANCH" && localbranchdeleted=$FLAGS_TRUE fi fi # no more branches: we can safely remove config section if ! git_remote_branch_exists "$ORIGIN/$BRANCH" -a ! git_local_branch_exists "$BRANCH"; then gitflow_config_remove_base_section "$BRANCH" fi fi echo echo "Summary of actions:" if flag fetch; then echo "- Latest objects have been fetched from '$ORIGIN'" fi echo "- Hotfix branch '$BRANCH' has been merged into '$BASE_BRANCH'" if noflag notag; then echo "- The hotfix was tagged '$VERSION_PREFIX$TAGNAME'" fi if [ "$BASE_BRANCH" = "$MASTER_BRANCH" ]; then [ "$commit" = "$BASE_BRANCH" ] && echo "- Master branch '$BASE_BRANCH' has been back-merged into '$DEVELOP_BRANCH'" [ "$commit" = "$VERSION_PREFIX$TAGNAME" ] && echo "- Hotfix tag '$VERSION_PREFIX$TAGNAME' has been back-merged into '$DEVELOP_BRANCH'" [ "$commit" = "$BRANCH" ] && echo "- Hotfix branch '$BRANCH' has been merged into '$DEVELOP_BRANCH'" fi if noflag keep; then if [ $localbranchdeleted -eq $FLAGS_TRUE ]; then keepmsg="has been locally deleted" else keepmsg="is still locally available" fi if [ $remotebranchdeleted -eq $FLAGS_TRUE ]; then keepmsg=$keepmsg"; it has been remotely deleted from '$ORIGIN'" elif git_remote_branch_exists "$ORIGIN/$BRANCH"; then keepmsg=$keepmsg"; it is still remotely available on '$ORIGIN'" fi else keepmsg="is still locally available" if git_remote_branch_exists "$ORIGIN/$BRANCH"; then keepmsg=$keepmsg"; it is still remotely available on '$ORIGIN'" fi fi echo "- Hotfix branch '$BRANCH' "$keepmsg if flag push; then if [ "$BASE_BRANCH" = "$MASTER_BRANCH" ]; then echo "- '$DEVELOP_BRANCH', '$BASE_BRANCH' and tags have been pushed to '$ORIGIN'" else echo "- '$BASE_BRANCH' and tags have been pushed to '$ORIGIN'" fi fi echo "- You are now on branch '$(git_current_branch)'" echo } cmd_delete() { OPTIONS_SPEC="\ git flow hotfix delete [-h] [-f] [-r] Delete the given hotfix branch -- h,help! Show this help showcommands! Show git commands while executing them f,[no]force Force deletion r,[no]remote Delete remote branch " local current_branch # Define flags DEFINE_boolean 'force' false "force deletion" f DEFINE_boolean 'remote' false "delete remote branch" r # Override defaults with values from config gitflow_override_flag_boolean "hotfix.delete.force" "force" gitflow_override_flag_boolean "hotfix.finish.remote" "remote" # Parse arguments parse_args "$@" gitflow_require_version_arg # Sanity checks require_branch "$BRANCH" run_pre_hook "$VERSION" "$ORIGIN" "$BRANCH" current_branch=$(git_current_branch) # We can't delete a branch we are on, switch to the master branch. if [ "$BRANCH" = "$current_branch" ]; then require_clean_working_tree git_do checkout "$MASTER_BRANCH" || die "Could not check out branch '$MASTER_BRANCH'." fi if ( git_is_branch_merged_into "$BRANCH" "$MASTER_BRANCH" && git_is_branch_merged_into "$BRANCH" "$DEVELOP_BRANCH" ); then git_do branch -d "$BRANCH" || die "Could not delete the $BRANCH." if flag remote; then git_remote_branch_delete "$BRANCH" fi else if flag force; then git_do branch -D "$BRANCH" || die "Could not delete the $BRANCH." if flag remote; then git_remote_branch_delete "$BRANCH" fi else die "Hotfix branch '$BRANCH' has been not been merged in branch '$MASTER_BRANCH' and/or branch '$DEVELOP_BRANCH'. Use -f to force the deletion." fi fi gitflow_config_remove_base_section "$BRANCH" run_post_hook "$VERSION" "$ORIGIN" "$BRANCH" echo echo "Summary of actions:" echo "- Hotfix branch '$BRANCH' has been deleted." flag remote && echo "- Hotfix branch '$BRANCH' in '$ORIGIN' has been deleted." echo "- You are now on branch '$(git_current_branch)'" echo } cmd_rename() { OPTIONS_SPEC="\ git flow hotfix rename [] Rename a given hotfix branch -- h,help! Show this help showcommands! Show git commands while executing them " gitflow_rename_branch "$@" }