#
# git-flow -- A collection of Git extensions to provide high-level
# repository operations for Vincent Driessen's branching model.
#
# Original blog post presenting this model is found at:
#    http://nvie.com/archives/323
#
# Feel free to contribute to this project at:
#    http://github.com/nvie/gitflow
#
# Copyright (c) 2010 by Vincent Driessen
# Copyright (c) 2010 by Benedikt Böhm
#

#
# Common functionality
#

# shell output
warn() { echo "$@" >&2; }
die() { warn "$@"; exit 1; }

# set logic
has() {
	local item=$1; shift
	echo " $@ " | grep -q " $item "
}

# 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 ]; }

#
# Git specific common functionality
#

git_local_branches() { git branch | sed 's/^[* ] //'; }
git_remote_branches() { git branch -r | sed 's/^[* ] //'; }
git_all_branches() { ( git branch; git branch -r) | sed 's/^[* ] //'; }
git_all_tags() { git tag; }

git_current_branch() {
	git branch | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g'
}

git_is_clean_working_tree() {
	if ! git diff --no-ext-diff --ignore-submodules --quiet --exit-code; then
		return 1
	elif ! git diff-index --cached --quiet --ignore-submodules HEAD --; then
		return 2
	else
		return 0
	fi
}

git_repo_is_headless() {
	! git rev-parse --quiet --verify HEAD >/dev/null 2>&1
}

git_local_branch_exists() {
	has $1 $(git_local_branches)
}

git_branch_exists() {
	has $1 $(git_all_branches)
}

git_tag_exists() {
	has $1 $(git_all_tags)
}

#
# git_compare_branches()
#
# Tests whether branches and their "origin" counterparts have diverged and need
# merging first. It returns error codes to provide more detail, like so:
#
# 0    Branch heads point to the same commit
# 1    First given branch needs fast-forwarding
# 2    Second given branch needs fast-forwarding
# 3    Branch needs a real merge
# 4    There is no merge base, i.e. the branches have no common ancestors
#
git_compare_branches() {
	local commit1=$(git rev-parse "$1")
	local commit2=$(git rev-parse "$2")
	if [ "$commit1" != "$commit2" ]; then
		local 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 succesfully merged into $2
#
git_is_branch_merged_into() {
	local subject=$1
	local base=$2
	local all_merges=$(git branch --contains $subject | sed 's/^[* ] //')
	has $base $all_merges
}

#
# gitflow specific common functionality
#

# check if this repo has been inited for gitflow
gitflow_has_master_configured() {
	local master=$(git config --get gitflow.branch.master)
	[ "$master" != "" ] && git_local_branch_exists "$master"
}

gitflow_has_develop_configured() {
	local develop=$(git config --get gitflow.branch.develop)
	[ "$develop" != "" ] && git_local_branch_exists "$develop"
}

gitflow_has_prefixes_configured() {
	git config --get gitflow.prefix.feature >/dev/null 2>&1     && \
	git config --get gitflow.prefix.release >/dev/null 2>&1     && \
	git config --get gitflow.prefix.hotfix >/dev/null 2>&1      && \
	git config --get gitflow.prefix.support >/dev/null 2>&1     && \
	git config --get gitflow.prefix.versiontag >/dev/null 2>&1
}

gitflow_is_initialized() {
	gitflow_has_master_configured                    && \
	gitflow_has_develop_configured                   && \
	[ "$(git config --get gitflow.branch.master)" !=    \
	  "$(git config --get gitflow.branch.develop)" ] && \
	gitflow_has_prefixes_configured
}

# loading settings that can be overridden using git config
gitflow_load_settings() {
	export DOT_GIT_DIR=$(git rev-parse --git-dir >/dev/null 2>&1)
	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_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=$1
	local prefix=$2
	local matches
	local num_matches

	# first, check if there is a perfect match
	if has "$(git_local_branches)" "$prefix$name"; then
		echo "$name"
		return 0
	fi

	matches=$(echo "$(git_local_branches)" | grep "^$prefix$name")
	num_matches=$(echo "$matches" | wc -l)
	if [ -z "$matches" ]; then
		# no prefix match, so take it literally
		warn "No branch matches 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
}

#
# Assertions for use in git-flow subcommands
#

require_git_repo() {
	if ! git rev-parse --git-dir >/dev/null 2>&1; then
		die "fatal: Not a git repository"
	fi
}

require_gitflow_initialized() {
	if ! gitflow_is_initialized; then
		die "fatal: Not a gitflow-enabled repo yet. Please run \"git flow init\" first."
	fi
}

require_clean_working_tree() {
	git_is_clean_working_tree
	local result=$?
	if [ $result -eq 1 ]; then
		die "fatal: Working tree contains unstaged changes. Aborting."
	fi
	if [ $result -eq 2 ]; then
		die "fatal: Index contains uncommited changes. Aborting."
	fi
}

require_local_branch() {
	if ! git_local_branch_exists $1; then
		die "fatal: Local branch '$1' does not exist and is required."
	fi
}

require_remote_branch() {
	if ! has $1 $(git_remote_branches); then
		die "Remote branch '$1' does not exist and is required."
	fi
}

require_branch() {
	if ! has $1 $(git_all_branches); then
		die "Branch '$1' does not exist and is required."
	fi
}

require_branch_absent() {
	if has $1 $(git_all_branches); then
		die "Branch '$1' already exists. Pick another name."
	fi
}

require_tag_absent() {
	if has $1 $(git_all_tags); then
		die "Tag '$1' already exists. Pick another name."
	fi
}

require_branches_equal() {
	require_local_branch "$1"
	require_remote_branch "$2"
	git_compare_branches "$1" "$2"
	local status=$?
	if [ $status -gt 0 ]; then
		warn "Branches '$1' and '$2' have diverged."
		if [ $status -eq 1 ]; then
			die "And branch '$1' may be fast-forwarded."
		elif [ $status -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
}
