Merge branch 'feature/fix-gitflow-function-prefixes' into develop
diff --git a/git-flow-feature b/git-flow-feature
index d005648..0256e8a 100644
--- a/git-flow-feature
+++ b/git-flow-feature
@@ -12,8 +12,8 @@
 # Copyright (c) 2010 by Benedikt Böhm
 #
 
-gitflow_require_git_repo
-gitflow_require_initialized
+require_git_repo
+require_gitflow_initialized
 gitflow_load_settings
 PREFIX=$(git config --get gitflow.prefix.feature)
 
@@ -38,7 +38,7 @@
 	local feature_branches
 	local current_branch
 	local short_names
-	feature_branches=$(echo "$(gitflow_local_branches)" | grep "^$PREFIX")
+	feature_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX")
 	if [ -z "$feature_branches" ]; then
 		warn "No feature branches exist."
 		exit 0
@@ -102,7 +102,7 @@
 
 	local expanded_name
 	local exitcode
-	expanded_name=$(resolve_nameprefix "$NAME" "$PREFIX")
+	expanded_name=$(gitflow_resolve_nameprefix "$NAME" "$PREFIX")
 	exitcode=$?
 	case $exitcode in
 		0) NAME=$expanded_name
@@ -115,9 +115,9 @@
 expand_nameprefix_arg_or_current() {
 	if [ "$NAME" != "" ]; then
 		expand_nameprefix_arg
-		gitflow_require_branch "$PREFIX$NAME"
+		require_branch "$PREFIX$NAME"
 	else
-		local current_branch=$(gitflow_current_branch)
+		local current_branch=$(git_current_branch)
 		if startswith "$current_branch" "$PREFIX"; then
 			BRANCH=$current_branch
 			NAME=${BRANCH#$PREFIX}
@@ -149,16 +149,16 @@
 
 	# sanity checks
 	if noflag force; then
-		gitflow_require_clean_working_tree
+		require_clean_working_tree
 	fi
-	gitflow_require_branch_absent "$BRANCH"
+	require_branch_absent "$BRANCH"
 
 	# update the local repo with remote changes, if asked
 	if flag fetch; then
 		git fetch -q "$ORIGIN" "$DEVELOP_BRANCH"
 	fi
 
-	gitflow_require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
+	require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
 
 	# create branch
 	if ! git checkout -b "$BRANCH" "$BASE"; then
@@ -184,7 +184,7 @@
 	expand_nameprefix_arg
 
 	# sanity checks
-	gitflow_require_branch "$BRANCH"
+	require_branch "$BRANCH"
 
 	# detect if we're restoring from a merge conflict
 	if [ -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE" ]; then
@@ -194,16 +194,16 @@
 		# (although he/she should).
 		# 
 
-		# TODO: gitflow_test_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
 		# actually be testing for here
-		if gitflow_test_clean_working_tree; then
+		if git_is_clean_working_tree; then
 			FINISH_BASE=$(cat "$DOT_GIT_DIR/.gitflow/MERGE_BASE")
 
 			# Since the working tree is now clean, either the user did a
 			# succesfull merge manually, or the merge was cancelled.
-			# We detect this using gitflow_is_branch_merged_into()
-			if gitflow_is_branch_merged_into "$BRANCH" "$FINISH_BASE"; then
+			# We detect this using git_is_branch_merged_into()
+			if git_is_branch_merged_into "$BRANCH" "$FINISH_BASE"; then
 				rm -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE"
 				helper_finish_cleanup
 				exit 0
@@ -227,17 +227,17 @@
 	fi
 
 	# sanity checks
-	gitflow_require_clean_working_tree
+	require_clean_working_tree
 
 	# update local repo with remote changes first, if asked
 	if flag fetch; then
 		git fetch -q "$ORIGIN" "$BRANCH"
 	fi
 
-	if has "$ORIGIN/$BRANCH" "$(gitflow_remote_branches)"; then
-		gitflow_require_branches_equal "$BRANCH" "$ORIGIN/$BRANCH"
+	if has "$ORIGIN/$BRANCH" "$(git_remote_branches)"; then
+		require_branches_equal "$BRANCH" "$ORIGIN/$BRANCH"
 	fi
-	gitflow_require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
+	require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
 
 	# if the user wants to rebase, do that first
 	if flag rebase; then
@@ -280,8 +280,8 @@
 
 helper_finish_cleanup() {
 	# sanity checks
-	gitflow_require_branch "$BRANCH"
-	gitflow_require_clean_working_tree
+	require_branch "$BRANCH"
+	require_clean_working_tree
 
 	# delete branch
 	if flag fetch; then
@@ -303,10 +303,10 @@
 	expand_nameprefix_arg
 
 	# sanity checks
-	gitflow_require_clean_working_tree
-	gitflow_require_branch "$BRANCH"
+	require_clean_working_tree
+	require_branch "$BRANCH"
 	git fetch -q "$ORIGIN"
-	gitflow_require_branch_absent "$ORIGIN/$BRANCH"
+	require_branch_absent "$ORIGIN/$BRANCH"
 
 	# create remote branch
 	git push "$ORIGIN" "$BRANCH:refs/heads/$BRANCH"
@@ -330,10 +330,10 @@
 	require_name_arg
 
 	# sanity checks
-	gitflow_require_clean_working_tree
-	gitflow_require_branch_absent "$BRANCH"
+	require_clean_working_tree
+	require_branch_absent "$BRANCH"
 	git fetch -q "$ORIGIN"
-	gitflow_require_branch "$ORIGIN/$BRANCH"
+	require_branch "$ORIGIN/$BRANCH"
 
 	# create tracking branch
 	git checkout -b "$BRANCH" "$ORIGIN/$BRANCH"
@@ -353,7 +353,7 @@
 		BASE=$(git merge-base "$DEVELOP_BRANCH" "$BRANCH")
 		git diff "$BASE..$BRANCH"
 	else
-		if ! gitflow_current_branch | grep -q "^$PREFIX"; then
+		if ! git_current_branch | grep -q "^$PREFIX"; then
 			die "Not on a feature branch. Name one explicitly."
 		fi
 
@@ -367,8 +367,8 @@
 	parse_args "$@"
 	expand_nameprefix_arg_or_current
 	warn "Will try to rebase '$NAME'..."
-	gitflow_require_clean_working_tree
-	gitflow_require_branch "$BRANCH"
+	require_clean_working_tree
+	require_branch "$BRANCH"
 
 	git checkout -q "$BRANCH"
 	local OPTS=
diff --git a/git-flow-hotfix b/git-flow-hotfix
index 347b811..2c0ec45 100644
--- a/git-flow-hotfix
+++ b/git-flow-hotfix
@@ -12,8 +12,8 @@
 # Copyright (c) 2010 by Benedikt Böhm
 #
 
-gitflow_require_git_repo
-gitflow_require_initialized
+require_git_repo
+require_gitflow_initialized
 gitflow_load_settings
 VERSION_PREFIX=$(git config --get gitflow.prefix.versiontag)
 PREFIX=$(git config --get gitflow.prefix.hotfix)
@@ -35,7 +35,7 @@
 	local hotfix_branches
 	local current_branch
 	local short_names
-	hotfix_branches=$(echo "$(gitflow_local_branches)" | grep "^$PREFIX")
+	hotfix_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX")
 	if [ -z "$hotfix_branches" ]; then
 		warn "No hotfix branches exist."
 		exit 0
@@ -116,7 +116,7 @@
 }
 
 require_no_existing_hotfix_branches() {
-	local hotfix_branches=$(echo "$(gitflow_local_branches)" | grep "^$PREFIX")
+	local hotfix_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX")
 	local first_branch=$(echo ${hotfix_branches} | head -n1)
 	first_branch=${first_branch#$PREFIX}
 	[ -z "$hotfix_branches" ] || \
@@ -132,13 +132,13 @@
 	require_no_existing_hotfix_branches
 
 	# sanity checks
-	gitflow_require_clean_working_tree
-	gitflow_require_branch_absent "$BRANCH"
-	gitflow_require_tag_absent "$VERSION_PREFIX$VERSION"
+	require_clean_working_tree
+	require_branch_absent "$BRANCH"
+	require_tag_absent "$VERSION_PREFIX$VERSION"
 	if flag fetch; then
 		git fetch -q "$ORIGIN" "$MASTER_BRANCH"
 	fi
-	gitflow_require_branches_equal "$MASTER_BRANCH" "$ORIGIN/$MASTER_BRANCH"
+	require_branches_equal "$MASTER_BRANCH" "$ORIGIN/$MASTER_BRANCH"
 
 	# create branch
 	git checkout -b "$BRANCH" "$BASE"
@@ -172,21 +172,21 @@
 	fi
 
 	# sanity checks
-	gitflow_require_branch "$BRANCH"
-	gitflow_require_clean_working_tree
+	require_branch "$BRANCH"
+	require_clean_working_tree
 	if flag fetch; then
 		git fetch -q "$ORIGIN" "$MASTER_BRANCH" || \
 		  die "Could not fetch $MASTER_BRANCH from $ORIGIN."
 		git fetch -q "$ORIGIN" "$DEVELOP_BRANCH" || \
 		  die "Could not fetch $DEVELOP_BRANCH from $ORIGIN."
 	fi
-	gitflow_require_branches_equal "$MASTER_BRANCH" "$ORIGIN/$MASTER_BRANCH"
-	gitflow_require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
+	require_branches_equal "$MASTER_BRANCH" "$ORIGIN/$MASTER_BRANCH"
+	require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
 
 	# try to merge into master
 	# in case a previous attempt to finish this release branch has failed,
 	# but the merge into master was successful, we skip it now
-	if ! gitflow_is_branch_merged_into "$BRANCH" "$MASTER_BRANCH"; then
+	if ! git_is_branch_merged_into "$BRANCH" "$MASTER_BRANCH"; then
 		git checkout "$MASTER_BRANCH" || \
 		  die "Could not check out $MASTER_BRANCH."
 		git merge --no-ff "$BRANCH" || \
@@ -198,7 +198,7 @@
 	# in case a previous attempt to finish this release branch has failed,
 	# but the tag was set successful, we skip it now
 	local tagname=$VERSION_PREFIX$VERSION
-	if ! gitflow_tag_exists "$tagname"; then
+	if ! git_tag_exists "$tagname"; then
 		local opts="-a"
 		flag sign && opts="$opts -s"
 		[ "$FLAGS_signingkey" != "" ] && opts="$opts -u '$FLAGS_signingkey'"
@@ -210,7 +210,7 @@
 	# try to merge into develop
 	# in case a previous attempt to finish this release branch has failed,
 	# but the merge into develop was successful, we skip it now
-	if ! gitflow_is_branch_merged_into "$BRANCH" "$DEVELOP_BRANCH"; then
+	if ! git_is_branch_merged_into "$BRANCH" "$DEVELOP_BRANCH"; then
 		git checkout "$DEVELOP_BRANCH" || \
 		  die "Could not check out $DEVELOP_BRANCH."
 
diff --git a/git-flow-init b/git-flow-init
index 364420a..d533934 100644
--- a/git-flow-init
+++ b/git-flow-init
@@ -31,7 +31,7 @@
 		git init
 	else
 		# assure that we are not working in a repo with local changes
-		git_repo_is_headless || gitflow_require_clean_working_tree
+		git_repo_is_headless || require_clean_working_tree
 	fi
 
 	# running git flow init on an already initialized repo is fine
@@ -57,7 +57,7 @@
 		#    rather allow to use existing branches for git-flow.
 		local default_suggestion
 		local should_check_existence
-		branch_count=$(gitflow_local_branches | wc -l)
+		branch_count=$(git_local_branches | wc -l)
 		if [ "$branch_count" -eq 0 ]; then
 			echo "No branches exist yet. Base branches must be created now."
 			should_check_existence=NO
@@ -65,12 +65,12 @@
 		else
 			echo
 			echo "Which branch should be used for bringing forth production releases?"
-			gitflow_local_branches | sed 's/^.*$/   - &/g'
+			git_local_branches | sed 's/^.*$/   - &/g'
 
 			should_check_existence=YES
 			default_suggestion=
 			for guess in 'production' 'main' 'master'; do
-				if gitflow_local_branch_exists "$guess"; then
+				if git_local_branch_exists "$guess"; then
 					default_suggestion="$guess"
 					break
 				fi
@@ -83,7 +83,7 @@
 
 		# check existence in case of an already existing repo
 		if [ "$should_check_existence" = "YES" ]; then
-			gitflow_local_branch_exists "$master_branch" || \
+			git_local_branch_exists "$master_branch" || \
 				die "Local branch '$master_branch' does not exist."
 		fi
 
@@ -100,19 +100,19 @@
 		# considered (fresh repo or repo that contains branches)
 		local default_suggestion
 		local should_check_existence
-		branch_count=$(gitflow_local_branches | grep -v "^${master_branch}\$" | wc -l)
+		branch_count=$(git_local_branches | grep -v "^${master_branch}\$" | wc -l)
 		if [ "$branch_count" -eq 0 ]; then
 			should_check_existence=NO
 			default_suggestion=develop
 		else
 			echo
 			echo "Which branch should be used for integration of the \"next release\"?"
-			gitflow_local_branches | grep -v "^${master_branch}\$" | sed 's/^.*$/   - &/g'
+			git_local_branches | grep -v "^${master_branch}\$" | sed 's/^.*$/   - &/g'
 
 			should_check_existence=YES
 			default_suggestion=
 			for guess in 'develop' 'int' 'integration' 'master'; do
-				if gitflow_local_branch_exists "$guess"; then
+				if git_local_branch_exists "$guess"; then
 					default_suggestion="$guess"
 					break
 				fi
@@ -129,7 +129,7 @@
 
 		# check existence in case of an already existing repo
 		if [ "$should_check_existence" = "YES" ]; then
-			gitflow_local_branch_exists "$develop_branch" || \
+			git_local_branch_exists "$develop_branch" || \
 				die "Local branch '$develop_branch' does not exist."
 		fi
 
@@ -160,7 +160,7 @@
 	# in a git init'ed repo with one or more commits, master was picked as the
 	# default production branch and develop was "created".  We should create
 	# the develop branch now in that case (we base it on master, of course)
-	if ! gitflow_local_branch_exists "$develop_branch"; then
+	if ! git_local_branch_exists "$develop_branch"; then
 		git branch "$develop_branch" "$master_branch"
 		created_gitflow_branch=1
 	fi
diff --git a/git-flow-release b/git-flow-release
index 9aedf3c..21ad19a 100644
--- a/git-flow-release
+++ b/git-flow-release
@@ -12,8 +12,8 @@
 # Copyright (c) 2010 by Benedikt Böhm
 #
 
-gitflow_require_git_repo
-gitflow_require_initialized
+require_git_repo
+require_gitflow_initialized
 gitflow_load_settings
 VERSION_PREFIX=$(git config --get gitflow.prefix.versiontag)
 PREFIX=$(git config --get gitflow.prefix.release)
@@ -46,7 +46,7 @@
 	local release_branches
 	local current_branch
 	local short_names
-	release_branches=$(echo "$(gitflow_local_branches)" | grep "^$PREFIX")
+	release_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX")
 	if [ -z "$release_branches" ]; then
 		warn "No release branches exist."
 		exit 0
@@ -122,7 +122,7 @@
 }
 
 require_no_existing_release_branches() {
-	local release_branches=$(echo "$(gitflow_local_branches)" | grep "^$PREFIX")
+	local release_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX")
 	local first_branch=$(echo ${release_branches} | head -n1)
 	first_branch=${first_branch#$PREFIX}
 	[ -z "$release_branches" ] || \
@@ -138,13 +138,13 @@
 	require_no_existing_release_branches
 
 	# sanity checks
-	gitflow_require_clean_working_tree
-	gitflow_require_branch_absent "$BRANCH"
-	gitflow_require_tag_absent "$VERSION_PREFIX$VERSION"
+	require_clean_working_tree
+	require_branch_absent "$BRANCH"
+	require_tag_absent "$VERSION_PREFIX$VERSION"
 	if flag fetch; then
 		git fetch -q "$ORIGIN" "$DEVELOP_BRANCH"
 	fi
-	gitflow_require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
+	require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
 
 	# create branch
 	git checkout -b "$BRANCH" "$BASE"
@@ -179,21 +179,21 @@
 	fi
 
 	# sanity checks
-	gitflow_require_branch "$BRANCH"
-	gitflow_require_clean_working_tree
+	require_branch "$BRANCH"
+	require_clean_working_tree
 	if flag fetch; then
 		git fetch -q "$ORIGIN" "$MASTER_BRANCH" || \
 		  die "Could not fetch $MASTER_BRANCH from $ORIGIN."
 		git fetch -q "$ORIGIN" "$DEVELOP_BRANCH" || \
 		  die "Could not fetch $DEVELOP_BRANCH from $ORIGIN."
 	fi
-	gitflow_require_branches_equal "$MASTER_BRANCH" "$ORIGIN/$MASTER_BRANCH"
-	gitflow_require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
+	require_branches_equal "$MASTER_BRANCH" "$ORIGIN/$MASTER_BRANCH"
+	require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
 
 	# try to merge into master
 	# in case a previous attempt to finish this release branch has failed,
 	# but the merge into master was successful, we skip it now
-	if ! gitflow_is_branch_merged_into "$BRANCH" "$MASTER_BRANCH"; then
+	if ! git_is_branch_merged_into "$BRANCH" "$MASTER_BRANCH"; then
 		git checkout "$MASTER_BRANCH" || \
 		  die "Could not check out $MASTER_BRANCH."
 		git merge --no-ff "$BRANCH" || \
@@ -205,7 +205,7 @@
 	# in case a previous attempt to finish this release branch has failed,
 	# but the tag was set successful, we skip it now
 	local tagname=$VERSION_PREFIX$VERSION
-	if ! gitflow_tag_exists "$tagname"; then
+	if ! git_tag_exists "$tagname"; then
 		local opts="-a"
 		flag sign && opts="$opts -s"
 		[ "$FLAGS_signingkey" != "" ] && opts="$opts -u '$FLAGS_signingkey'"
@@ -217,7 +217,7 @@
 	# try to merge into develop
 	# in case a previous attempt to finish this release branch has failed,
 	# but the merge into develop was successful, we skip it now
-	if ! gitflow_is_branch_merged_into "$BRANCH" "$DEVELOP_BRANCH"; then
+	if ! git_is_branch_merged_into "$BRANCH" "$DEVELOP_BRANCH"; then
 		git checkout "$DEVELOP_BRANCH" || \
 		  die "Could not check out $DEVELOP_BRANCH."
 
diff --git a/git-flow-support b/git-flow-support
index 8a8ac56..f3e2eb3 100644
--- a/git-flow-support
+++ b/git-flow-support
@@ -12,8 +12,8 @@
 # Copyright (c) 2010 by Benedikt Böhm
 #
 
-gitflow_require_git_repo
-gitflow_require_initialized
+require_git_repo
+require_gitflow_initialized
 gitflow_load_settings
 VERSION_PREFIX=$(git config --get gitflow.prefix.versiontag)
 PREFIX=$(git config --get gitflow.prefix.support)
@@ -37,7 +37,7 @@
 	local support_branches
 	local current_branch
 	local short_names
-	support_branches=$(echo "$(gitflow_local_branches)" | grep "^$PREFIX")
+	support_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX")
 	if [ -z "$support_branches" ]; then
 		warn "No support branches exist."
 		exit 0
@@ -134,13 +134,13 @@
 	require_base_is_on_master
 
 	# sanity checks
-	gitflow_require_clean_working_tree
+	require_clean_working_tree
 
 	# fetch remote changes
 	if flag fetch; then
 		git fetch -q "$ORIGIN" "$BASE"
 	fi
-	gitflow_require_branch_absent "$BRANCH"
+	require_branch_absent "$BRANCH"
 
 	# create branch
 	git checkout -b "$BRANCH" "$BASE"
diff --git a/gitflow-common b/gitflow-common
index 9702818..ad1de80 100644
--- a/gitflow-common
+++ b/gitflow-common
@@ -12,6 +12,10 @@
 # Copyright (c) 2010 by Benedikt Böhm
 #
 
+#
+# Common functionality
+#
+
 # shell output
 warn() { echo "$@" >&2; }
 die() { warn "$@"; exit 1; }
@@ -38,15 +42,97 @@
 # 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" != "" ] && gitflow_local_branch_exists "$master"
+	[ "$master" != "" ] && git_local_branch_exists "$master"
 }
 
 gitflow_has_develop_configured() {
 	local develop=$(git config --get gitflow.branch.develop)
-	[ "$develop" != "" ] && gitflow_local_branch_exists "$develop"
+	[ "$develop" != "" ] && git_local_branch_exists "$develop"
 }
 
 gitflow_has_prefixes_configured() {
@@ -65,12 +151,6 @@
 	gitflow_has_prefixes_configured
 }
 
-# get all available branches
-gitflow_local_branches() { git branch | sed 's/^[* ] //'; }
-gitflow_remote_branches() { git branch -r | sed 's/^[* ] //'; }
-gitflow_all_branches() { ( git branch; git branch -r) | sed 's/^[* ] //'; }
-gitflow_all_tags() { git tag; }
-
 # 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)
@@ -80,13 +160,13 @@
 }
 
 #
-# resolve_nameprefix
+# gitflow_resolve_nameprefix
 #
 # Inputs:
 # $1 = name prefix to resolve
 # $2 = branch prefix to use
 #
-# Searches branch names from gitflow_local_branches() to look for a unique
+# 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:
@@ -95,19 +175,19 @@
 # 1: No match is found.
 # 2: Multiple matches found. These matches are written to stderr
 #
-resolve_nameprefix() {
+gitflow_resolve_nameprefix() {
 	local name=$1
 	local prefix=$2
 	local matches
 	local num_matches
 
 	# first, check if there is a perfect match
-	if has "$(gitflow_local_branches)" "$prefix$name"; then
+	if has "$(git_local_branches)" "$prefix$name"; then
 		echo "$name"
 		return 0
 	fi
 
-	matches=$(echo "$(gitflow_local_branches)" | grep "^$prefix$name")
+	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
@@ -128,38 +208,24 @@
 	fi
 }
 
-gitflow_current_branch() {
-	git branch | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g'
-}
+#
+# Assertions for use in git-flow subcommands
+#
 
-gitflow_test_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
-}
-
-gitflow_require_git_repo() {
+require_git_repo() {
 	if ! git rev-parse --git-dir >/dev/null 2>&1; then
 		die "fatal: Not a git repository"
 	fi
 }
 
-gitflow_require_initialized() {
+require_gitflow_initialized() {
 	if ! gitflow_is_initialized; then
 		die "fatal: Not a gitflow-enabled repo yet. Please run \"git flow init\" first."
 	fi
 }
 
-git_repo_is_headless() {
-	! git rev-parse --quiet --verify HEAD >/dev/null 2>&1
-}
-
-gitflow_require_clean_working_tree() {
-	gitflow_test_clean_working_tree
+require_clean_working_tree() {
+	git_is_clean_working_tree
 	local result=$?
 	if [ $result -eq 1 ]; then
 		die "fatal: Working tree contains unstaged changes. Aborting."
@@ -169,83 +235,40 @@
 	fi
 }
 
-gitflow_local_branch_exists() {
-	has $1 $(gitflow_local_branches)
-}
-
-gitflow_branch_exists() {
-	has $1 $(gitflow_all_branches)
-}
-
-gitflow_tag_exists() {
-	has $1 $(gitflow_all_tags)
-}
-
-gitflow_require_local_branch() {
-	if ! gitflow_local_branch_exists; then
+require_local_branch() {
+	if ! git_local_branch_exists $1; then
 		die "fatal: Local branch '$1' does not exist and is required."
 	fi
 }
 
-gitflow_require_remote_branch() {
-	if ! has $1 $(gitflow_remote_branches); then
+require_remote_branch() {
+	if ! has $1 $(git_remote_branches); then
 		die "Remote branch '$1' does not exist and is required."
 	fi
 }
 
-gitflow_require_branch() {
-	if ! has $1 $(gitflow_all_branches); then
+require_branch() {
+	if ! has $1 $(git_all_branches); then
 		die "Branch '$1' does not exist and is required."
 	fi
 }
 
-gitflow_require_branch_absent() {
-	if has $1 $(gitflow_all_branches); then
+require_branch_absent() {
+	if has $1 $(git_all_branches); then
 		die "Branch '$1' already exists. Pick another name."
 	fi
 }
 
-gitflow_require_tag_absent() {
-	if has $1 $(gitflow_all_tags); then
+require_tag_absent() {
+	if has $1 $(git_all_tags); then
 		die "Tag '$1' already exists. Pick another name."
 	fi
 }
 
-#
-# gitflow_test_branches_equal()
-#
-# 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
-#
-gitflow_test_branches_equal() {
-	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
-}
-
-gitflow_require_branches_equal() {
-	gitflow_require_local_branch "$1"
-	gitflow_require_remote_branch "$2"
-	gitflow_test_branches_equal "$1" "$2"
+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."
@@ -259,15 +282,3 @@
 		fi
 	fi
 }
-
-#
-# gitflow_is_branch_merged_into()
-#
-# Checks whether branch $1 is succesfully merged into $2
-#
-gitflow_is_branch_merged_into() {
-	local subject=$1
-	local base=$2
-	local all_merges=$(git branch --contains $subject | sed 's/^[* ] //')
-	has $base $all_merges
-}