#!/bin/sh
#
# Copyright (c) Josef "Jeff" Sipek, 2007-2013
#

USAGE="[<hash> | <since>..[<until>] | ..<until>]"
if [ -z "$GUILT_VERSION" ]; then
	echo "Invoking `basename "$0"` directly is no longer supported." >&2
	exit 1
fi

_main() {

while [ $# -gt 0 ]; do
	case "$1" in
		-h|--help)
			usage ;;
		-*)
			usage ;;
		*)
			break
	esac
done

if [ $# -ne 1 ] || [ -z "$1" ]; then
	die "You must specify a range of commits"
fi

rhash=`munge_hash_range $1`

# make sure that there are no unapplied changes
if ! must_commit_first; then
	die "Uncommited changes detected. Refresh first."
fi

disp "About to begin conversion..." >&2
disp "Current head: `git rev-parse \`git_branch\``" >&2

for rev in `git rev-list $rhash`; do
	s=`git log --no-decorate --pretty=oneline -1 $rev | cut -c 42-`

	# Try to convert the first line of the commit message to a
	# valid patch name.
	fname=`printf %s "$s" | sed -e "s/&/and/g" -e "s/[ :]/_/g" -e "s,[/\\],-,g" \
			-e "s/['\\[{}<>(),$]//g" -e 's/]//g' -e 's/\*/-/g' \
			-e 's/\?/-/g' -e 's/\.\.\.*/./g' -e 's/^\.//' \
			-e 's/\.patch$//' -e 's/\.$//' | tr A-Z a-z`

	if [ `expr length "$fname"` -gt 80 ] ; then
		# Limit the patch length to about 80 chars.  While this is
		# arbitrary, we have to have a limit to avoid trying to
		# create filenames that are too long for the filesystem to
		# handle.
		fname=`expr substr "$fname" 1 80`
	fi

	if ! valid_patchname "$fname"; then
		# Try harder to make it a legal commit name by
		# removing all but a few safe characters.
		fname=`echo $fname|tr -d -c _a-zA-Z0-9---/\\n`
	fi
	if ! valid_patchname "$fname"; then
		# If we failed to derive a legal patch name, use the
		# name "x".  (If this happens, we likely have to
		# append a suffix to make the name unique.)
		fname=x
	fi

	disp "Converting `echo $rev | cut -c 1-8` as $fname"

	mangle_prefix=1
	fname_base=$fname
	while [ -f "$GUILT_DIR/$branch/$fname.patch" ]; do
		fname="$fname_base-$mangle_prefix"
	        mangle_prefix=`expr $mangle_prefix + 1`
		disp "Patch under that name exists...trying '$fname'"
	done
	fname="$fname".patch

	(
		do_make_header $rev
		echo ""
		git diff --binary $rev^..$rev
	) > "$GUILT_DIR/$branch/$fname"

	# FIXME: grab the GIT_AUTHOR_DATE from the commit object and set the
	# timestamp on the patch

	# insert the patch name into the series file
	series_insert_patch $fname

	# Only reset if the commit was on this branch
	if head_check $rev 2> /dev/null; then
		# BEWARE: "git reset" ahead! Is there a way to verify that
		# we really created a patch? - We don't want to lose any
		# history.
		git reset --hard $rev^ > /dev/null
	elif [ -z "$warned" ]; then
		disp "Warning: commit $rev is not the HEAD...preserving commit" >&2
		disp "Warning: (this message is displayed only once)" >&2
		warned=t
	fi
done

disp "Done." >&2
disp "Current head: `git rev-parse \`git_branch\``" >&2

}
