Initial class construction
This commit is contained in:
810
Git/usr/bin/gitflow-common
Normal file
810
Git/usr/bin/gitflow-common
Normal file
@ -0,0 +1,810 @@
|
||||
# $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.
|
||||
#
|
||||
|
||||
#
|
||||
# Common functionality
|
||||
#
|
||||
|
||||
# Shell output
|
||||
warn() { echo "$@" >&2; }
|
||||
die() { warn "Fatal: $@"; exit 1; }
|
||||
die_help() { warn $@; flags_help; exit 1; }
|
||||
|
||||
escape() {
|
||||
echo "$1" | sed 's/\([\.\$\*]\)/\\\1/g'
|
||||
}
|
||||
|
||||
#
|
||||
# String contains function
|
||||
# $1 haystack
|
||||
# $2 Needle
|
||||
#
|
||||
contains() {
|
||||
local return
|
||||
|
||||
case $1 in
|
||||
*$2*)
|
||||
return=$FLAGS_TRUE
|
||||
;;
|
||||
*)
|
||||
return=$FLAGS_FALSE
|
||||
;;
|
||||
esac
|
||||
return $return
|
||||
}
|
||||
|
||||
# Basic math
|
||||
min() { [ "$1" -le "$2" ] && echo "$1" || echo "$2"; }
|
||||
max() { [ "$1" -ge "$2" ] && echo "$1" || echo "$2"; }
|
||||
|
||||
# Basic string matching
|
||||
startswith() { [ "$1" != "${1#$2}" ]; }
|
||||
endswith() { [ "$1" != "${1%$2}" ]; }
|
||||
|
||||
# Convenience functions for checking shFlags flags
|
||||
flag() { local FLAG; eval FLAG='$FLAGS_'$1; [ $FLAG -eq $FLAGS_TRUE ]; }
|
||||
noflag() { local FLAG; eval FLAG='$FLAGS_'$1; [ $FLAG -ne $FLAGS_TRUE ]; }
|
||||
|
||||
# check_boolean
|
||||
# Check if given value can be interpreted as a boolean
|
||||
#
|
||||
# This function determines if the passed parameter is a valid boolean value.
|
||||
#
|
||||
# Param $1: string Value to check if it's a valid boolean
|
||||
#
|
||||
# Return: string FLAGS_TRUE|FLAGS_FALSE|FLAGS_ERROR
|
||||
# FLAGS_TRUE if the parameter is a boolean TRUE
|
||||
# FLAGS_FALSE if the parameter is a boolean FALSE
|
||||
# FLAGS_ERROR if the parameter is not a boolean
|
||||
#
|
||||
check_boolean() {
|
||||
local _return _value
|
||||
_value="${1}"
|
||||
case "${_value}" in
|
||||
${FLAGS_TRUE} | [yY] | [yY][eE][sS] | [tT] | [tT][rR][uU][eE])
|
||||
_return=${FLAGS_TRUE}
|
||||
;;
|
||||
${FLAGS_FALSE} | [nN] | [nN][oO] | [fF] | [fF][aA][lL][sS][eE])
|
||||
_return=${FLAGS_FALSE}
|
||||
;;
|
||||
|
||||
*)
|
||||
_return=${FLAGS_ERROR}
|
||||
;;
|
||||
esac
|
||||
unset _value
|
||||
return ${_return}
|
||||
}
|
||||
|
||||
#
|
||||
# Git specific common functionality
|
||||
#
|
||||
|
||||
git_local_branches() { git for-each-ref --sort refname --format='%(refname:short)' refs/heads; }
|
||||
git_remote_branches() { git for-each-ref --sort refname --format='%(refname:short)' refs/remotes; }
|
||||
git_all_branches() { git for-each-ref --sort refname --format='%(refname:short)' refs/remotes refs/heads; }
|
||||
git_all_tags() { git for-each-ref --format='%(refname:short)' refs/tags; }
|
||||
|
||||
git_local_branches_prefixed() {
|
||||
[ -z $1 ] && die "Prefix parameter missing." # This should never happen.
|
||||
git for-each-ref --format='%(refname:short)' refs/heads/$1\* ;
|
||||
}
|
||||
|
||||
git_current_branch() {
|
||||
local branch_name
|
||||
|
||||
branch_name="$(git symbolic-ref --quiet HEAD)"
|
||||
[ -z $branch_name ] && branch_name="(unnamed branch)" || branch_name="$(git for-each-ref --format='%(refname:short)' $branch_name)"
|
||||
echo "$branch_name"
|
||||
}
|
||||
|
||||
git_is_clean_working_tree() {
|
||||
git rev-parse --verify HEAD >/dev/null || exit 1
|
||||
git update-index -q --ignore-submodules --refresh
|
||||
|
||||
# Check for unstaged changes
|
||||
git diff-files --quiet --ignore-submodules || return 1
|
||||
|
||||
# Check for Uncommited changes
|
||||
git diff-index --cached --quiet --ignore-submodules HEAD -- || return 2
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
git_repo_is_headless() {
|
||||
! git rev-parse --quiet --verify HEAD >/dev/null 2>&1
|
||||
}
|
||||
|
||||
git_local_branch_exists() {
|
||||
[ -n "$1" ] || die "Missing branch name"
|
||||
[ -n "$(git for-each-ref --format='%(refname:short)' refs/heads/$1)" ]
|
||||
}
|
||||
|
||||
git_remote_branch_exists() {
|
||||
[ -n "$1" ] || die "Missing branch name"
|
||||
[ -n "$(git for-each-ref --format='%(refname:short)' refs/remotes/$1)" ]
|
||||
}
|
||||
|
||||
git_remote_branch_delete() {
|
||||
[ -n "$1" ] || die "Missing branch name"
|
||||
if git_remote_branch_exists "$ORIGIN/$1"; then
|
||||
git_do push "$ORIGIN" :"$1" || die "Could not delete the remote $1 in $ORIGIN."
|
||||
return 0
|
||||
else
|
||||
warn "Trying to delete the remote branch $1, but it does not exists in $ORIGIN"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
git_branch_exists() {
|
||||
[ -n "$1" ] || die "Missing branch name"
|
||||
git_local_branch_exists "$1" || git_remote_branch_exists "$ORIGIN/$1"
|
||||
}
|
||||
|
||||
git_tag_exists() {
|
||||
[ -n "$1" ] || die "Missing tag name"
|
||||
[ -n "$(git for-each-ref --format='%(refname:short)' refs/tags/$1)" ]
|
||||
}
|
||||
|
||||
git_config_bool_exists() {
|
||||
local value
|
||||
|
||||
[ -n "$1" ] || die "Missing config option"
|
||||
value=$(git config --get --bool $1)
|
||||
[ "$value" = "true" ]
|
||||
}
|
||||
#
|
||||
# git_compare_refs()
|
||||
#
|
||||
# Tests whether two references have diverged and need merging
|
||||
# first. It returns error codes to provide more detail, like so:
|
||||
#
|
||||
# 0 References point to the same commit
|
||||
# 1 First given reference needs fast-forwarding
|
||||
# 2 Second given reference needs fast-forwarding
|
||||
# 3 References need a real merge
|
||||
# 4 There is no merge base, i.e. the references have no common ancestors
|
||||
#
|
||||
git_compare_refs() {
|
||||
local commit1 commit2 base
|
||||
|
||||
commit1=$(git rev-parse "$1"^{})
|
||||
commit2=$(git rev-parse "$2"^{})
|
||||
if [ "$commit1" != "$commit2" ]; then
|
||||
base=$(git merge-base "$commit1" "$commit2")
|
||||
if [ $? -ne 0 ]; then
|
||||
return 4
|
||||
elif [ "$commit1" = "$base" ]; then
|
||||
return 1
|
||||
elif [ "$commit2" = "$base" ]; then
|
||||
return 2
|
||||
else
|
||||
return 3
|
||||
fi
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# git_is_branch_merged_into()
|
||||
#
|
||||
# Checks whether branch $1 is successfully merged into $2
|
||||
#
|
||||
git_is_branch_merged_into() {
|
||||
local merge_hash base_hash
|
||||
|
||||
merge_hash=$(git merge-base "$1"^{} "$2"^{})
|
||||
base_hash=$(git rev-parse "$1"^{})
|
||||
|
||||
# If the hashes are equal, the branches are merged.
|
||||
[ "$merge_hash" = "$base_hash" ]
|
||||
}
|
||||
|
||||
#
|
||||
# git_is_ancestor()
|
||||
#
|
||||
# This is the same function as git_is_branch_merged_into but
|
||||
# for readability given a different name.
|
||||
#
|
||||
git_is_ancestor() {
|
||||
git_is_branch_merged_into "$1" "$2"
|
||||
}
|
||||
|
||||
#
|
||||
# git_fetch_branch()
|
||||
#
|
||||
# $1 Origin - Where to fetch from
|
||||
# $2 Branch - Which branch to fetch
|
||||
#
|
||||
# This fetches the given branch from the given origin.
|
||||
# Instead of storing it in FETCH_HEAD it will be stored in
|
||||
# refs/remotes/<origin>/<branch>
|
||||
#
|
||||
git_fetch_branch() {
|
||||
local origin branch
|
||||
|
||||
[ -n "$1" ] || die "Missing origin"
|
||||
[ -n "$2" ] || die "Missing branch name"
|
||||
origin="$1"
|
||||
branch="$2"
|
||||
if git_remote_branch_exists "$origin/$branch"; then
|
||||
git_do fetch -q "$origin" "$branch" || die "Could not fetch $branch from $origin."
|
||||
else
|
||||
warn "Trying to fetch branch '$origin/$branch' but it does not exist."
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# gitflow specific common functionality
|
||||
#
|
||||
|
||||
# Function used to check if the repository is git-flow enabled.
|
||||
gitflow_has_master_configured() {
|
||||
local master
|
||||
|
||||
master=$(git config --get gitflow.branch.master)
|
||||
[ "$master" != "" ] && git_local_branch_exists "$master"
|
||||
}
|
||||
|
||||
gitflow_has_develop_configured() {
|
||||
local develop
|
||||
|
||||
develop=$(git config --get gitflow.branch.develop)
|
||||
[ "$develop" != "" ] && git_local_branch_exists "$develop"
|
||||
}
|
||||
|
||||
gitflow_is_initialized() {
|
||||
gitflow_has_master_configured && \
|
||||
gitflow_has_develop_configured && \
|
||||
[ "$(git config --get gitflow.branch.master)" != "$(git config --get gitflow.branch.develop)" ] && \
|
||||
git config --get-regexp gitflow.prefix >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Loading settings that can be overridden using git config
|
||||
gitflow_load_settings() {
|
||||
export GIT_CURRENT_REPO_DIR="$(git rev-parse --show-toplevel 2>/dev/null)"
|
||||
DOT_GIT_DIR=$(git rev-parse --git-dir)
|
||||
export DOT_GIT_DIR="$(cd ${DOT_GIT_DIR} >/dev/null 2>&1 && pwd)"
|
||||
export HOOKS_DIR="$(git config --get gitflow.path.hooks || echo ${DOT_GIT_DIR}/hooks)" # the second option is used to support previous versions of git-flow
|
||||
export MASTER_BRANCH=$(git config --get gitflow.branch.master)
|
||||
export DEVELOP_BRANCH=$(git config --get gitflow.branch.develop)
|
||||
export ORIGIN=$(git config --get gitflow.origin || echo origin)
|
||||
|
||||
GITFLOW_CONFIG="$DOT_GIT_DIR/gitflow_config"
|
||||
if [ -f "$GITFLOW_CONFIG" ]; then # move all settings from old .git/gitflow_config to the local conf.
|
||||
warn "Migrating old \"$GITFLOW_CONFIG\" to the \"--local\" repo config."
|
||||
_config_lines=`git config --list --file="$GITFLOW_CONFIG"`;
|
||||
for _config_line in ${_config_lines}; do
|
||||
_key=${_config_line%=*}
|
||||
_value=${_config_line#=*}
|
||||
git_do config --local gitflow.${_key} ${_value}
|
||||
done;
|
||||
mv "$GITFLOW_CONFIG" "$GITFLOW_CONFIG".backup 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# gitflow_resolve_nameprefix
|
||||
#
|
||||
# Inputs:
|
||||
# $1 = name prefix to resolve
|
||||
# $2 = branch prefix to use
|
||||
#
|
||||
# Searches branch names from git_local_branches() to look for a unique
|
||||
# branch name whose name starts with the given name prefix.
|
||||
#
|
||||
# There are multiple exit codes possible:
|
||||
# 0: The unambiguous full name of the branch is written to stdout
|
||||
# (success)
|
||||
# 1: No match is found.
|
||||
# 2: Multiple matches found. These matches are written to stderr
|
||||
#
|
||||
gitflow_resolve_nameprefix() {
|
||||
local name prefix
|
||||
local match matches num_matches
|
||||
|
||||
name=$1
|
||||
prefix=$2
|
||||
|
||||
# first, check if there is a perfect match
|
||||
if git_local_branch_exists "$prefix$name"; then
|
||||
echo "$name"
|
||||
return 0
|
||||
fi
|
||||
|
||||
matches=$(echo "$(git_local_branches)" | grep "^$(escape "$prefix$name")")
|
||||
num_matches=$(echo "$matches" | wc -l)
|
||||
if [ -z "$matches" ]; then
|
||||
# no prefix match, so take it literally
|
||||
warn "No branches match '$prefix$name*'"
|
||||
return 1
|
||||
else
|
||||
if [ $num_matches -eq 1 ]; then
|
||||
echo "${matches#$prefix}"
|
||||
return 0
|
||||
else
|
||||
# multiple matches, cannot decide
|
||||
warn "Multiple branches match prefix '$name':"
|
||||
for match in $matches; do
|
||||
warn "- $match"
|
||||
done
|
||||
return 2
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Check if the given branch is a git-flow branch
|
||||
#
|
||||
gitflow_is_prefixed_branch() {
|
||||
local branch return
|
||||
|
||||
branch=$1
|
||||
case $branch in
|
||||
$(git config --get gitflow.prefix.feature)* | \
|
||||
$(git config --get gitflow.prefix.bugfix)* | \
|
||||
$(git config --get gitflow.prefix.release)* | \
|
||||
$(git config --get gitflow.prefix.hotfix)* | \
|
||||
$(git config --get gitflow.prefix.support)* )
|
||||
return=0
|
||||
;;
|
||||
*)
|
||||
return=1
|
||||
;;
|
||||
esac
|
||||
return $return
|
||||
}
|
||||
#
|
||||
# Update the config with the base of a new git-flow branch.
|
||||
#
|
||||
# @param $1 Base of the new branch
|
||||
# @param $2 Name of the branch
|
||||
#
|
||||
gitflow_config_set_base_branch() {
|
||||
local base branch
|
||||
|
||||
base=$1
|
||||
branch=$2
|
||||
$(git_do config --local "gitflow.branch.$branch.base" $base)
|
||||
}
|
||||
|
||||
#
|
||||
# Get the base of a branch as set by gitflow_set_branch
|
||||
#
|
||||
# @param $1 Name of the branch
|
||||
# @return string|empty String when a base is found otherwise empty
|
||||
#
|
||||
gitflow_config_get_base_branch() {
|
||||
local branch
|
||||
|
||||
branch=$1
|
||||
echo $(git config --local --get "gitflow.branch.$branch.base")
|
||||
}
|
||||
|
||||
#
|
||||
# Remove the section that contains the base of a branch as set by gitflow_set_branch
|
||||
#
|
||||
# @param $1 Name of the branch
|
||||
#
|
||||
gitflow_config_remove_base_section() {
|
||||
local branch
|
||||
|
||||
branch=$1
|
||||
$(git_do config --local --remove-section "gitflow.branch.$branch" 2>/dev/null)
|
||||
}
|
||||
|
||||
#
|
||||
# Remove the base of the git-flow branch from the.
|
||||
# @param $1 Name of the branch
|
||||
#
|
||||
gitflow_config_remove_base_branch() {
|
||||
local base
|
||||
|
||||
base=$1
|
||||
$(git_do config --local --unset "gitflow.branch.$branch.base" 2>/dev/null)
|
||||
}
|
||||
|
||||
#
|
||||
# Remove the base of the git-flow branch from the.
|
||||
# @param $1 Name of the branch
|
||||
#
|
||||
gitflow_config_rename_sections() {
|
||||
local new
|
||||
local old
|
||||
|
||||
old=$1
|
||||
new=$2
|
||||
$(git_do config --local --rename-section "gitflow.branch.$old" "gitflow.branch.$new" 2>/dev/null)
|
||||
}
|
||||
|
||||
# gitflow_override_flag_boolean()
|
||||
#
|
||||
# Override a boolean flag
|
||||
#
|
||||
# Param $1: string The name of the config variable e.g. "feature.start.fetch"
|
||||
# Param $2: string The flag name
|
||||
#
|
||||
gitflow_override_flag_boolean() {
|
||||
local _variable
|
||||
|
||||
_variable=$(git config --bool --get gitflow.$1 2>&1)
|
||||
case $? in
|
||||
0)
|
||||
[ "${_variable}" = "true" ] && eval "FLAGS_${2}=${FLAGS_TRUE}" || eval "FLAGS_${2}=${FLAGS_FALSE}"
|
||||
;;
|
||||
128)
|
||||
die "${_variable}"
|
||||
;;
|
||||
esac
|
||||
unset _variable
|
||||
return ${FLAGS_TRUE}
|
||||
}
|
||||
|
||||
# gitflow_override_flag_string()
|
||||
#
|
||||
# Override a string flag
|
||||
#
|
||||
# Param $1: string The name of the config variable e.g. "feature.start.fetch"
|
||||
# Param $2: string The flag name
|
||||
#
|
||||
gitflow_override_flag_string() {
|
||||
local _variable
|
||||
|
||||
_variable=$(git config --get gitflow.$1 2>&1)
|
||||
case $? in
|
||||
0)
|
||||
eval "FLAGS_${2}=\"${_variable}\""
|
||||
;;
|
||||
esac
|
||||
unset _variable
|
||||
return ${FLAGS_TRUE}
|
||||
}
|
||||
|
||||
# gitflow_create_squash_message()
|
||||
#
|
||||
# Create the squash message, overriding the one generated by git itself
|
||||
#
|
||||
# Param $1: string The line to be added
|
||||
# Param $2: string The base of the branch that will me merged
|
||||
# Param $3: string The branch that will be merged.
|
||||
#
|
||||
gitflow_create_squash_message() {
|
||||
echo Squashed commit of the following:
|
||||
echo
|
||||
echo $1
|
||||
echo
|
||||
git log --no-merges --pretty=medium ^"$2" $3
|
||||
}
|
||||
|
||||
#
|
||||
# Parameter functions
|
||||
#
|
||||
gitflow_require_name_arg() {
|
||||
if [ "$NAME" = "" ]; then
|
||||
die_help "Missing argument <name>"
|
||||
fi
|
||||
}
|
||||
|
||||
gitflow_expand_nameprefix_arg() {
|
||||
local expanded_name exitcode
|
||||
|
||||
gitflow_require_name_arg
|
||||
|
||||
expanded_name=$(gitflow_resolve_nameprefix "$NAME" "$PREFIX")
|
||||
exitcode=$?
|
||||
case $exitcode in
|
||||
0)
|
||||
NAME=$expanded_name
|
||||
BRANCH=$PREFIX$NAME
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
gitflow_require_version_arg() {
|
||||
if [ "$VERSION" = "" ]; then
|
||||
die_help "Missing argument <version>"
|
||||
fi
|
||||
}
|
||||
|
||||
gitflow_expand_versionprefix_arg() {
|
||||
local expanded_version exitcode
|
||||
|
||||
gitflow_require_version_arg
|
||||
|
||||
version=$(gitflow_resolve_nameprefix "$VERSION" "$PREFIX")
|
||||
exitcode=$?
|
||||
case $exitcode in
|
||||
0)
|
||||
VERSION=$version
|
||||
BRANCH=$PREFIX$VERSION
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
gitflow_require_base_arg() {
|
||||
if [ "$BASE" = "" ]; then
|
||||
die_help "Missing argument <base>"
|
||||
fi
|
||||
}
|
||||
|
||||
gitflow_use_current_branch_name() {
|
||||
local current_branch
|
||||
|
||||
current_branch=$(git_current_branch)
|
||||
|
||||
if startswith "$current_branch" "$PREFIX"; then
|
||||
BRANCH=$current_branch
|
||||
NAME=${BRANCH#$PREFIX}
|
||||
else
|
||||
warn "The current HEAD is no ${SUBCOMMAND} branch."
|
||||
warn "Please specify a <name> argument."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
gitflow_use_current_branch_version() {
|
||||
local current_branch
|
||||
|
||||
current_branch=$(git_current_branch)
|
||||
|
||||
if startswith "$current_branch" "$PREFIX"; then
|
||||
BRANCH=$current_branch
|
||||
VERSION=${BRANCH#$PREFIX}
|
||||
else
|
||||
warn "The current HEAD is no ${SUBCOMMAND} branch."
|
||||
warn "Please specify a <version> argument."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
gitflow_rename_branch() {
|
||||
# Parse arguments
|
||||
FLAGS "$@" || exit $?
|
||||
eval set -- "${FLAGS_ARGV}"
|
||||
|
||||
# read arguments into global variables
|
||||
if [ -z $1 ]; then
|
||||
NEW_NAME=''
|
||||
else
|
||||
NEW_NAME=$1
|
||||
fi
|
||||
|
||||
if [ -z $2 ]; then
|
||||
NAME=''
|
||||
else
|
||||
NAME=$2
|
||||
fi
|
||||
BRANCH=${PREFIX}${NAME}
|
||||
NEW_BRANCH=${PREFIX}${NEW_NAME}
|
||||
|
||||
if [ -z "$NEW_NAME" ]; then
|
||||
die "No new name given."
|
||||
fi
|
||||
|
||||
# Use current branch if no name is given
|
||||
if [ "$NAME" = "" ]; then
|
||||
gitflow_use_current_branch_name
|
||||
fi
|
||||
|
||||
|
||||
# Sanity checks
|
||||
require_branch "$BRANCH"
|
||||
require_branch_absent "$NEW_BRANCH"
|
||||
|
||||
run_pre_hook "$NAME" "$ORIGIN" "$BRANCH"
|
||||
git_do branch -m "$BRANCH" "$NEW_BRANCH" || die "Error renaming branch '$BRANCH' to '$NEW_BRANCH'"
|
||||
gitflow_config_rename_sections "$BRANCH" "$NEW_BRANCH"
|
||||
run_post_hook "$NAME" "$ORIGIN" "$BRANCH"
|
||||
|
||||
echo
|
||||
echo "Summary of actions:"
|
||||
echo "- Branch '$BRANCH' has been renamed to '$NEW_BRANCH'."
|
||||
echo "- You are now on branch '$(git_current_branch)'"
|
||||
echo
|
||||
}
|
||||
#
|
||||
# Assertions for use in git-flow subcommands
|
||||
#
|
||||
|
||||
require_git_repo() {
|
||||
git rev-parse 2>/dev/null || die "Not a git repository"
|
||||
}
|
||||
|
||||
require_gitflow_initialized() {
|
||||
gitflow_is_initialized || die "Not a gitflow-enabled repo yet. Please run 'git flow init' first."
|
||||
$(git config --get gitflow.prefix.versiontag >/dev/null 2>&1) || die "Version tag not set. Please run 'git flow init'."
|
||||
}
|
||||
|
||||
require_clean_working_tree() {
|
||||
local result
|
||||
|
||||
git_is_clean_working_tree
|
||||
result=$?
|
||||
if [ $result -eq 1 ]; then
|
||||
die "Working tree contains unstaged changes. Aborting."
|
||||
fi
|
||||
if [ $result -eq 2 ]; then
|
||||
die "Index contains uncommited changes. Aborting."
|
||||
fi
|
||||
}
|
||||
|
||||
require_base_is_local_branch() {
|
||||
git_local_branch_exists "$1" || die "Base '$1' needs to be a branch. It does not exist and is required."
|
||||
}
|
||||
|
||||
require_local_branch() {
|
||||
git_local_branch_exists "$1" || die "Local branch '$1' does not exist and is required."
|
||||
}
|
||||
|
||||
require_remote_branch() {
|
||||
git_remote_branch_exists "$1" || die "Remote branch '$1' does not exist and is required."
|
||||
}
|
||||
|
||||
require_branch() {
|
||||
git_branch_exists "$1" || die "Branch '$1' does not exist and is required."
|
||||
}
|
||||
|
||||
require_branch_absent() {
|
||||
git_branch_exists "$1" && die "Branch '$1' already exists. Pick another name."
|
||||
}
|
||||
|
||||
require_local_branch_absent() {
|
||||
git_local_branch_exists "$1" && die "Branch '$1' already exists. Pick another name."
|
||||
}
|
||||
|
||||
require_tag_absent() {
|
||||
git_tag_exists "$1" && die "Tag '$1' already exists. Pick another name."
|
||||
}
|
||||
|
||||
require_branches_equal() {
|
||||
local compare_refs_result
|
||||
|
||||
require_local_branch "$1"
|
||||
require_remote_branch "$2"
|
||||
git_compare_refs "$1" "$2"
|
||||
compare_refs_result=$?
|
||||
|
||||
if [ $compare_refs_result -gt 0 ]; then
|
||||
warn "Branches '$1' and '$2' have diverged."
|
||||
if [ $compare_refs_result -eq 1 ]; then
|
||||
die "And branch '$1' may be fast-forwarded."
|
||||
elif [ $compare_refs_result -eq 2 ]; then
|
||||
# Warn here, since there is no harm in being ahead
|
||||
warn "And local branch '$1' is ahead of '$2'."
|
||||
else
|
||||
die "Branches need merging first."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Show commands if flag is set.
|
||||
#
|
||||
git_do() {
|
||||
if flag showcommands; then
|
||||
echo "git $@" >&2
|
||||
fi
|
||||
|
||||
git "$@"
|
||||
}
|
||||
|
||||
#
|
||||
# run_filter_hook
|
||||
#
|
||||
# Looks for a Git hook script called as defined by the first variable
|
||||
#
|
||||
# filter-flow-command
|
||||
#
|
||||
# If such a hook script exists and is executable, it is called with the given
|
||||
# positional arguments.
|
||||
#
|
||||
run_filter_hook() {
|
||||
local command scriptfile return
|
||||
|
||||
command=$1
|
||||
shift
|
||||
scriptfile="${HOOKS_DIR}/filter-flow-${command}"
|
||||
if [ -x "$scriptfile" ]; then
|
||||
return=`$scriptfile "$@"`
|
||||
if [ $? -eq 127 ]; then
|
||||
echo "$return"
|
||||
exit 127
|
||||
fi
|
||||
echo $return
|
||||
else
|
||||
echo "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# run_pre_hook
|
||||
#
|
||||
# Looks for a Git hook script called
|
||||
#
|
||||
# pre-flow-<subcmd>-<subaction>
|
||||
#
|
||||
# If such a hook script exists and is executable, it is called with the given
|
||||
# positional arguments. If its return code non-zero, the git-flow action is
|
||||
# aborted.
|
||||
#
|
||||
run_pre_hook() {
|
||||
local scriptfile exitcode
|
||||
|
||||
scriptfile="${HOOKS_DIR}/pre-flow-${SUBCOMMAND}-${SUBACTION}"
|
||||
exitcode=0
|
||||
if [ -x "$scriptfile" ]; then
|
||||
"$scriptfile" "$@"
|
||||
exitcode=$?
|
||||
|
||||
if [ $exitcode -gt 0 ]; then
|
||||
die "Hook command $scriptfile ended with exit code $exitcode."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# run_post_hook
|
||||
#
|
||||
# Looks for a Git hook script called
|
||||
#
|
||||
# post-flow-<subcmd>-<subaction>
|
||||
#
|
||||
# If such a hook script exists and is executable, it is called with the given
|
||||
# positional arguments. Its return code is ignored.
|
||||
#
|
||||
run_post_hook() {
|
||||
local scriptfile
|
||||
|
||||
scriptfile="${HOOKS_DIR}/post-flow-${SUBCOMMAND}-${SUBACTION}"
|
||||
if [ -x "$scriptfile" ]; then
|
||||
"$scriptfile" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
flags_help() {
|
||||
eval "$( echo "$OPTIONS_SPEC" | git rev-parse --parseopt -- "-h" || echo exit $? )"
|
||||
}
|
Reference in New Issue
Block a user