#!/bin/bash
#
# Compares multiple branches against a reference and shows which ones contain
# each commit, and the level of backports since the origin or its own ancestors.
#
# Copyright (c) 2016 Willy Tarreau <w@1wt.eu>
#
# The purpose is to make it easy to visualize what backports might be missing
# in a maintenance branch, and to easily spot the ones that are needed and the
# ones that are not. It solely relies on the "cherry-picked from" tags in the
# commit messages to find what commit is available where, and can even find a
# reference commit's ancestor in another branch's commit ancestors as well to
# detect that the patch is present. When done with the proper references and
# a correct ordering of the branches, it can be used to quickly apply a set of
# fixes to a branch since it dumps suggested commands at the end. When doing
# so it is a good idea to use "HEAD" as the last branch to avoid doing mistakes.
#
# Examples :
# - find what's in master and not in current branch :
#   show-backports -q -m -r master HEAD
# - find what's in 1.6/master and in hapee-maint-1.5r2 but not in current branch :
#   show-backports -q -m -r 1.6/master hapee-maint-1.5r2 HEAD | grep ' [a-f0-9]\{8\}[-+][0-9] '
# - check that no recent fix from master is missing in any maintenance branch :
#   show-backports -r master hapee-maint-1.5r2 aloha-7.5 hapee-maint-1.5r1 aloha-7.0
# - see what was recently merged into 1.6 and has no equivalent in local master :
#   show-backports -q -m -r 1.6/master -b "1.6/master@{1 week ago}" master
# - check what extra backports are present in hapee-r2 compared to hapee-r1 :
#   show-backports -q -m -r hapee-r2 hapee-r1


USAGE="Usage: ${0##*/} [-q] [-H] [-m] [-u] [-r reference] [-l logexpr] [-s subject] [-b base] {branch|range} [...]"
BASES=( )
BRANCHES=( )
REF=master
BASE=
QUIET=
LOGEXPR=
SUBJECT=
MISSING=
UPSTREAM=
BODYHASH=

die() {
	[ "$#" -eq 0 ] || echo "$*" >&2
	exit 1
}

err() {
	echo "$*" >&2
}

quit() {
	[ "$#" -eq 0 ] || echo "$*"
	exit 0
}

short() {
	# git rev-parse --short $1
	echo "${1::8}"
}

dump_commit_matrix() {
	title=":$REF:"
	for branch in "${BRANCHES[@]}"; do
		#echo -n " $branch"
		title="$title :${branch}:"
	done
	title="$title |"

	count=0
	# now look up commits
	while read ref subject; do
		if [ -n "$MISSING" -a "${subject:0:9}" = "[RELEASE]" ]; then
			continue
		fi

		upstream="none"
		missing=0
		refbhash=""
		line=""
		for branch in "${BRANCHES[@]}"; do
			set -- $(grep -m 1 $ref "$WORK/${branch//\//_}")
			newhash=$1 ; shift
			bhash=""
			# count the number of cherry-picks after this one. Since we shift,
			# the result is in "$#"
			while [ -n "$1" -a "$1" != "$ref" ]; do
				shift
			done
			if [ -n "$newhash" ]; then
				line="${line} $(short $newhash)-$#"
			else
				# before giving up we can check if our current commit was
				# itself cherry-picked and check this again. In order not
				# to have to do it all the time, we can cache the result
				# for the current line. If a match is found we report it
				# with the '+' delimiter instead of '-'.
				if [ "$upstream" = "none" ]; then
					upstream=( $(git log -1 --pretty --format=%B "$ref" | \
						sed -n 's/^commit \([^)]*\) upstream\.$/\1/p;s/^(cherry picked from commit \([^)]*\))/\1/p') )
				fi
				newhash=""
				for h in ${upstream[@]}; do
					set -- $(grep -m 1 $h "$WORK/${branch//\//_}")
					newhash=$1 ; shift
					while [ -n "$1" -a "$1" != "$h" ]; do
						shift
					done
					if [ -n "$newhash" ]; then
						line="${line} $(short $newhash)+$#"
						break
					fi
				done
				if [ -z "$newhash" -a -n "$BODYHASH" ]; then
					if [ -z "$refbhash" ]; then
						refbhash=$(git log -1 --pretty="%an|%ae|%at|%B" "$ref" | sed -n '/^\(Signed-off-by\|(cherry picked\)/q;p' | md5sum)
					fi


					set -- $(grep -m 1 "H$refbhash\$" "$WORK/${branch//\//_}")
					newhash=$1 ; shift
					if [ -n "$newhash" ]; then
						line="${line} $(short $newhash)+?"
						break
					fi
				fi
				if [ -z "$newhash" ]; then
					line="${line} -"
					missing=1
				fi
			fi
		done
		line="${line} |"
		if [ -z "$MISSING" -o $missing -gt 0 ]; then
			[ $((count++)) -gt 0 ] || echo $title
			[ "$QUIET" != "" -o $count -lt 20 ] || count=0
			if [ -z "$UPSTREAM" -o "$upstream" = "none" -o -z "$upstream" ]; then
				echo "$(short $ref) $line"
			else
				echo "$(short $upstream) $line"
			fi
		fi
	done < "$WORK/${REF//\//_}"
}

