#!/bin/bash
#
# Generate a web page of recent commits.
# (c) 2005 Randy Dunlap.
#
# Based on 'gitfeedmaillist.sh' by David Woodhouse, which was:
# Based on 'gitlog.sh' originally written by (c) Ross Vandegrift.
# Adapted to his scripts set by (c) Petr Baudis, 2005.
# Major optimizations by (c) Phillip Lougher.
#
# Takes an id resolving to a commit to start from (HEAD by default).

### Missing:
###	locks;
###	any command-line args;

STAGINGDIR=.html
HTMLFILE=$STAGINGDIR/newindex.$$.html
BIGPATCH=$STAGINGDIR/cset-`date -u '+%Y%m%d_%H%M'`.txt

[ -d $STAGINGDIR ] || mkdir $STAGINGDIR || exit 1
rm -f $STAGINGDIR/*
touch $HTMLFILE

# CL = commits list, CM = commits message, MD = message dir., DS = diffstat
TMPCL=$(mktemp -t gitweb.XXXXXX)
TMPCM=$(mktemp -t gitweb.XXXXXX)
TMPDS=$(mktemp -t gitweb.XXXXXX)
TMPMD=$(mktemp -td gitweb.XXXXXX)
###echo "### TMPCL=$TMPCL, TMPCM=$TMPCM, TMPMD=$TMPMD, TMPDS=$TMPDS"

write_html_header() {
    cat >> $HTMLFILE <<EOF
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Linux kernel patches for `hostname`:</title>
  </head>

  <body>
  <H1>Linux kernel patches since '<$lastweb>': $changecount changesets</H1>

  <H2><A HREF="$BIGPATCH.gz">Gzipped full patch since '<$lastweb>'</A></H2>
  (diffstat at end)<br>

EOF
}

# arg1 is filename whose contents to _add_ to web page output.
write_web_page() {
    echo "<HR>" >> $HTMLFILE
    echo "<pre>" >> $HTMLFILE
    cat $1 >> $HTMLFILE
    echo "</pre>" >> $HTMLFILE
    cat $1 >> $BIGPATCH
}

create_no_changes() {
    echo "<H3>No changes since last tag</h3>" >> $HTMLFILE
}

write_diffstat() {
    diffstat -p1 $BIGPATCH > $TMPDS
    echo "<HR>" >> $HTMLFILE
    echo "<pre>" >> $HTMLFILE
    cat $TMPDS >> $HTMLFILE
    echo "</pre>" >> $HTMLFILE
}

write_html_footer() {
    cat >> $HTMLFILE <<EOF
  <HR>
  Index generated at `date -u`
  </body>
</HTML>
EOF
}

# takes an object and generates the object's parent(s)
get_commit_objects () {
	local parents new_parent
	declare -a new_parent

	new_parent=("$@")
	parents=$#

	while [ $parents -gt 0 ]; do
		parent=${new_parent[$(($parents - 1))]}

		echo $parent >> $TMPCL

		cat-file commit $parent >$TMPCM

		parents=0
		ignoredparents=0
		lastparent=
		SUBJECT=
		while read type text; do
			if [ "$type" = "" ]; then
				read SUBJECT
				break;
			elif [ $type = 'parent' ]; then
			    if grep -q $text $TMPCL; then
				ignoredparents=$(($ignoredparents + 1))
				lastparent=$text
			    else
				new_parent[$parents]=$text
				parents=$(($parents + 1))
			    fi
			fi
		done < $TMPCM
		if [ $(($parents + $ignoredparents)) -eq 1 ]; then
		    [ -z "$lastparent" ] && lastparent=${new_parent[0]}
		    # Only one parent; not a merge. Use this cset.
		    (
		    cat $TMPCM
		    echo
		    git diff $lastparent $parent > $TMPCM
		    diffstat $TMPCM 2>/dev/null
		    echo 
		    cat $TMPCM
		    ) > $TMPMD/$parent
		    changecount=$(($changecount + 1))
		fi

		i=0
		while [ $i -lt $(($parents - 1)) ]; do
			changelog ${new_parent[$i]}
			i=$(($i + 1))
		done
	done
}

if [ ! -e .git/tags/WebDone ]; then
    mkdir .git/tags
    touch .git/tags/WebDone
fi

if [ -z $2 ]; then
    lastweb=`cat .git/tags/WebDone`
else
    lastweb=$(gitXnormid.sh -c $2)
fi

#if [ -z $3 ]; then
#    tagname=`ls -rt .git/tags | grep -v WebDone | tail -1`
#    release=`cat .git/tags/$tagname`
#else
#    release=$(gitXnormid.sh -c $3)
#fi    

base=$(gitXnormid.sh -c $1) || exit 1

###echo "### base=<$base>, lastweb=<$lastweb>"

if [ "$base" != "$lastweb" ]; then
    # List the commits at which we should stop following the tree, because
    # we've come back to commits which were already in $lastweb.
    rev-tree --edges $base $lastweb | sed 's/[a-z0-9]*:1//g' >> $TMPCL
    cat $TMPCL

    changecount=0
    get_commit_objects $base
    ###echo "### changecount: $changecount"

    # No 'git tag -F' -- cheat.
    echo $base > .git/tags/WebDone

    write_html_header

    if [ "$changecount" -eq 0 ] ; then
	create_no_changes
    else
	tac $TMPCL | while read commit; do
	    if [ -r "$TMPMD/$commit" ]; then
		write_web_page "$TMPMD/$commit"
	    fi
	done
	write_diffstat
	gzip $BIGPATCH
    fi

    write_html_footer
    mv $HTMLFILE $STAGINGDIR/index.html
fi

rm -rf $TMPCL $TMPCM $TMPDS $TMPMD
