diff --git a/git-flow-release b/git-flow-release index e61b4612..2daed24a 100644 --- a/git-flow-release +++ b/git-flow-release @@ -43,7 +43,7 @@ # _finish_from_develop() { local opts merge_branch commit keepmsg remotebranchdeleted localbranchdeleted compare_refs_result merge_result - + remotebranchdeleted=$FLAGS_FALSE localbranchdeleted=$FLAGS_FALSE @@ -439,6 +439,7 @@ git flow release publish git flow release track git flow release rebase git flow release delete +git flow release create Manage your release branches. @@ -548,6 +549,197 @@ require_no_existing_release_branches() { [ -z "$release_branches" ] || die "There is an existing release branch '$first_branch'. Finish that one first." } +cmd_create() { + OPTIONS_SPEC="\ +git flow release create [options] [] + +Create a new release branch +-- +h,help Show this help +showcommands! Show git commands while executing them +F,[no]fetch Fetch from origin before performing finish +s,sign! Sign the release tag cryptographically +u,signingkey! Use the given GPG-key for the digital signature (implies -s) +m,message! Use the given tag message +f,[no]messagefile= Use the contents of the given file as a tag message +p,[no]push Push to origin after performing finish +[no]pushproduction Push the production branch +[no]pushdevelop Push the develop branch +[no]pushtag Push the tag +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 release branch after finish +n,[no]tag Don't tag this release +b,[no]nobackmerge Don't back-merge master, or tag if applicable, in develop +S,[no]squash Squash release during merge +[no]ff-master Fast forward master branch if possible +e,[no]edit The --noedit option can be used to accept the auto-generated message on merging +T,tagname! Use given tag name +nodevelopmerge! Don't back-merge develop branch +" + + local base + + # 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 a tag message" f + DEFINE_boolean 'push' false "push to $ORIGIN after performing finish" p + DEFINE_boolean 'pushproduction' false "push the production branch" + DEFINE_boolean 'pushdevelop' false "push the develop branch" + DEFINE_boolean 'pushtag' false "push the tag" + 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 release branch after finish" D + DEFINE_boolean 'notag' false "don't tag this release" 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_boolean 'ff-master' false "fast forward master branch if possible" + DEFINE_boolean 'edit' true "accept the auto-generated message on merging" e + DEFINE_string 'tagname' "" "use the given tag name" T + DEFINE_boolean 'nodevelopmerge' false "don't merge $BRANCH into $DEVELOP_BRANCH " + + # Override defaults with values from config + gitflow_override_flag_boolean "release.finish.fetch" "fetch" + gitflow_override_flag_boolean "release.finish.sign" "sign" + gitflow_override_flag_boolean "release.finish.push" "push" + gitflow_override_flag_boolean "release.finish.pushproduction" "pushproduction" + gitflow_override_flag_boolean "release.finish.pushdevelop" "pushdevelop" + gitflow_override_flag_boolean "release.finish.pushtag" "pushtag" + gitflow_override_flag_boolean "release.finish.keep" "keep" + gitflow_override_flag_boolean "release.finish.keepremote" "keepremote" + gitflow_override_flag_boolean "release.finish.keeplocal" "keeplocal" + gitflow_override_flag_boolean "release.finish.force-delete" "force_delete" + gitflow_override_flag_boolean "release.finish.notag" "notag" + gitflow_override_flag_boolean "release.finish.nobackmerge" "nobackmerge" + gitflow_override_flag_boolean "release.finish.squash" "squash" + gitflow_override_flag_boolean "release.finish.squash-info" "squash_info" + gitflow_override_flag_boolean "release.finish.ff-master" "ff-master" + gitflow_override_flag_string "release.finish.signingkey" "signingkey" + gitflow_override_flag_string "release.finish.message" "message" + gitflow_override_flag_string "release.finish.messagefile" "messagefile" + gitflow_override_flag_boolean "release.finish.nodevelopmerge" "nodevelopmerge" + + + + parse_args "$@" + eval set -- "${FLAGS_ARGV}" + + base=${2:-$DEVELOP_BRANCH} +# Run filter on the version + VERSION=$(run_filter_hook create-start-version $VERSION) + if [ $? -eq 127 ]; then + die $VERSION + fi + + # As VERSION might have changed reset BRANCH with new VERSION + BRANCH=$PREFIX$VERSION + + require_base_is_local_branch "$base" + gitflow_require_version_arg + + require_no_existing_release_branches + + # Sanity checks + git_config_bool_exists "gitflow.allowdirty" || require_clean_working_tree + require_branch_absent "$BRANCH" + require_tag_absent "$VERSION_PREFIX$VERSION" + if flag fetch; then + git_fetch_branch "$ORIGIN" "$base" + fi + 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 release 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 "- Bump the version number now!" + echo "- Start committing last-minute fixes in preparing your release" + echo "- When done, run:" + echo + echo " git flow release finish '$VERSION'" + echo + # Run filter on the version + VERSION=$(run_filter_hook create-finish-version $VERSION) + if [ $? -eq 127 ]; then + die $VERSION + fi + + # Use branch name if no tag name is given + if [ "$FLAGS_tagname" != "" ]; then + TAGNAME=$FLAGS_tagname + else + TAGNAME=$VERSION + fi + + # As VERSION might have changed reset BRANCH with new VERSION + BRANCH=$PREFIX$VERSION + + BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH) + BASE_BRANCH=${BASE_BRANCH:-$DEVELOP_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 release branch '$BRANCH'." + + # 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 + + # Pushing implies we push all. + if flag push; then + FLAGS_pushproduction=$FLAGS_TRUE + FLAGS_pushdevelop=$FLAGS_TRUE + FLAGS_pushtag=$FLAGS_TRUE + fi + # If we push either of these it means we need to do a push + if flag pushproduction || flag pushdevelop || flag pushtag; then + FLAGS_push=$FLAGS_TRUE + fi + + # Sanity checks + require_branch "$BRANCH" + require_clean_working_tree + + # 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 + + if [ "$BASE_BRANCH" = "$DEVELOP_BRANCH" ]; then + SUBCOMMAND="create" + SUBACTION="finish" + _finish_from_develop + else + SUBCOMMAND="create" + SUBACTION="finish" + _finish_base + fi +} + cmd_start() { OPTIONS_SPEC="\ git flow release start [options] [] diff --git a/hooks/filter-flow-create-finish-version b/hooks/filter-flow-create-finish-version new file mode 100644 index 00000000..0169fb70 --- /dev/null +++ b/hooks/filter-flow-create-finish-version @@ -0,0 +1,22 @@ +#!/bin/sh +# +# Runs during git flow release create finish +# +# Positional arguments: +# $1 Version +# +# Return VERSION - When VERSION is returned empty, git-flow will stop as the +# version is necessary +# +# The following variables are available as they are exported by git-flow: +# +# MASTER_BRANCH - The branch defined as Master +# DEVELOP_BRANCH - The branch defined as Develop +# +VERSION=$1 + +# Implement your script here. + +# Return the VERSION +echo ${VERSION} +exit 0 diff --git a/hooks/filter-flow-create-start-version b/hooks/filter-flow-create-start-version new file mode 100644 index 00000000..885603e5 --- /dev/null +++ b/hooks/filter-flow-create-start-version @@ -0,0 +1,22 @@ +#!/bin/sh +# +# Runs during git flow release create start +# +# Positional arguments: +# $1 Version +# +# Return VERSION - When VERSION is returned empty, git-flow will stop as the +# version is necessary +# +# The following variables are available as they are exported by git-flow: +# +# MASTER_BRANCH - The branch defined as Master +# DEVELOP_BRANCH - The branch defined as Develop +# +VERSION=$1 + +# Implement your script here. + +# Return the VERSION +echo ${VERSION} +exit 0 diff --git a/hooks/filter-flow-release-finish-version b/hooks/filter-flow-release-finish-version new file mode 100644 index 00000000..987ca8a4 --- /dev/null +++ b/hooks/filter-flow-release-finish-version @@ -0,0 +1,22 @@ +#!/bin/sh +# +# Runs during git flow release finish +# +# Positional arguments: +# $1 Version +# +# Return VERSION - When VERSION is returned empty, git-flow will stop as the +# version is necessary +# +# The following variables are available as they are exported by git-flow: +# +# MASTER_BRANCH - The branch defined as Master +# DEVELOP_BRANCH - The branch defined as Develop +# +VERSION=$1 + +# Implement your script here. + +# Return the VERSION +echo ${VERSION} +exit 0 diff --git a/hooks/post-flow-create-finish b/hooks/post-flow-create-finish new file mode 100755 index 00000000..be85ea7f --- /dev/null +++ b/hooks/post-flow-create-finish @@ -0,0 +1,21 @@ +#!/bin/sh +# +# Runs at the end of git flow release create finish +# +# Positional arguments: +# $1 The version (including the version prefix) +# $2 The origin remote +# $3 The full branch name (including the release prefix) +# +# The following variables are available as they are exported by git-flow: +# +# MASTER_BRANCH - The branch defined as Master +# DEVELOP_BRANCH - The branch defined as Develop +# +VERSION=$1 +ORIGIN=$2 +BRANCH=$3 + +# Implement your script here. + +exit 0 diff --git a/hooks/post-flow-release-create b/hooks/post-flow-release-create new file mode 100755 index 00000000..42c9034e --- /dev/null +++ b/hooks/post-flow-release-create @@ -0,0 +1,23 @@ +#!/bin/sh +# +# Runs at the end of git flow release create start +# +# Positional arguments: +# $1 The version (including the version prefix) +# $2 The origin remote +# $3 The full branch name (including the release prefix) +# $4 The base from which this release is started +# +# The following variables are available as they are exported by git-flow: +# +# MASTER_BRANCH - The branch defined as Master +# DEVELOP_BRANCH - The branch defined as Develop +# +VERSION=$1 +ORIGIN=$2 +BRANCH=$3 +BASE=$4 + +# Implement your script here. + +exit 0 diff --git a/hooks/pre-flow-create-finish b/hooks/pre-flow-create-finish new file mode 100755 index 00000000..cebf8ab9 --- /dev/null +++ b/hooks/pre-flow-create-finish @@ -0,0 +1,22 @@ +#!/bin/sh +# +# Runs before git flow release create finish +# +# Positional arguments: +# $1 The version (including the version prefix) +# $2 The origin remote +# $3 The full branch name (including the release prefix) +# +# The following variables are available as they are exported by git-flow: +# +# MASTER_BRANCH - The branch defined as Master +# DEVELOP_BRANCH - The branch defined as Develop +# +VERSION=$1 +ORIGIN=$2 +BRANCH=$3 + +# Implement your script here. + +# To terminate the git-flow action, return a non-zero exit code. +exit 0 diff --git a/hooks/pre-flow-release-create b/hooks/pre-flow-release-create new file mode 100755 index 00000000..5b2c1c4a --- /dev/null +++ b/hooks/pre-flow-release-create @@ -0,0 +1,24 @@ +#!/bin/sh +# +# Runs before git flow release create start +# +# Positional arguments: +# $1 The version (including the version prefix) +# $2 The origin remote +# $3 The full branch name (including the release prefix) +# $4 The base from which this release is started +# +# The following variables are available as they are exported by git-flow: +# +# MASTER_BRANCH - The branch defined as Master +# DEVELOP_BRANCH - The branch defined as Develop +# +VERSION=$1 +ORIGIN=$2 +BRANCH=$3 +BASE=$4 + +# Implement your script here. + +# To terminate the git-flow action, return a non-zero exit code. +exit 0