Skip to content

Commit

Permalink
feat: add cherrypick option to hotfix finish (#73)
Browse files Browse the repository at this point in the history
Allows for the commits that resolve the hotfix to be applied to the
develop branch instead of the entire hotfix branch. This option is not
compatible with the nobackmerge or releaseBackmerge flags.

The initial pull request provided by
[simonweil](https://github.com/simonweil)

closes #67
closes #37
closes petervanderdoes#164
closes petervanderdoes#165


Co-authored-by: simonweil  <[email protected]>
  • Loading branch information
ChrisJStone and simonweil authored Jul 6, 2023
1 parent 25c387c commit ca6828e
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 4 deletions.
59 changes: 55 additions & 4 deletions git-flow-hotfix
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ showcommands! Show git commands while executing them

cmd_finish() {
OPTIONS_SPEC="\
git flow hotfix finish [-h] [-F] [-s] [-u] [-m | -f ] [-p] [-k] [-n] [-b] [-S] <version>
git flow hotfix finish [-h] [-F] [-s] [-u] [-m | -f ] [-p] [-k] [-n] [-b | -c] [-S] <version>
Finish hotfix branch <version>
--
Expand All @@ -387,6 +387,7 @@ b,[no]nobackmerge Don't back-merge master, or tag if applicable, in develop
r,releaseBackmerge Back-merge to release branch if exists
S,[no]squash Squash hotfix during merge
T,tagname! Use given tag name
c,cherrypick Cherry Pick to $DEVELOP_BRANCH instead of merge
"
local opts commit keepmsg remotebranchdeleted localbranchdeleted

Expand All @@ -407,6 +408,7 @@ T,tagname! Use given tag name
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
DEFINE_boolean 'cherrypick' false "Cherry Pick to $DEVELOP_BRANCH instead of merge" c

# Override defaults with values from config
gitflow_override_flag_boolean "hotfix.finish.fetch" "fetch"
Expand All @@ -424,6 +426,7 @@ T,tagname! Use given tag name
gitflow_override_flag_string "hotfix.finish.signingkey" "signingkey"
gitflow_override_flag_string "hotfix.finish.message" "message"
gitflow_override_flag_string "hotfix.finish.messagefile" "messagefile"
gitflow_override_flag_boolean "hotfix.finish.cherrypick" "cherrypick"

# Parse arguments
parse_args "$@"
Expand Down Expand Up @@ -453,6 +456,15 @@ T,tagname! Use given tag name
FLAGS_keep=$FLAGS_TRUE
fi

# Check that not both no merge flags were given
if flag cherrypick && flag nobackmerge; then
die "You can't use 'cherrypick' and 'nobackmerge' together."
fi

if flag cherrypick && flag releasebackmerge; then
die "You can't use 'cherrypick' and 'releasebackmerge' together."
fi

# Sanity checks
require_branch "$BRANCH"
require_clean_working_tree
Expand Down Expand Up @@ -521,6 +533,42 @@ T,tagname! Use given tag name

run_pre_hook "$VERSION_PREFIX$TAGNAME" "$ORIGIN" "$BRANCH"

if flag cherrypick; then
printf 'this is the cherrypick\n'
read
git_do checkout "$DEVELOP_BRANCH" || die "Could not check out branch '$DEVELOP_BRANCH'."

local old_IFS=$IFS # save the field separator
IFS=$'\n' # new field separator, the end of line
for git_line in $(git log --format="%H %s" --reverse $MASTER_BRANCH..$BRANCH | grep -vE "^[a-z0-9]* Merge branch '[^'].*?'$"); do
local commit_hash=$(echo $git_line | cut -d" " -f1)
if [[ $(git log $DEVELOP_BRANCH --grep "$commit_hash" | wc -l) -eq 0 ]]; then
echo "\n${LIGHTGREEN}Cherry picking: $git_line${NOCOLOR}"
git_do cherry-pick -x -s $commit_hash
if [[ $? -ne 0 ]]; then
echo "
===============================================================
= Cherry pick has conflicts, steps to continue:
= 1. Fix the conflicts
= 2. Stage the fixed file: '${BLUE}git add <file names>${NOCOLOR}'
= 3. Continue the cherry pick: '${BLUE}git cherry-pick --continue${NOCOLOR}'
= *** If fixing the conflict results in an empty commit,
= you will need to run this command: '${BLUE}git commit --allow-empty${NOCOLOR}'
= 4. Switch back to the hotfix branch: '${BLUE}git checkout $BRANCH${NOCOLOR}'
= 5. Rerun the finish command: '${BLUE}git flow hotfix finish${NOCOLOR}'
= OR run '${BLUE}git cherry-pick --abort${NOCOLOR}' to abort the cherry pick
===============================================================\n"
die "Cherry pick failed for commit: $commit_hash"
fi
else
echo "\n${LIGHTGREEN}Commit has already been Cherry Picked: $git_line${NOCOLOR}"
fi
done
IFS=$old_IFS # restore default field separator

git_do checkout $BRANCH || die "Could not check out branch '$BRANCH'."
fi

# 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
Expand Down Expand Up @@ -556,7 +604,7 @@ T,tagname! Use given tag name
fi
fi

if [ "$BASE_BRANCH" = "$MASTER_BRANCH" ] && noflag nobackmerge; then
if [ "$BASE_BRANCH" = "$MASTER_BRANCH" ] && noflag nobackmerge && noflag cherrypick; then
# Try to merge into develop unless the user specified the nobackmerge option.
# In case a previous attempt to finish this release branch has failed,
# but the merge into develop was successful, we skip it now
Expand Down Expand Up @@ -660,12 +708,15 @@ T,tagname! Use given tag name
if noflag notag; then
echo "- The hotfix was tagged '$VERSION_PREFIX$TAGNAME'"
fi
if [ "$BASE_BRANCH" = "$MASTER_BRANCH" ]; then
if flag cherrypick; then
echo "- All commits from the hotfix branch have been cherry picked into '$DEVELOP_BRANCH'"
elif [ "$BASE_BRANCH" = "$MASTER_BRANCH" ]; then
[ "$commit" = "$BASE_BRANCH" ] && echo "- Master branch '$BASE_BRANCH' has been back-merged into '$DEVELOP_BRANCH'"
[ -n "$release_branch" ] && echo "- Hotfix tag '$VERSION_PREFIX$TAGNAME' has been back-merged into '$release_branch'"
[ "$commit" = "$VERSION_PREFIX$TAGNAME" ] && echo "- Hotfix tag '$VERSION_PREFIX$TAGNAME' has been back-merged into '$DEVELOP_BRANCH'"
[ "$commit" = "$VERSION_PREFIX$VERSION" ] && echo "- Hotfix tag '$VERSION_PREFIX$VERSION' 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"
Expand Down
19 changes: 19 additions & 0 deletions gitflow-common
Original file line number Diff line number Diff line change
Expand Up @@ -811,3 +811,22 @@ run_post_hook() {
flags_help() {
eval "$( echo "$OPTIONS_SPEC" | git rev-parse --parseopt -- "-h" || echo exit $? )"
}

#
# Color constants
#
echo_color_support() {
local echo_path=$(which echo)
local echo_out=$($echo_path -e)
if [[ $echo_out == "" ]]; then
alias echo="$echo_path -e "
BLUE="\e[34m"
LIGHTGREEN="\e[92m"
NOCOLOR="\e[0m"
else
BLUE=""
LIGHTGREEN=""
NOCOLOR=""
fi
}
echo_color_support

0 comments on commit ca6828e

Please sign in to comment.