Commit 96edd7c1 authored by Clive Makamara's avatar Clive Makamara Committed by GitHub

Merge pull request #15 from dreidev/develop

merge master
parents 82ff372c faff3ea5
node_modules/* node_modules/*
npm-debug.log npm-debug.log
npm-debug.log* npm-debug.log*
\ No newline at end of file gitflow/*
db/*
\ No newline at end of file
language: node_js
env:
- TRAVIS=true
node_js:
- "7"
- "6"
- "6.1"
- "5.11"
- "4"
- "iojs"
notifications:
email: false
script: npm install --ignore-scripts
\ No newline at end of file
# git-flow (Dreidev Edition) # git-flow (Dreidev Edition)
[![Build Status](https://travis-ci.org/dreidev/gitflow.svg?branch=master)](https://travis-ci.org/dreidev/gitflow) [![npm version](https://badge.fury.io/js/gitflow.svg)](https://badge.fury.io/js/gitflow) [![Dependencies](https://david-dm.org/dreidev/gitflow.svg)](https://david-dm.org/dreidev/gitflow)
A collection of Git extensions to provide high-level repository operations A collection of Git extensions to provide high-level repository operations
for Vincent Driessen's [branching model](http://nvie.com/git-model "original for Vincent Driessen's [branching model](http://nvie.com/git-model "original
blog post"). This fork adds functionality not added to the original branch. [wiki](http://github.com/dreidev/gitflow/wiki) blog post"). This fork adds functionality not added to the original branch. [wiki](http://github.com/dreidev/gitflow/wiki)
......
# #
# git-flow -- A collection of Git extensions to provide high-level # git-flow -- A collection of Git extensions to provide high-level
# repository operations for Vincent Driessen's branching model. # repository operations for Vincent Driessen's branching model.
# #
# A blog post presenting this model is found at: # A blog post presenting this model is found at:
# http://blog.avirtualhome.com/development-workflow-using-git/ # http://blog.avirtualhome.com/development-workflow-using-git/
# #
# Feel free to contribute to this project at: # Feel free to contribute to this project at:
# http://github.com/petervanderdoes/gitflow # http://github.com/petervanderdoes/gitflow
# #
# Authors: # Authors:
# Copyright 2012-2016 Peter van der Does. All rights reserved. # Copyright 2012-2016 Peter van der Does. All rights reserved.
# #
# Original Author: # Original Author:
# Copyright 2010 Vincent Driessen. All rights reserved. # Copyright 2010 Vincent Driessen. All rights reserved.
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met: # modification, are permitted provided that the following conditions are met:
# #
# 1. Redistributions of source code must retain the above copyright notice, this # 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer. # list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice, # 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation # this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution. # and/or other materials provided with the distribution.
# #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # 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 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # 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 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# #
initialize() { initialize() {
require_git_repo require_git_repo
require_gitflow_initialized require_gitflow_initialized
git config --get gitflow.prefix.bugfix >/dev/null 2>&1 || die "Bugfix prefix not set. Please run 'git flow init'." git config --get gitflow.prefix.bugfix >/dev/null 2>&1 || die "Bugfix prefix not set. Please run 'git flow init'."
gitflow_load_settings gitflow_load_settings
PREFIX=$(git config --get gitflow.prefix.bugfix) PREFIX=$(git config --get gitflow.prefix.bugfix)
} }
usage() { usage() {
OPTIONS_SPEC="\ OPTIONS_SPEC="\
git flow bugfix [list] git flow bugfix [list]
git flow bugfix start git flow bugfix start
git flow bugfix finish git flow bugfix finish
git flow bugfix publish git flow bugfix publish
git flow bugfix track git flow bugfix track
git flow bugfix diff git flow bugfix diff
git flow bugfix rebase git flow bugfix rebase
git flow bugfix checkout git flow bugfix checkout
git flow bugfix pull git flow bugfix pull
git flow bugfix delete git flow bugfix delete
Manage your bugfix branches. Manage your bugfix branches.
For more specific help type the command followed by --help For more specific help type the command followed by --help
-- --
" "
flags_help flags_help
} }
cmd_default() { cmd_default() {
cmd_list "$@" cmd_list "$@"
} }
cmd_list() { cmd_list() {
OPTIONS_SPEC="\ OPTIONS_SPEC="\
git flow bugfix [list] [-h] [-v] git flow bugfix [list] [-h] [-v]
Lists all the existing bugfix branches in the local repository. Lists all the existing bugfix branches in the local repository.
-- --
h,help! Show this help h,help! Show this help
v,verbose Verbose (more) output v,verbose Verbose (more) output
" "
local bugfix_branches current_branch width branch len local bugfix_branches current_branch width branch len
local base develop_sha branch_sha local base develop_sha branch_sha
# Define flags # Define flags
DEFINE_boolean 'verbose' false 'verbose (more) output' v DEFINE_boolean 'verbose' false 'verbose (more) output' v
# Parse argun=ments # Parse argun=ments
parse_args "$@" parse_args "$@"
bugfix_branches=$(git_local_branches_prefixed "$PREFIX") bugfix_branches=$(git_local_branches_prefixed "$PREFIX")
if [ -z "$bugfix_branches" ]; then if [ -z "$bugfix_branches" ]; then
warn "No bugfix branches exist." warn "No bugfix branches exist."
warn "" warn ""
warn "You can start a new bugfix branch:" warn "You can start a new bugfix branch:"
warn "" warn ""
warn " git flow bugfix start <name> [<base>]" warn " git flow bugfix start <name> [<base>]"
warn "" warn ""
exit 0 exit 0
fi fi
current_branch=$(git_current_branch) current_branch=$(git_current_branch)
# Determine column width first # Determine column width first
width=0 width=0
for branch in $bugfix_branches; do for branch in $bugfix_branches; do
len=${#branch} len=${#branch}
width=$(max $width $len) width=$(max $width $len)
done done
width=$(($width+3-${#PREFIX})) width=$(($width+3-${#PREFIX}))
for branch in $bugfix_branches; do for branch in $bugfix_branches; do
base=$(git merge-base "$branch" "$DEVELOP_BRANCH") base=$(git merge-base "$branch" "$DEVELOP_BRANCH")
develop_sha=$(git rev-parse "$DEVELOP_BRANCH") develop_sha=$(git rev-parse "$DEVELOP_BRANCH")
branch_sha=$(git rev-parse "$branch") branch_sha=$(git rev-parse "$branch")
if [ "$branch" = "$current_branch" ]; then if [ "$branch" = "$current_branch" ]; then
printf "* " printf "* "
else else
printf " " printf " "
fi fi
if flag verbose; then if flag verbose; then
printf "%-${width}s" "${branch#$PREFIX}" printf "%-${width}s" "${branch#$PREFIX}"
if [ "$branch_sha" = "$develop_sha" ]; then if [ "$branch_sha" = "$develop_sha" ]; then
printf "(no commits yet)" printf "(no commits yet)"
elif [ "$base" = "$branch_sha" ]; then elif [ "$base" = "$branch_sha" ]; then
printf "(is behind develop, may ff)" printf "(is behind develop, may ff)"
elif [ "$base" = "$develop_sha" ]; then elif [ "$base" = "$develop_sha" ]; then
printf "(based on latest develop)" printf "(based on latest develop)"
else else
printf "(may be rebased)" printf "(may be rebased)"
fi fi
else else
printf "%s" "${branch#$PREFIX}" printf "%s" "${branch#$PREFIX}"
fi fi
echo echo
done done
} }
cmd_help() { cmd_help() {
usage usage
exit 0 exit 0
} }
# Parse arguments and set common variables # Parse arguments and set common variables
parse_args() { parse_args() {
FLAGS "$@" || exit $? FLAGS "$@" || exit $?
eval set -- "${FLAGS_ARGV}" eval set -- "${FLAGS_ARGV}"
# read arguments into global variables # read arguments into global variables
if [ -z $1 ]; then if [ -z $1 ]; then
NAME='' NAME=''
else else
NAME=$1 NAME=$1
fi fi
BRANCH=$PREFIX$NAME BRANCH=$PREFIX$NAME
} }
parse_remote_name() { parse_remote_name() {
# Parse arguments # Parse arguments
FLAGS "$@" || exit $? FLAGS "$@" || exit $?
eval set -- "${FLAGS_ARGV}" eval set -- "${FLAGS_ARGV}"
# read arguments into global variables # read arguments into global variables
if [ -z $1 ]; then if [ -z $1 ]; then
REMOTE='' REMOTE=''
else else
REMOTE=$1 REMOTE=$1
fi fi
if [ -z $2 ]; then if [ -z $2 ]; then
NAME='' NAME=''
else else
NAME=$2 NAME=$2
fi fi
BRANCH=$PREFIX$NAME BRANCH=$PREFIX$NAME
} }
cmd_start() { cmd_start() {
OPTIONS_SPEC="\ OPTIONS_SPEC="\
git flow bugfix start [-h] [-F] <name> [<base>] git flow bugfix start [-h] [-F] <name> [<base>]
Start new bugfix <name>, optionally basing it on <base> instead of <develop> Start new bugfix <name>, optionally basing it on <base> instead of <develop>
-- --
h,help! Show this help h,help! Show this help
showcommands! Show git commands while executing them showcommands! Show git commands while executing them
F,[no]fetch Fetch from origin before performing local operation F,[no]fetch Fetch from origin before performing local operation
" "
local base local base
# Define flags # Define flags
DEFINE_boolean 'fetch' false 'fetch from origin before performing local operation' F DEFINE_boolean 'fetch' false 'fetch from origin before performing local operation' F
# Override defaults with values from config # Override defaults with values from config
gitflow_override_flag_boolean "bugfix.start.fetch" "fetch" gitflow_override_flag_boolean "bugfix.start.fetch" "fetch"
# Parse arguments # Parse arguments
parse_args "$@" parse_args "$@"
eval set -- "${FLAGS_ARGV}" eval set -- "${FLAGS_ARGV}"
base=${2:-$DEVELOP_BRANCH} base=${2:-$DEVELOP_BRANCH}
require_base_is_local_branch "$base" require_base_is_local_branch "$base"
gitflow_require_name_arg gitflow_require_name_arg
gitflow_config_set_base_branch $base $BRANCH gitflow_config_set_base_branch $base $BRANCH
# Update the local repo with remote changes, if asked # Update the local repo with remote changes, if asked
if flag fetch; then if flag fetch; then
git_fetch_branch "$ORIGIN" "$base" git_fetch_branch "$ORIGIN" "$base"
fi fi
# Sanity checks # Sanity checks
require_branch_absent "$BRANCH" require_branch_absent "$BRANCH"
# If the origin branch counterpart exists, assert that the local branch # If the origin branch counterpart exists, assert that the local branch
# isn't behind it (to avoid unnecessary rebasing) # isn't behind it (to avoid unnecessary rebasing)
if git_remote_branch_exists "$ORIGIN/$base"; then if git_remote_branch_exists "$ORIGIN/$base"; then
require_branches_equal "$base" "$ORIGIN/$base" require_branches_equal "$base" "$ORIGIN/$base"
fi fi
run_pre_hook "$NAME" "$ORIGIN" "$BRANCH" "$base" run_pre_hook "$NAME" "$ORIGIN" "$BRANCH" "$base"
# create branch # create branch
git_do checkout -b "$BRANCH" "$base" || die "Could not create bugfix branch '$BRANCH'." git_do checkout -b "$BRANCH" "$base" || die "Could not create bugfix branch '$BRANCH'."
run_post_hook "$NAME" "$ORIGIN" "$BRANCH" "$base" run_post_hook "$NAME" "$ORIGIN" "$BRANCH" "$base"
echo echo
echo "Summary of actions:" echo "Summary of actions:"
echo "- A new branch '$BRANCH' was created, based on '$base'" echo "- A new branch '$BRANCH' was created, based on '$base'"
echo "- You are now on branch '$(git_current_branch)'" echo "- You are now on branch '$(git_current_branch)'"
echo "" echo ""
echo "Now, start committing on your bugfix. When done, use:" echo "Now, start committing on your bugfix. When done, use:"
echo "" echo ""
echo " git flow bugfix finish $NAME" echo " git flow bugfix finish $NAME"
echo echo
} }
cmd_finish() { cmd_finish() {
OPTIONS_SPEC="\ OPTIONS_SPEC="\
git flow bugfix finish [-h] [-F] [-r] [-p] [-k] [-D] [-S] [--no-ff] <name|nameprefix> git flow bugfix finish [-h] [-F] [-r] [-p] [-k] [-D] [-S] [--no-ff] <name|nameprefix>
Finish bugfix <name> Finish bugfix <name>
-- --
h,help! Show this help h,help! Show this help
showcommands! Show git commands while executing them showcommands! Show git commands while executing them
F,[no]fetch Fetch from origin before performing finish F,[no]fetch Fetch from origin before performing finish
r,[no]rebase Rebase before merging r,[no]rebase Rebase before merging
p,[no]preserve-merges Preserve merges while rebasing p,[no]preserve-merges Preserve merges while rebasing
k,[no]keep Keep branch after performing finish k,[no]keep Keep branch after performing finish
keepremote! Keep the remote branch keepremote! Keep the remote branch
keeplocal! Keep the local branch keeplocal! Keep the local branch
D,[no]force_delete Force delete bugfix branch after finish D,[no]force_delete Force delete bugfix branch after finish
S,[no]squash Squash bugfix during merge S,[no]squash Squash bugfix during merge
no-ff! Never fast-forward during the merge no-ff! Never fast-forward during the merge
" "
local finish_base local finish_base
# Define flags # Define flags
DEFINE_boolean 'fetch' false "fetch from $ORIGIN before performing finish" F DEFINE_boolean 'fetch' false "fetch from $ORIGIN before performing finish" F
DEFINE_boolean 'rebase' false "rebase before merging" r DEFINE_boolean 'rebase' false "rebase before merging" r
DEFINE_boolean 'preserve-merges' false 'try to recreate merges while rebasing' p DEFINE_boolean 'preserve-merges' false 'try to recreate merges while rebasing' p
DEFINE_boolean 'keep' false "keep branch after performing finish" k DEFINE_boolean 'keep' false "keep branch after performing finish" k
DEFINE_boolean 'keepremote' false "keep the remote branch" DEFINE_boolean 'keepremote' false "keep the remote branch"
DEFINE_boolean 'keeplocal' false "keep the local branch" DEFINE_boolean 'keeplocal' false "keep the local branch"
DEFINE_boolean 'force_delete' false "force delete bugfix branch after finish" D DEFINE_boolean 'force_delete' false "force delete bugfix branch after finish" D
DEFINE_boolean 'squash' false "squash bugfix during merge" S DEFINE_boolean 'squash' false "squash bugfix during merge" S
DEFINE_boolean 'squash-info' false "add branch info during squash" DEFINE_boolean 'squash-info' false "add branch info during squash"
DEFINE_boolean 'no-ff!' false "Don't fast-forward ever during merge " DEFINE_boolean 'no-ff!' false "Don't fast-forward ever during merge "
# Override defaults with values from config # Override defaults with values from config
gitflow_override_flag_boolean "bugfix.finish.fetch" "fetch" gitflow_override_flag_boolean "bugfix.finish.fetch" "fetch"
gitflow_override_flag_boolean "bugfix.finish.rebase" "rebase" gitflow_override_flag_boolean "bugfix.finish.rebase" "rebase"
gitflow_override_flag_boolean "bugfix.finish.preserve-merges" "preserve_merges" gitflow_override_flag_boolean "bugfix.finish.preserve-merges" "preserve_merges"
gitflow_override_flag_boolean "bugfix.finish.keep" "keep" gitflow_override_flag_boolean "bugfix.finish.keep" "keep"
gitflow_override_flag_boolean "bugfix.finish.keepremote" "keepremote" gitflow_override_flag_boolean "bugfix.finish.keepremote" "keepremote"
gitflow_override_flag_boolean "bugfix.finish.keeplocal" "keeplocal" gitflow_override_flag_boolean "bugfix.finish.keeplocal" "keeplocal"
gitflow_override_flag_boolean "bugfix.finish.force-delete" "force_delete" gitflow_override_flag_boolean "bugfix.finish.force-delete" "force_delete"
gitflow_override_flag_boolean "bugfix.finish.squash" "squash" gitflow_override_flag_boolean "bugfix.finish.squash" "squash"
gitflow_override_flag_boolean "bugfix.finish.squash-info" "squash_info" gitflow_override_flag_boolean "bugfix.finish.squash-info" "squash_info"
gitflow_override_flag_boolean "bugfix.finish.no-ff" "no_ff" gitflow_override_flag_boolean "bugfix.finish.no-ff" "no_ff"
# Parse arguments # Parse arguments
parse_args "$@" parse_args "$@"
# Use current branch if no name is given # Use current branch if no name is given
if [ "$NAME" = "" ]; then if [ "$NAME" = "" ]; then
gitflow_use_current_branch_name gitflow_use_current_branch_name
fi fi
# Keeping both branches implies the --keep flag to be true. # Keeping both branches implies the --keep flag to be true.
if flag keepremote && flag keeplocal; then if flag keepremote && flag keeplocal; then
FLAGS_keep=$FLAGS_TRUE FLAGS_keep=$FLAGS_TRUE
fi fi
# Sanity checks # Sanity checks
require_branch "$BRANCH" require_branch "$BRANCH"
BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH) BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH)
BASE_BRANCH=${BASE_BRANCH:-$DEVELOP_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 bugfix branch '$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 bugfix branch '$BRANCH'."
# Detect if we're restoring from a merge conflict # Detect if we're restoring from a merge conflict
if [ -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE" ]; then if [ -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE" ]; then
# #
# TODO: detect that we're working on the correct branch here! # TODO: detect that we're working on the correct branch here!
# The user need not necessarily have given the same $NAME twice here # The user need not necessarily have given the same $NAME twice here
# (although he/she should). # (although he/she should).
# #
# TODO: git_is_clean_working_tree() should provide an alternative # TODO: git_is_clean_working_tree() should provide an alternative
# exit code for "unmerged changes in working tree", which we should # exit code for "unmerged changes in working tree", which we should
# actually be testing for here # actually be testing for here
if git_is_clean_working_tree; then if git_is_clean_working_tree; then
finish_base=$(cat "$DOT_GIT_DIR/.gitflow/MERGE_BASE") finish_base=$(cat "$DOT_GIT_DIR/.gitflow/MERGE_BASE")
# Since the working tree is now clean, either the user did a # Since the working tree is now clean, either the user did a
# successful merge manually, or the merge was cancelled. # successful merge manually, or the merge was cancelled.
# We detect this using git_is_branch_merged_into() # We detect this using git_is_branch_merged_into()
if git_is_branch_merged_into "$BRANCH" "$finish_base"; then if git_is_branch_merged_into "$BRANCH" "$finish_base"; then
rm -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE" rm -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE"
helper_finish_cleanup helper_finish_cleanup
exit 0 exit 0
else else
# If the user cancelled the merge and decided to wait until # If the user cancelled the merge and decided to wait until
# later,that's fine. But we have to acknowledge this by # later,that's fine. But we have to acknowledge this by
# removing the MERGE_BASE file and continuing normal execution # removing the MERGE_BASE file and continuing normal execution
# of the finish # of the finish
rm -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE" rm -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE"
fi fi
else else
echo echo
echo "Merge conflicts not resolved yet, use:" echo "Merge conflicts not resolved yet, use:"
echo " git mergetool" echo " git mergetool"
echo " git commit" echo " git commit"
echo echo
echo "You can then complete the finish by running it again:" echo "You can then complete the finish by running it again:"
echo " git flow bugfix finish $NAME" echo " git flow bugfix finish $NAME"
echo echo
exit 1 exit 1
fi fi
fi fi
# Sanity checks # Sanity checks
require_clean_working_tree require_clean_working_tree
# We always fetch the Branch from Origin # We always fetch the Branch from Origin
# This is done to avoid possible commits on the remote that are not # This is done to avoid possible commits on the remote that are not
# merged into the local branch # merged into the local branch
if git_remote_branch_exists "$ORIGIN/$BRANCH"; then if git_remote_branch_exists "$ORIGIN/$BRANCH"; then
git_fetch_branch "$ORIGIN" "$BRANCH" git_fetch_branch "$ORIGIN" "$BRANCH"
fi fi
# Update local branches with remote branches # Update local branches with remote branches
if flag fetch; then if flag fetch; then
git_fetch_branch "$ORIGIN" "$BASE_BRANCH" git_fetch_branch "$ORIGIN" "$BASE_BRANCH"
fi fi
# Check if the local branches have all the commits from the remote branches # Check if the local branches have all the commits from the remote branches
if git_remote_branch_exists "$ORIGIN/$BRANCH"; then if git_remote_branch_exists "$ORIGIN/$BRANCH"; then
require_branches_equal "$BRANCH" "$ORIGIN/$BRANCH" require_branches_equal "$BRANCH" "$ORIGIN/$BRANCH"
fi fi
if git_remote_branch_exists "$ORIGIN/$BASE_BRANCH"; then if git_remote_branch_exists "$ORIGIN/$BASE_BRANCH"; then
require_branches_equal "$BASE_BRANCH" "$ORIGIN/$BASE_BRANCH" require_branches_equal "$BASE_BRANCH" "$ORIGIN/$BASE_BRANCH"
fi fi
run_pre_hook "$NAME" "$ORIGIN" "$BRANCH" run_pre_hook "$NAME" "$ORIGIN" "$BRANCH"
# If the user wants to rebase, do that first # If the user wants to rebase, do that first
if flag rebase; then if flag rebase; then
local _rebase_opts="" local _rebase_opts=""
if flag preserve_merges; then if flag preserve_merges; then
_rebase_opts="$_rebase_opts -p" _rebase_opts="$_rebase_opts -p"
fi fi
if flag showcommands; then if flag showcommands; then
_rebase_opts="$_rebase_opts --showcommands" _rebase_opts="$_rebase_opts --showcommands"
fi fi
if ! git flow bugfix rebase $_rebase_opts "$NAME"; then if ! git flow bugfix rebase $_rebase_opts "$NAME"; then
warn "Finish was aborted due to conflicts during rebase." warn "Finish was aborted due to conflicts during rebase."
warn "Please finish the rebase manually now." warn "Please finish the rebase manually now."
warn "When finished, re-run:" warn "When finished, re-run:"
warn " git flow bugfix finish '$NAME' '$BASE_BRANCH'" warn " git flow bugfix finish '$NAME' '$BASE_BRANCH'"
exit 1 exit 1
fi fi
fi fi
# Merge into BASE # Merge into BASE
git_do checkout "$BASE_BRANCH" || die "Could not check out branch '$BASE_BRANCH'." git_do checkout "$BASE_BRANCH" || die "Could not check out branch '$BASE_BRANCH'."
if noflag squash; then if noflag squash; then
if flag no_ff; then if flag no_ff; then
git_do merge --no-ff "$BRANCH" git_do merge --no-ff "$BRANCH"
else else
if [ "$(git rev-list -n2 "$BASE_BRANCH..$BRANCH" | wc -l)" -eq 1 ]; then if [ "$(git rev-list -n2 "$BASE_BRANCH..$BRANCH" | wc -l)" -eq 1 ]; then
git_do merge --ff "$BRANCH" git_do merge --ff "$BRANCH"
else else
git_do merge --no-ff "$BRANCH" git_do merge --no-ff "$BRANCH"
fi fi
fi fi
else else
git_do merge --squash "$BRANCH" git_do merge --squash "$BRANCH"
flag squash_info && gitflow_create_squash_message "Merged bugfix branch '$BRANCH'" "$BASE_BRANCH" "$BRANCH" > "$DOT_GIT_DIR/SQUASH_MSG" flag squash_info && gitflow_create_squash_message "Merged bugfix branch '$BRANCH'" "$BASE_BRANCH" "$BRANCH" > "$DOT_GIT_DIR/SQUASH_MSG"
git_do commit git_do commit
fi fi
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
# Oops.. we have a merge conflict! # Oops.. we have a merge conflict!
# Write the given $BASE_BRANCH to a temporary file as we will # Write the given $BASE_BRANCH to a temporary file as we will
# be needing it later. # be needing it later.
mkdir -p "$DOT_GIT_DIR/.gitflow" mkdir -p "$DOT_GIT_DIR/.gitflow"
echo "$BASE_BRANCH" > "$DOT_GIT_DIR/.gitflow/MERGE_BASE" echo "$BASE_BRANCH" > "$DOT_GIT_DIR/.gitflow/MERGE_BASE"
echo echo
echo "There were merge conflicts. To resolve the merge conflict manually, use:" echo "There were merge conflicts. To resolve the merge conflict manually, use:"
echo " git mergetool" echo " git mergetool"
echo " git commit" echo " git commit"
echo echo
echo "You can then complete the finish by running it again:" echo "You can then complete the finish by running it again:"
echo " git flow bugfix finish $NAME" echo " git flow bugfix finish $NAME"
echo echo
exit 1 exit 1
fi fi
run_post_hook "$NAME" "$ORIGIN" "$BRANCH" run_post_hook "$NAME" "$ORIGIN" "$BRANCH"
# When no merge conflict is detected, just clean up the bugfix branch # When no merge conflict is detected, just clean up the bugfix branch
gitflow_config_remove_base_branch "$BRANCH" gitflow_config_remove_base_branch "$BRANCH"
helper_finish_cleanup helper_finish_cleanup
} }
helper_finish_cleanup() { helper_finish_cleanup() {
local keepmsg remotebranchdeleted localbranchdeleted local keepmsg remotebranchdeleted localbranchdeleted
# Sanity checks # Sanity checks
require_branch "$BRANCH" require_branch "$BRANCH"
require_clean_working_tree require_clean_working_tree
remotebranchdeleted=$FLAGS_FALSE remotebranchdeleted=$FLAGS_FALSE
localbranchdeleted=$FLAGS_FALSE localbranchdeleted=$FLAGS_FALSE
if noflag keep; then if noflag keep; then
# Always delete remote first # Always delete remote first
if noflag keepremote;then if noflag keepremote;then
if git_remote_branch_exists "$ORIGIN/$BRANCH"; then if git_remote_branch_exists "$ORIGIN/$BRANCH"; then
git_remote_branch_delete "$BRANCH" && remotebranchdeleted=$FLAGS_TRUE git_remote_branch_delete "$BRANCH" && remotebranchdeleted=$FLAGS_TRUE
fi fi
fi fi
# Delete local after remote to avoid warnings # Delete local after remote to avoid warnings
if noflag keeplocal; then if noflag keeplocal; then
if [ "$BRANCH" = "$(git_current_branch)" ]; then if [ "$BRANCH" = "$(git_current_branch)" ]; then
git_do checkout "$BASE_BRANCH" || die "Could not check out branch '$BASE_BRANCH'." git_do checkout "$BASE_BRANCH" || die "Could not check out branch '$BASE_BRANCH'."
fi fi
if flag force_delete; then if flag force_delete; then
git_do branch -D "$BRANCH" && localbranchdeleted=$FLAGS_TRUE git_do branch -D "$BRANCH" && localbranchdeleted=$FLAGS_TRUE
else else
if noflag squash; then if noflag squash; then
git_do branch -d "$BRANCH" && localbranchdeleted=$FLAGS_TRUE git_do branch -d "$BRANCH" && localbranchdeleted=$FLAGS_TRUE
else else
git_do branch -D "$BRANCH" && localbranchdeleted=$FLAGS_TRUE git_do branch -D "$BRANCH" && localbranchdeleted=$FLAGS_TRUE
fi fi
fi fi
fi fi
# no more branches: we can safely remove config section # no more branches: we can safely remove config section
if ! git_remote_branch_exists "$ORIGIN/$BRANCH" -a ! git_local_branch_exists "$BRANCH"; then if ! git_remote_branch_exists "$ORIGIN/$BRANCH" -a ! git_local_branch_exists "$BRANCH"; then
gitflow_config_remove_base_section "$BRANCH" gitflow_config_remove_base_section "$BRANCH"
fi fi
fi fi
echo echo
echo "Summary of actions:" echo "Summary of actions:"
echo "- The bugfix branch '$BRANCH' was merged into '$BASE_BRANCH'" echo "- The bugfix branch '$BRANCH' was merged into '$BASE_BRANCH'"
#echo "- Merge conflicts were resolved" # TODO: Add this line when it's supported #echo "- Merge conflicts were resolved" # TODO: Add this line when it's supported
if noflag keep; then if noflag keep; then
if [ $localbranchdeleted -eq $FLAGS_TRUE ]; then if [ $localbranchdeleted -eq $FLAGS_TRUE ]; then
keepmsg="has been locally deleted" keepmsg="has been locally deleted"
else else
keepmsg="is still locally available" keepmsg="is still locally available"
fi fi
if [ $remotebranchdeleted -eq $FLAGS_TRUE ]; then if [ $remotebranchdeleted -eq $FLAGS_TRUE ]; then
keepmsg=$keepmsg"; it has been remotely deleted from '$ORIGIN'" keepmsg=$keepmsg"; it has been remotely deleted from '$ORIGIN'"
elif git_remote_branch_exists "$ORIGIN/$BRANCH"; then elif git_remote_branch_exists "$ORIGIN/$BRANCH"; then
keepmsg=$keepmsg"; it is still remotely available on '$ORIGIN'" keepmsg=$keepmsg"; it is still remotely available on '$ORIGIN'"
fi fi
else else
keepmsg="is still locally available" keepmsg="is still locally available"
if git_remote_branch_exists "$ORIGIN/$BRANCH"; then if git_remote_branch_exists "$ORIGIN/$BRANCH"; then
keepmsg=$keepmsg"; it is still remotely available on '$ORIGIN'" keepmsg=$keepmsg"; it is still remotely available on '$ORIGIN'"
fi fi
fi fi
echo "- bugfix branch '$BRANCH' "$keepmsg echo "- bugfix branch '$BRANCH' "$keepmsg
echo "- You are now on branch '$(git_current_branch)'" echo "- You are now on branch '$(git_current_branch)'"
echo echo
} }
cmd_publish() { cmd_publish() {
OPTIONS_SPEC="\ OPTIONS_SPEC="\
git flow bugfix publish [-h] [<name>] git flow bugfix publish [-h] [<name>]
Publish bugfix branch <name> on $ORIGIN. Publish bugfix branch <name> on $ORIGIN.
When <name> is omitted the current branch is used, but only if it's a bugfix branch. When <name> is omitted the current branch is used, but only if it's a bugfix branch.
-- --
h,help! Show this help h,help! Show this help
showcommands! Show git commands while executing them showcommands! Show git commands while executing them
" "
# Parse arguments # Parse arguments
parse_args "$@" parse_args "$@"
# Use current branch if no name is given # Use current branch if no name is given
if [ "$NAME" = "" ]; then if [ "$NAME" = "" ]; then
gitflow_use_current_branch_name gitflow_use_current_branch_name
fi fi
# Sanity checks # Sanity checks
require_clean_working_tree require_clean_working_tree
require_branch "$BRANCH" require_branch "$BRANCH"
git_do fetch -q "$ORIGIN" || die "Could not fetch branch '$BRANCH' from remote '$ORIGIN'." git_do fetch -q "$ORIGIN" || die "Could not fetch branch '$BRANCH' from remote '$ORIGIN'."
require_branch_absent "$ORIGIN/$BRANCH" require_branch_absent "$ORIGIN/$BRANCH"
run_pre_hook "$NAME" "$ORIGIN" "$BRANCH" run_pre_hook "$NAME" "$ORIGIN" "$BRANCH"
# Create remote branch with remote tracking # Create remote branch with remote tracking
git_do push -u "$ORIGIN" "$BRANCH:$BRANCH" git_do push -u "$ORIGIN" "$BRANCH:$BRANCH"
git_do fetch -q "$ORIGIN" "$BRANCH" || die "Could not fetch branch '$BRANCH' from remote '$ORIGIN'." 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'." git_do checkout "$BRANCH" || die "Could not check out branch '$BRANCH'."
run_post_hook "$NAME" "$ORIGIN" "$BRANCH" run_post_hook "$NAME" "$ORIGIN" "$BRANCH"
echo echo
echo "Summary of actions:" echo "Summary of actions:"
echo "- The remote branch '$BRANCH' was created or updated" echo "- The remote branch '$BRANCH' was created or updated"
echo "- The local branch '$BRANCH' was configured to track the remote branch" echo "- The local branch '$BRANCH' was configured to track the remote branch"
echo "- You are now on branch '$(git_current_branch)'" echo "- You are now on branch '$(git_current_branch)'"
echo echo
} }
cmd_track() { cmd_track() {
OPTIONS_SPEC="\ OPTIONS_SPEC="\
git flow bugfix track [-h] <name> git flow bugfix track [-h] <name>
Start tracking bugfix <name> that is shared on $ORIGIN Start tracking bugfix <name> that is shared on $ORIGIN
-- --
h,help! Show this help h,help! Show this help
showcommands! Show git commands while executing them showcommands! Show git commands while executing them
" "
# Parse arguments # Parse arguments
parse_args "$@" parse_args "$@"
gitflow_require_name_arg gitflow_require_name_arg
# Sanity checks # Sanity checks
require_clean_working_tree require_clean_working_tree
require_local_branch_absent "$BRANCH" require_local_branch_absent "$BRANCH"
run_pre_hook "$NAME" "$ORIGIN" "$BRANCH" run_pre_hook "$NAME" "$ORIGIN" "$BRANCH"
git_do fetch -q "$ORIGIN" || die "Could not fetch branch '$BRANCH' from remote '$ORIGIN'." git_do fetch -q "$ORIGIN" || die "Could not fetch branch '$BRANCH' from remote '$ORIGIN'."
git_remote_branch_exists "$ORIGIN/$BRANCH" git_remote_branch_exists "$ORIGIN/$BRANCH"
# Create tracking branch # Create tracking branch
git_do checkout -b "$BRANCH" "$ORIGIN/$BRANCH" || die "Could not create '$BRANCH'." git_do checkout -b "$BRANCH" "$ORIGIN/$BRANCH" || die "Could not create '$BRANCH'."
run_post_hook "$NAME" "$ORIGIN" "$BRANCH" run_post_hook "$NAME" "$ORIGIN" "$BRANCH"
echo echo
echo "Summary of actions:" echo "Summary of actions:"
echo "- A new remote tracking branch '$BRANCH' was created" echo "- A new remote tracking branch '$BRANCH' was created"
echo "- You are now on branch '$(git_current_branch)'" echo "- You are now on branch '$(git_current_branch)'"
echo echo
} }
cmd_diff() { cmd_diff() {
OPTIONS_SPEC="\ OPTIONS_SPEC="\
git flow bugfix diff [-h] [<name|nameprefix>] git flow bugfix diff [-h] [<name|nameprefix>]
Show all changes in <name> that are not in the base Show all changes in <name> that are not in the base
-- --
h,help! Show this help h,help! Show this help
showcommands! Show git commands while executing them showcommands! Show git commands while executing them
" "
local base local base
# Parse arguments # Parse arguments
parse_args "$@" parse_args "$@"
# Use current branch if no name is given # Use current branch if no name is given
if [ "$NAME" = "" ]; then if [ "$NAME" = "" ]; then
gitflow_use_current_branch_name gitflow_use_current_branch_name
fi fi
base=$(gitflow_config_get_base_branch $BRANCH) base=$(gitflow_config_get_base_branch $BRANCH)
base=${base:-$DEVELOP_BRANCH} base=${base:-$DEVELOP_BRANCH}
git_do diff "$base..$BRANCH" git_do diff "$base..$BRANCH"
} }
cmd_checkout() { cmd_checkout() {
OPTIONS_SPEC="\ OPTIONS_SPEC="\
git flow bugfix checkout [-h] [<name|nameprefix>] git flow bugfix checkout [-h] [<name|nameprefix>]
Switch to bugfix branch <name> Switch to bugfix branch <name>
-- --
h,help! Show this help h,help! Show this help
showcommands! Show git commands while executing them showcommands! Show git commands while executing them
" "
# Parse arguments # Parse arguments
parse_args "$@" parse_args "$@"
NAME=$(gitflow_resolve_nameprefix "$NAME" "$PREFIX") NAME=$(gitflow_resolve_nameprefix "$NAME" "$PREFIX")
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
BRANCH=$PREFIX$NAME BRANCH=$PREFIX$NAME
git_do checkout "$BRANCH" || die "Could not check out branch '$BRANCH'." git_do checkout "$BRANCH" || die "Could not check out branch '$BRANCH'."
fi fi
} }
cmd_co() { cmd_co() {
# Alias for checkout # Alias for checkout
cmd_checkout "$@" cmd_checkout "$@"
} }
cmd_rebase() { cmd_rebase() {
OPTIONS_SPEC="\ OPTIONS_SPEC="\
git flow bugfix rebase [-h] [-i] [-p] [<name|nameprefix>] git flow bugfix rebase [-h] [-i] [-p] [<name|nameprefix>]
Rebase <name> on <base_branch> Rebase <name> on <base_branch>
-- --
h,help! Show this help h,help! Show this help
showcommands! Show git commands while executing them showcommands! Show git commands while executing them
i,[no]interactive Do an interactive rebase i,[no]interactive Do an interactive rebase
p,[no]preserve-merges Preserve merges p,[no]preserve-merges Preserve merges
" "
local opts local opts
# Define flags # Define flags
DEFINE_boolean 'interactive' false 'do an interactive rebase' i DEFINE_boolean 'interactive' false 'do an interactive rebase' i
DEFINE_boolean 'preserve-merges' false 'try to recreate merges' p DEFINE_boolean 'preserve-merges' false 'try to recreate merges' p
# Override defaults with values from config # Override defaults with values from config
gitflow_override_flag_boolean "bugfix.rebase.interactive" "interactive" gitflow_override_flag_boolean "bugfix.rebase.interactive" "interactive"
gitflow_override_flag_boolean "bugfix.rebase.preserve-merges" "preserve_merges" gitflow_override_flag_boolean "bugfix.rebase.preserve-merges" "preserve_merges"
# Parse arguments # Parse arguments
parse_args "$@" parse_args "$@"
# Use current branch if no name is given # Use current branch if no name is given
if [ "$NAME" = "" ]; then if [ "$NAME" = "" ]; then
gitflow_use_current_branch_name gitflow_use_current_branch_name
fi fi
BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH) BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH)
BASE_BRANCH=${BASE_BRANCH:-$DEVELOP_BRANCH} BASE_BRANCH=${BASE_BRANCH:-$DEVELOP_BRANCH}
warn "Will try to rebase '$NAME' which is based on '$BASE_BRANCH'..." warn "Will try to rebase '$NAME' which is based on '$BASE_BRANCH'..."
require_clean_working_tree require_clean_working_tree
require_branch "$BRANCH" 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 bugfix 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 bugfix branch '$BRANCH'."
git_do checkout -q "$BRANCH" || die "Could not check out branch '$BRANCH'." git_do checkout -q "$BRANCH" || die "Could not check out branch '$BRANCH'."
if flag interactive; then if flag interactive; then
opts="$opts -i" opts="$opts -i"
fi fi
if flag preserve_merges; then if flag preserve_merges; then
opts="$opts -p" opts="$opts -p"
fi fi
git_do rebase $opts "$BASE_BRANCH" git_do rebase $opts "$BASE_BRANCH"
} }
avoid_accidental_cross_branch_action() { avoid_accidental_cross_branch_action() {
local current_branch local current_branch
current_branch=$(git_current_branch) current_branch=$(git_current_branch)
if [ "$BRANCH" != "$current_branch" ]; then if [ "$BRANCH" != "$current_branch" ]; then
warn "Trying to pull from '$BRANCH' while currently on branch '$current_branch'." warn "Trying to pull from '$BRANCH' while currently on branch '$current_branch'."
warn "To avoid unintended merges, git-flow aborted." warn "To avoid unintended merges, git-flow aborted."
return 1 return 1
fi fi
return 0 return 0
} }
cmd_pull() { cmd_pull() {
OPTIONS_SPEC="\ OPTIONS_SPEC="\
git flow bugfix pull [-h] <remote> [<name>] git flow bugfix pull [-h] <remote> [<name>]
Pull bugfix <name> from <remote> Pull bugfix <name> from <remote>
-- --
h,help! Show this help h,help! Show this help
showcommands! Show git commands while executing them showcommands! Show git commands while executing them
" "
local current_branch local current_branch
# Define flags # Define flags
DEFINE_boolean 'rebase' false "pull with rebase" r DEFINE_boolean 'rebase' false "pull with rebase" r
warn "The command 'git flow bugfix pull' will be deprecated per version 2.0.0. Use 'git flow bugfix track' instead." warn "The command 'git flow bugfix pull' will be deprecated per version 2.0.0. Use 'git flow bugfix track' instead."
# Parse arguments # Parse arguments
parse_remote_name "$@" parse_remote_name "$@"
if [ -z "$REMOTE" ]; then if [ -z "$REMOTE" ]; then
die "Name a remote explicitly." die "Name a remote explicitly."
fi fi
# Use current branch if no name is given # Use current branch if no name is given
if [ "$NAME" = "" ]; then if [ "$NAME" = "" ]; then
gitflow_use_current_branch_name gitflow_use_current_branch_name
fi fi
# To avoid accidentally merging different bugfix branches into each other, # To avoid accidentally merging different bugfix branches into each other,
# die if the current bugfix branch differs from the requested $NAME # die if the current bugfix branch differs from the requested $NAME
# argument. # argument.
current_branch=$(git_current_branch) current_branch=$(git_current_branch)
if startswith "$current_branch" "$PREFIX"; then if startswith "$current_branch" "$PREFIX"; then
# We are on a local bugfix branch already, so $BRANCH must be equal to # We are on a local bugfix branch already, so $BRANCH must be equal to
# the current branch # the current branch
avoid_accidental_cross_branch_action || die avoid_accidental_cross_branch_action || die
fi fi
require_clean_working_tree require_clean_working_tree
run_pre_hook "$NAME" "$REMOTE" "$BRANCH" run_pre_hook "$NAME" "$REMOTE" "$BRANCH"
if git_local_branch_exists "$BRANCH"; then if git_local_branch_exists "$BRANCH"; then
# Again, avoid accidental merges # Again, avoid accidental merges
avoid_accidental_cross_branch_action || die avoid_accidental_cross_branch_action || die
# We already have a local branch called like this, so simply pull the # We already have a local branch called like this, so simply pull the
# remote changes in # remote changes in
if flag rebase; then if flag rebase; then
if ! git_do pull --rebase -q "$REMOTE" "$BRANCH"; then if ! git_do pull --rebase -q "$REMOTE" "$BRANCH"; then
warn "Pull was aborted. There might be conflicts during rebase or '$REMOTE' might be inaccessible." warn "Pull was aborted. There might be conflicts during rebase or '$REMOTE' might be inaccessible."
exit 1 exit 1
fi fi
else else
git_do pull -q "$REMOTE" "$BRANCH" || die "Failed to pull from remote '$REMOTE'." git_do pull -q "$REMOTE" "$BRANCH" || die "Failed to pull from remote '$REMOTE'."
fi fi
echo "Pulled $REMOTE's changes into $BRANCH." echo "Pulled $REMOTE's changes into $BRANCH."
else else
# Setup the local branch clone for the first time # Setup the local branch clone for the first time
git_do fetch -q "$REMOTE" "$BRANCH" || die "Could not fetch branch '$BRANCH' from remote '$REMOTE'." # Stores in FETCH_HEAD git_do fetch -q "$REMOTE" "$BRANCH" || die "Could not fetch branch '$BRANCH' from remote '$REMOTE'." # Stores in FETCH_HEAD
git_do branch --no-track "$BRANCH" FETCH_HEAD || die "Branch failed." git_do branch --no-track "$BRANCH" FETCH_HEAD || die "Branch failed."
git_do checkout -q "$BRANCH" || die "Could not check out branch '$BRANCH'." git_do checkout -q "$BRANCH" || die "Could not check out branch '$BRANCH'."
echo "Created local branch $BRANCH based on $REMOTE's $BRANCH." echo "Created local branch $BRANCH based on $REMOTE's $BRANCH."
fi fi
run_post_hook "$NAME" "$REMOTE" "$BRANCH" run_post_hook "$NAME" "$REMOTE" "$BRANCH"
} }
cmd_delete() { cmd_delete() {
OPTIONS_SPEC="\ OPTIONS_SPEC="\
git flow bugfix delete [-h] [-f] [-r] <name> git flow bugfix delete [-h] [-f] [-r] <name>
Delete a given bugfix branch Delete a given bugfix branch
-- --
h,help! Show this help h,help! Show this help
showcommands! Show git commands while executing them showcommands! Show git commands while executing them
f,[no]force Force deletion f,[no]force Force deletion
r,[no]remote Delete remote branch r,[no]remote Delete remote branch
" "
local current_branch local current_branch
# Define flags # Define flags
DEFINE_boolean 'force' false "force deletion" f DEFINE_boolean 'force' false "force deletion" f
DEFINE_boolean 'remote' false "delete remote branch" r DEFINE_boolean 'remote' false "delete remote branch" r
# Override defaults with values from config # Override defaults with values from config
gitflow_override_flag_boolean "bugfix.delete.force" "force" gitflow_override_flag_boolean "bugfix.delete.force" "force"
gitflow_override_flag_boolean "bugfix.delete.remote" "remote" gitflow_override_flag_boolean "bugfix.delete.remote" "remote"
# Parse arguments # Parse arguments
parse_args "$@" parse_args "$@"
gitflow_require_name_arg gitflow_require_name_arg
# Sanity checks # Sanity checks
require_branch "$BRANCH" require_branch "$BRANCH"
BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH) BASE_BRANCH=$(gitflow_config_get_base_branch $BRANCH)
BASE_BRANCH=${BASE_BRANCH:-$DEVELOP_BRANCH} BASE_BRANCH=${BASE_BRANCH:-$DEVELOP_BRANCH}
run_pre_hook "$NAME" "$ORIGIN" "$BRANCH" run_pre_hook "$NAME" "$ORIGIN" "$BRANCH"
current_branch=$(git_current_branch) current_branch=$(git_current_branch)
# We can't delete a branch we are on, switch to the develop branch. # We can't delete a branch we are on, switch to the develop branch.
if [ "$BRANCH" = "$current_branch" ]; then if [ "$BRANCH" = "$current_branch" ]; then
require_clean_working_tree require_clean_working_tree
if git_local_branch_exists "$BASE_BRANCH"; then if git_local_branch_exists "$BASE_BRANCH"; then
git_do checkout "$BASE_BRANCH" git_do checkout "$BASE_BRANCH"
else else
git_do checkout "$DEVELOP_BRANCH" || die "Could not check out branch '$DEVELOP_BRANCH'." git_do checkout "$DEVELOP_BRANCH" || die "Could not check out branch '$DEVELOP_BRANCH'."
fi fi
fi fi
if git_is_branch_merged_into "$BRANCH" "$BASE_BRANCH"; then if git_is_branch_merged_into "$BRANCH" "$BASE_BRANCH"; then
git_do branch -d "$BRANCH" || die "Could not delete the $BRANCH." git_do branch -d "$BRANCH" || die "Could not delete the $BRANCH."
if flag remote; then if flag remote; then
git_do push "$ORIGIN" :"$BRANCH" || die "Could not delete the remote $BRANCH in $ORIGIN." git_do push "$ORIGIN" :"$BRANCH" || die "Could not delete the remote $BRANCH in $ORIGIN."
fi fi
else else
if flag force; then if flag force; then
git_do branch -D "$BRANCH" || die "Could not delete the $BRANCH." git_do branch -D "$BRANCH" || die "Could not delete the $BRANCH."
if flag remote; then if flag remote; then
git_do push "$ORIGIN" :"$BRANCH" || die "Could not delete the remote $BRANCH in $ORIGIN." git_do push "$ORIGIN" :"$BRANCH" || die "Could not delete the remote $BRANCH in $ORIGIN."
fi fi
else else
die "bugfix branch '$BRANCH' has been not been merged yet. Use -f to force the deletion." die "bugfix branch '$BRANCH' has been not been merged yet. Use -f to force the deletion."
fi fi
fi fi
gitflow_config_remove_base_section "$BRANCH" gitflow_config_remove_base_section "$BRANCH"
run_post_hook "$NAME" "$ORIGIN" "$BRANCH" run_post_hook "$NAME" "$ORIGIN" "$BRANCH"
echo echo
echo "Summary of actions:" echo "Summary of actions:"
echo "- bugfix branch '$BRANCH' has been deleted." echo "- bugfix branch '$BRANCH' has been deleted."
flag remote && echo "- bugfix branch '$BRANCH' in '$ORIGIN' has been deleted." flag remote && echo "- bugfix branch '$BRANCH' in '$ORIGIN' has been deleted."
echo "- You are now on branch '$(git_current_branch)'" echo "- You are now on branch '$(git_current_branch)'"
echo echo
} }
...@@ -230,16 +230,11 @@ F,[no]fetch Fetch from origin before performing local operation ...@@ -230,16 +230,11 @@ F,[no]fetch Fetch from origin before performing local operation
echo "How long do you think this feature will take in hours (e.g 1.5)?" echo "How long do you think this feature will take in hours (e.g 1.5)?"
read TIME_REQUIRED read TIME_REQUIRED
PROJECT="$(basename $(git rev-parse --show-toplevel))"
breakout-flow -nf $NAME -p $PROJECT
echo $TIME_REQUIRED >> "./.git/.gitflow/.timelog-feature-$NAME" breakout-flow -lf $NAME -p $PROJECT -m "Time Required:$TIME_REQUIRED"
git add .
git commit --allow-empty -m "--Flow message(start) -- Started working on $BRANCH on $(date) estimated Time $TIME_REQUIRED hour(s)"
echo $(date +%s) >> "./.git/.gitflow/.timelog-feature-$NAME"
echo echo
echo "Summary of actions:" echo "Summary of actions:"
...@@ -444,29 +439,16 @@ no-ff! Never fast-forward during the merge ...@@ -444,29 +439,16 @@ no-ff! Never fast-forward during the merge
# When no merge conflict is detected, just clean up the feature branch # When no merge conflict is detected, just clean up the feature branch
gitflow_config_remove_base_branch "$BRANCH" gitflow_config_remove_base_branch "$BRANCH"
echo $(date +%s) >> "./.git/.gitflow/.timelog-feature-$NAME" ######################
LAST_TIME=$(tail -1 .git/.gitflow/.timelog-feature-$NAME | head -1) #TODO
PREV_TIME=$(tail -2 .git/.gitflow/.timelog-feature-$NAME | head -1) #Insert timer here
TIME_USED=$((LAST_TIME-PREV_TIME)) PROJECT="$(basename $(git rev-parse --show-toplevel))"
echo "$TIME_USED" >> "./.git/.gitflow/.seconds-feature-$NAME" breakout-flow -lf $NAME -p $PROJECT -m "Finished $NAME, merges into $DEVELOP_BRANCH"
if [ -f ./.git/.gitflow/.breaktime-feature-$NAME ]; breakout-flow -xf $NAME -p $PROJECT
then
TOTAL_BREAK_TIME=$(awk '{ sum += $1 } END { print sum }' ./.git/.gitflow/.breaktime-feature-$NAME)
else
TOTAL_BREAK_TIME=0
fi
TOTAL_TIME=$(awk '{ sum += $1 } END { print sum }' ./.git/.gitflow/.seconds-feature-$NAME)
TIME_EXPECTED=$(head -n 1 ./.git/.gitflow/.timelog-feature-$NAME)
FINALTIME=$((TOTAL_TIME/86400))" days "$(date -d "1970-01-01 + $TOTAL_TIME seconds" "+%H hours %M minutes %S seconds")
TOTAL_TIME_OFF=$((TOTAL_BREAK_TIME/86400))" days "$(date -d "1970-01-01 + $TOTAL_BREAK_TIME seconds" "+%H hours %M minutes %S seconds")
git commit --allow-empty -m "--Flow message(finish) --$BRANCH was completed on $(date), total time taken:$FINALTIME expectde time was $TIME_EXPECTED hour(s), Time spent on breaks was $TOTAL_TIME_OFF"
helper_finish_cleanup helper_finish_cleanup
} }
...@@ -573,9 +555,15 @@ showcommands! Show git commands while executing them ...@@ -573,9 +555,15 @@ showcommands! Show git commands while executing them
git_do push -u "$ORIGIN" "$BRANCH:$BRANCH" git_do push -u "$ORIGIN" "$BRANCH:$BRANCH"
git_do fetch -q "$ORIGIN" "$BRANCH" || die "Could not fetch branch '$BRANCH' from remote '$ORIGIN'." 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'." git_do checkout "$BRANCH" || die "Could not check out branch '$BRANCH'."
run_post_hook "$NAME" "$ORIGIN" "$BRANCH" run_post_hook "$NAME" "$ORIGIN" "$BRANCH"
PROJECT="$(basename $(git rev-parse --show-toplevel))"
breakout-flow -lf $NAME -p $PROJECT -m "Published $NAME sent for review"
echo echo
echo "Summary of actions:" echo "Summary of actions:"
echo "- The remote branch '$BRANCH' was created or updated" echo "- The remote branch '$BRANCH' was created or updated"
...@@ -891,31 +879,18 @@ cmd_pause() { ...@@ -891,31 +879,18 @@ cmd_pause() {
current_name=$(echo "$current_branch" | sed "s ^$PREFIX g") current_name=$(echo "$current_branch" | sed "s ^$PREFIX g")
echo $(date +%s) >> "./.git/.gitflow/.timelog-feature-$current_name"
LAST_TIME=$(tail -1 .git/.gitflow/.timelog-feature-$current_name | head -1)
PREV_TIME=$(tail -2 .git/.gitflow/.timelog-feature-$current_name | head -1)
TIME_USED=$((LAST_TIME-PREV_TIME))
echo "$TIME_USED" >> "./.git/.gitflow/.seconds-feature-$current_name"
seconds=$TIME_USED; TIMESTAMP=$((seconds/86400))" days "$(date -d "1970-01-01 + $seconds seconds" "+%H hours %M minutes %S seconds")
git add --all . git add --all .
git commit -m "$current_branch/WIP" git commit -m "$current_branch/WIP"
git commit --allow-empty -m "--Flow message(pause) -- $current_branch/WIP time-paused:$(date), time taken thus far:$TIMESTAMP"
git checkout -b "$current_branch-paused" "flopharn" git checkout -b "$current_branch-paused" "flopharn"
git rm * --quiet --ignore-unmatch git rm * --quiet --ignore-unmatch
PROJECT="$(basename $(git rev-parse --show-toplevel))"
breakout-flow -lf $NAME -p $PROJECT -m "Took a break"
breakout-flow -hf $NAME -p $PROJECT
echo echo
echo "Summary of actions:" echo "Summary of actions:"
...@@ -947,37 +922,26 @@ cmd_interrupt() { ...@@ -947,37 +922,26 @@ cmd_interrupt() {
current_branch=$(git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g') current_branch=$(git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g')
current_name=$(echo "$current_branch" | sed "s ^$PREFIX g") current_name=$(echo "$current_branch" | sed "s ^$PREFIX g")
echo "dummy" >> "./$DOT_GIT_DIR/.gitflow/.interrupt-feature-$current_name"
echo $(date +%s) >> "./.git/.gitflow/.timelog-feature-$current_name"
LAST_TIME=$(tail -1 .git/.gitflow/.timelog-feature-$current_name | head -1)
PREV_TIME=$(tail -2 .git/.gitflow/.timelog-feature-$current_name | head -1)
TIME_USED=$((LAST_TIME-PREV_TIME))
echo "$TIME_USED" >> "./.git/.gitflow/.seconds-feature-$current_name"
echo "dummy" >> "./.git/.gitflow/.interrupt-feature-$current_name"
seconds=$TIME_USED; TIMESTAMP=$((seconds/86400))" days "$(date -d "1970-01-01 + $seconds seconds" "+%H hours %M minutes %S seconds")
git add --all . git add --all .
git commit -m "$current_branch/WIP" git commit -m "$current_branch/WIP"
git commit --allow-empty -m "--Flow message(interrupt) --$current_branch/WIP You were disturbed on $(date), time taken so far:$TIMESTAMP"
git checkout -b "$current_branch-paused" "flopharn" git checkout -b "$current_branch-paused" "flopharn"
git rm * --quiet --ignore-unmatch git rm * --quiet --ignore-unmatch
PROJECT="$(basename $(git rev-parse --show-toplevel))"
breakout-flow -lf $NAME -p $PROJECT -m "Was interrupted"
breakout-flow -hf $NAME -p $PROJECT
echo echo
echo "Summary of actions:" echo "Summary of actions:"
echo "- Created orphan branch called '$current_branch-paused'" echo "- Created orphan branch called '$current_branch-paused'"
echo "- You are now free to take a break, you have spent $TIMESTAMP in this session" echo "- You are now free to take a break"
echo "" echo ""
echo "Now, have some coffee and when you are done, use:" echo "Now, have some coffee and when you are done, use:"
echo "" echo ""
...@@ -994,46 +958,36 @@ Allows you to continue working on a feature after using pause or interrupt ...@@ -994,46 +958,36 @@ Allows you to continue working on a feature after using pause or interrupt
---- ----
h,help! Show this help h,help! Show this help
" "
PROJECT="$(basename $(git rev-parse --show-toplevel))"
parse_args "$@" parse_args "$@"
gitflow_require_name_arg gitflow_require_name_arg
# sanity checks # sanity checks
require_branch "$BRANCH" require_branch "$BRANCH"
if [ -f ./.git/.gitflow/.interrupt-feature-$NAME ]; if [ -f ./$DOT_GIT_DIR/.gitflow/.interrupt-feature-$NAME ];
then then
echo "Why were you interrupted?" echo "Why were you interrupted?"
read INTERRUPT_REASON read INTERRUPT_REASON
rm ./.git/.gitflow/.interrupt-feature-$NAME
breakout-flow -lf $NAME -p $PROJECT -m "Reason for interrupt $INTERRUPT_REASON"
else else
INTERRUPT_REASON="No reason :)" INTERRUPT_REASON="No reason :)"
fi fi
LAST_TIME=$(date +%s)
PREV_TIME=$(tail -1 .git/.gitflow/.timelog-feature-$NAME | head -1)
BREAK_TIME=$((LAST_TIME-PREV_TIME))
echo "$BREAK_TIME" >> "./.git/.gitflow/.breaktime-feature-$NAME"
seconds=$BREAK_TIME; TIME_OFF=$((seconds/86400))" days "$(date -d "1970-01-01 + $seconds seconds" "+%H hours %M minutes %S seconds")
git add . git add .
git commit --allow-empty -m "--Flow message(resume)"
git checkout "$BRANCH" git checkout "$BRANCH"
git branch -D "$BRANCH-paused" git branch -D "$BRANCH-paused"
git commit --allow-empty -m "--Flow message(resume) --$BRANCH/Back to Work at:$(date) Time off:$TIME_OFF, Reason: $INTERRUPT_REASON" breakout-flow -rf $NAME -p $PROJECT
echo $(date +%s) >> "./.git/.gitflow/.timelog-feature-$NAME"
echo echo
echo "Summary of actions:" echo "Summary of actions:"
...@@ -1074,30 +1028,10 @@ h,help! Show this help ...@@ -1074,30 +1028,10 @@ h,help! Show this help
git_do config "branch.$BRANCH.merge" "refs/heads/$BRANCH" git_do config "branch.$BRANCH.merge" "refs/heads/$BRANCH"
git_do checkout "$BRANCH" git_do checkout "$BRANCH"
PROJECT="$(basename $(git rev-parse --show-toplevel))"
breakout-flow -lf $NAME -p $PROJECT -m "Sent $NAME for review"
breakout-flow -xf $NAME -p $PROJECT
echo $(date +%s) >> "./.git/.gitflow/.timelog-feature-$NAME"
LAST_TIME=$(tail -1 .git/.gitflow/.timelog-feature-$NAME | head -1)
PREV_TIME=$(tail -2 .git/.gitflow/.timelog-feature-$NAME | head -1)
TIME_USED=$((LAST_TIME-PREV_TIME))
echo "$TIME_USED" >> "./.git/.gitflow/.seconds-feature-$NAME"
if [ -f ./.git/.gitflow/.breaktime-feature-$NAME ];
then
TOTAL_BREAK_TIME=$(awk '{ sum += $1 } END { print sum }' ./.git/.gitflow/.breaktime-feature-$NAME)
else
TOTAL_BREAK_TIME=0
fi
TOTAL_TIME=$(awk '{ sum += $1 } END { print sum }' ./.git/.gitflow/.seconds-feature-$NAME)
TIME_EXPECTED=$(head -n 1 ./.git/.gitflow/.timelog-feature-$NAME)
FINALTIME=$((TOTAL_TIME/86400))" days "$(date -d "1970-01-01 + $TOTAL_TIME seconds" "+%H hours %M minutes %S seconds")
TOTAL_TIME_OFF=$((TOTAL_BREAK_TIME/86400))" days "$(date -d "1970-01-01 + $TOTAL_BREAK_TIME seconds" "+%H hours %M minutes %S seconds")
git commit --allow-empty -m "--Flow message(finish) --$BRANCH was completed on $(date), total time taken:$FINALTIME expected time was $TIME_EXPECTED hour(s), Time spent on breaks was $TOTAL_TIME_OFF"
GIT_URL=$(git config --get remote.origin.url) GIT_URL=$(git config --get remote.origin.url)
GIT_URL_WITHOUT_SUFFIX="${GIT_URL%.*}" GIT_URL_WITHOUT_SUFFIX="${GIT_URL%.*}"
...@@ -1106,11 +1040,11 @@ h,help! Show this help ...@@ -1106,11 +1040,11 @@ h,help! Show this help
OWNER=$(basename $(echo $URL_WITH_OWNER | tr ":" /)) OWNER=$(basename $(echo $URL_WITH_OWNER | tr ":" /))
DEVELOPMENT_BRANCH=$(git config --get gitflow.branch.develop) DEVELOPMENT_BRANCH=$(git config --get gitflow.branch.develop)
if [ -f ./.git/.gitflow/.github_token ]; if [ -f ./$DOT_GIT_DIR/.gitflow/.github_token ];
then then
GITHUB_USERNAME=$(tail -1 ./.git/.gitflow/.github_username | head -1) GITHUB_USERNAME=$(tail -1 ./$DOT_GIT_DIR/.gitflow/.github_username | head -1)
GITHUB_TOKEN=$(tail -1 ./.git/.gitflow/.github_token | head -1) GITHUB_TOKEN=$(tail -1 ./$DOT_GIT_DIR/.gitflow/.github_token | head -1)
GITHUB_REQUEST=$(curl -X POST --write-out %{http_code} --silent --output /dev/null -H "Content-Type: application/json" \ GITHUB_REQUEST=$(curl -X POST --write-out %{http_code} --silent --output /dev/null -H "Content-Type: application/json" \
-H "Cache-Control: no-cache" \ -H "Cache-Control: no-cache" \
...@@ -1135,10 +1069,10 @@ h,help! Show this help ...@@ -1135,10 +1069,10 @@ h,help! Show this help
fi fi
if [ -f ./.git/.gitflow/.gitlab_token ]; if [ -f ./$DOT_GIT_DIR/.gitflow/.gitlab_token ];
then then
GITLAB_TOKEN=$(tail -1 ./.git/.gitflow/.gitlab_token | head -1) GITLAB_TOKEN=$(tail -1 ./$DOT_GIT_DIR/.gitflow/.gitlab_token | head -1)
USER_NAME=$(git config --get --global user.name) USER_NAME=$(git config --get --global user.name)
GITLAB_REQUEST=$(curl -X POST --write-out %{http_code} --silent --output /dev/null -H "PRIVATE-TOKEN: $GITLAB_TOKEN" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -H "Postman-Token: 209ed2f2-a7bd-ab33-a432-1d884669976b" -d '{ GITLAB_REQUEST=$(curl -X POST --write-out %{http_code} --silent --output /dev/null -H "PRIVATE-TOKEN: $GITLAB_TOKEN" -H "Content-Type: application/json" -H "Cache-Control: no-cache" -H "Postman-Token: 209ed2f2-a7bd-ab33-a432-1d884669976b" -d '{
......
...@@ -409,10 +409,13 @@ file= use given config file ...@@ -409,10 +409,13 @@ file= use given config file
mkdir -p "./.git/.gitflow" mkdir -p "./.git/.gitflow"
git checkout --orphan flopharn git checkout --orphan flopharn
git rm * --quiet --ignore-unmatch git rm * --quiet --ignore-unmatch
git commit --allow-empty -m "flopharn was created successfully" git commit --allow-empty -m "Git flow Initialized successfully"
git checkout $develop_branch git checkout $develop_branch
PROJECT="$(basename $(git rev-parse --show-toplevel))"
breakout-flow -np $PROJECT
if git remote -v | grep github > /dev/null if git remote -v | grep github > /dev/null
then then
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# #
GITFLOW_VERSION=0.4.11 GITFLOW_VERSION=0.5.5
initialize() { initialize() {
# A function can not be empty. Comments count as empty. # A function can not be empty. Comments count as empty.
......
gitflow @ 82ff372c
Subproject commit 82ff372cb151ec7dc3732e58c8bfc20b943fb98e
{ {
"name": "gitflow", "name": "gitflow",
"version": "0.4.11", "version": "0.5.5",
"description": "Modified gitflow for dreidev", "description": "Modified gitflow for dreidev",
"main": "src/index.js", "main": "src/index.js",
"scripts": { "scripts": {
"postinstall": "curl https://raw.githubusercontent.com/dreidev/gitflow/develop/contrib/gitflow-installer.sh > gitflow-installer.sh; chmod a+x gitflow-installer.sh; sudo bash gitflow-installer.sh install stable", "postinstall": "curl https://raw.githubusercontent.com/dreidev/gitflow/develop/contrib/gitflow-installer.sh > gitflow-installer.sh; chmod a+x gitflow-installer.sh; if [ -z ${TRAVIS+x} ]; then sudo bash gitflow-installer.sh install stable; else bash gitflow-installer.sh install stable;exit 0;fi",
"postuninstall": "curl https://raw.githubusercontent.com/dreidev/gitflow/develop/contrib/gitflow-installer.sh > gitflow-installer.sh; chmod a+x gitflow-installer.sh; sudo bash gitflow-installer.sh uninstall" "postuninstall": "curl https://raw.githubusercontent.com/dreidev/gitflow/develop/contrib/gitflow-installer.sh > gitflow-installer.sh; chmod a+x gitflow-installer.sh; if [ -z ${TRAVIS+x} ]; then sudo bash gitflow-installer.sh uninstall; else sudo gitflow-installer.sh uninstall;exit 0;fi"
}, },
"files": [ "files": [
"src/" "src/"
], ],
"bin": { "bin": {
"flow": "src/flow.js" "breakout-flow": "./node_modules/breakout-timeline/bin/index.js"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/dreidev/gitflow.git" "url": "git+https://github.com/dreidev/gitflow.git"
}, },
"os": [
"!win32"
],
"keywords": [ "keywords": [
"gitflow", "gitflow",
"dreidev", "dreidev",
"version", "version",
"control", "control",
"git", "git",
"drazious",
"cmosh" "cmosh"
], ],
"author": { "author": {
...@@ -31,13 +33,14 @@ ...@@ -31,13 +33,14 @@
"email": "clive@makamara.me", "email": "clive@makamara.me",
"url": "http://github.com/cmosh", "url": "http://github.com/cmosh",
"organization": "dreidev" "organization": "dreidev"
}, },
"license": "LGPL", "license": "MIT",
"bugs": { "bugs": {
"url": "https://github.com/dreidev/gitflow/issues" "url": "https://github.com/dreidev/gitflow/issues"
}, },
"homepage": "https://github.com/dreidev/gitflow#readme", "homepage": "https://github.com/dreidev/gitflow#readme",
"dependencies": { "dependencies": {
"breakout-timeline": "0.0.4",
"commander": "^2.9.0", "commander": "^2.9.0",
"shelljs": "^0.7.6" "shelljs": "^0.7.6"
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment