#!/bin/sh

base= ignore_file=
while :
do
	case "$1" in
	--base=*)
		base=${1#*=} ;;
	--ignore=*)
		ignore_file=${1#*=} ;;
	-*)
		echo >&2 "Eh? $1"
		exit 1 ;;
	*)
		break ;;
	esac
	shift
done

if test -z "$base"
then
	describe=$(git describe "master")
	base=$(expr "$describe" : '\(.*\)-\([0-9]*\)-g[0-9a-f]*$') ||
	base="$describe"

	git rev-parse --verify "$base^0" >/dev/null 2>/dev/null || {
	    echo >&2 "Eh? where is your base?"
	    exit 1
	}
fi

topics= leftover= dothis=
LF='
'

ignores=
if test -f "$ignore_file"
then
	while read ignore rest
	do
		test -n "$ignore" &&
		if ignore=$(git rev-parse -q --verify $ignore)
		then
			:
		elif ignore=$(expr "$rest" : '.* \([0-9a-f]\{40\}\)$')
		then
			:
		else
			continue
		fi
		ignores="$ignores$ignore "
	done <"$ignore_file"
fi

defer () {
	leftover="$leftover$1$LF"
}

dothis () {
	dothis="$1$LF$LF$dothis"
}

one_topic () {
	topic="$2" tip="$3" date="$4" merged="$1"
	case " $topics" in *" $topic "*) return ;; esac
	topics="$topics$topic "

	contam_count=$(git rev-list "maint..$tip" | grep -F "$merges_to_master" | wc -l)
	if test "$contam_count" != 0
	then
		echo "**** forked from master $topic ****"
		return
	fi

	maint_count=$(git rev-list "maint..$tip" | wc -l)
	if test "$maint_count" = 0
	then
		echo "**** already merged $topic ****"
		return ;# already merged
	fi

	ready=no label=

	master_count=$(git rev-list "$base..$tip" | wc -l)
	if test $maint_count -le $master_count
	then
		mergeable=yes
	else
		mergeable=no
	fi

	if current=$(git rev-parse --verify -q "$topic^0") &&
	   test "$current" = "$tip"
	then
		ready=yes
		label="$topic"
	elif test -z "$current"
	then
		ready=yes
		label="$tip"
	fi

	case "$mergeable,$ready" in
	no,*)
		comment="# $topic: not mergeable ($master_count vs $maint_count)"
		comment="$comment$LF# $merged"
		defer "$comment"
		;;
	yes,no)
		topic_count=$(git rev-list "$base..$current" | wc -l)

		comment="# $topic: not ready ($master_count vs $topic_count)"
		comment="$comment$LF# $merged"
		defer "$comment"
		;;
	yes,yes)
		insn="$label"
		if test $maint_count = $master_count
		then
			insn="$insn # $master_count ($date) $merged"
		else
			insn="$insn # $maint_count/$master_count ($date) $merged"
		fi
		insn="$insn$LF$(git log --oneline "maint..$tip" | sed -e "s/^/# /")"
		dothis "$insn"
		;;
	esac
}

merges_to_master="$(git rev-list --merges $base..master)"

git log --first-parent --min-parents=2 --max-parents=2 \
	--format='%ci %H %P %s' "$base..master" | {
	while read date time zone commit parent tip subject
	do
		case " $ignores" in *" $commit "*) continue ;; esac
		topic=$(expr "$subject" : "Merge branch '\(.*\)'$") || {
			defer "# ignoring $commit ($subject)"
			continue
		}
		one_topic "$commit" "$topic" "$tip" "$date"
	done
	echo "$leftover"
	echo "$dothis"
}