while [ -n "$1" -a -z "${1##-*}" ]; do
	case "$1" in
		-b)        BASE="$2"      ; shift 2 ;;
		-r)        REF="$2"       ; shift 2 ;;
		-l)        LOGEXPR="$2"   ; shift 2 ;;
		-s)        SUBJECT="$2"   ; shift 2 ;;
		-q)        QUIET=1        ; shift   ;;
		-m)        MISSING=1      ; shift   ;;
		-u)        UPSTREAM=1     ; shift   ;;
		-H)        BODYHASH=1     ; shift   ;;
		-h|--help) quit "$USAGE" ;;
		*)         die  "$USAGE" ;;
	esac
done

# branches may also appear as id1..id2 to limit the history instead of looking
# back to the common base. The field is left empty if not set.
BRANCHES=( )
BASES=( )
while [ $# -gt 0 ]; do
	branch="${1##*..}"
	if [ "$branch" == "$1" ]; then
		base=""
	else
		base="${1%%..*}"
	fi
	BASES[${#BRANCHES[@]}]="$base"
	BRANCHES[${#BRANCHES[@]}]="$branch"
	shift
done

if [ ${#BRANCHES[@]} = 0 ]; then
	die "$USAGE"
fi

for branch in "$REF" "${BRANCHES[@]}"; do
	if ! git rev-parse --verify -q "$branch" >/dev/null; then
		die "Failed to check git branch $branch."
	fi
done

if [ -z "$BASE" ]; then
	err "Warning! No base specified, looking for common ancestor."
	BASE=$(git merge-base --all "$REF" "${BRANCHES[@]}")
	if [ -z "$BASE" ]; then
		die "Couldn't find a common ancestor between these branches"
	fi
fi

# we want to go to the git root dir
DIR="$PWD"
cd $(git rev-parse --show-toplevel)

mkdir -p .git/.show-backports #|| die "Can't create .git/.show-backports"
WORK=.git/.show-backports

rm -f "$WORK/${REF//\//_}"
git log --reverse ${LOGEXPR:+--grep $LOGEXPR} --pretty="%H %s" "$BASE".."$REF" | grep "${SUBJECT}" > "$WORK/${REF//\//_}"

# for each branch, enumerate all commits and their ancestry

branch_num=0;
while [ $branch_num -lt "${#BRANCHES[@]}" ]; do
	branch="${BRANCHES[$branch_num]}"
	base="${BASES[$branch_num]}"
	base="${base:-$BASE}"
	rm -f "$WORK/${branch//\//_}"
	git log --reverse --pretty="%H %s" "$base".."$branch" | grep "${SUBJECT}" | while read h subject; do
		echo -n "$h" $(git log -1 --pretty --format=%B "$h" | \
			sed -n 's/^commit \([^)]*\) upstream\.$/\1/p;s/^(cherry picked from commit \([^)]*\))/\1/p')
		if [ -n "$BODYHASH" ]; then
			echo " H$(git log -1 --pretty="%an|%ae|%at|%B" "$h" | sed -n '/^\(Signed-off-by\|(cherry picked\)/q;p' | md5sum)"
		else
			echo
		fi
	done > "$WORK/${branch//\//_}"
	(( branch_num++ ))
done

count=0
dump_commit_matrix | column -t | \
(
	left_commits=( )
	right_commits=( )
	while read line; do
		# append the subject at the end of the line
		set -- $line
		echo -n "$line "
		if [ "${line::1}" = ":" ]; then
			echo "---- Subject ----"
		else
			# doing it this way prevents git from abusing the terminal
			echo $(git log -1 --pretty="%s" "$1")
			left_commits[${#left_commits[@]}]="$1"
			comm=""
			while [ -n "$1" -a "$1" != "-" -a "$1" != "|" ]; do
				comm="${1%-*}"
				shift
			done
			right_commits[${#right_commits[@]}]="$comm"
		fi
	done
	if [ -n "$MISSING" -a ${#left_commits[@]} -eq 0 ]; then
		echo "No missing commit to apply."
	elif [ -n "$MISSING" ]; then
		echo
		echo "In order to show and/or apply all leftmost commits to current branch :"
		echo "   git show ${left_commits[@]}"
		echo "   git cherry-pick -x ${left_commits[@]}"
		echo
		echo "In order to show and/or apply all rightmost commits to current branch :"
		echo "   git show ${right_commits[@]}"
		echo "   git cherry-pick -x ${right_commits[@]}"
	fi
)
