:
# This utility is used to generate a compact list of changes
# for each release, bjm 2000-02-22

# Usage $0 file

# no branches:	# cvs log -d '>1999-06-14 00:00:00 GMT' . > log
#
# pre and post-branch logs:
# find . -name CVS -type d -exec touch '{}/Entries.Static' \;
# cvs log -d'2000-05-08 00:00:00 GMT<2000-05-29 00:00:00 GMT'
# cvs log -d'>2000-05-29 00:00:00 GMT' -rREL7_1_STABLE
# cvs log -d'>1999-06-14 00:00:00 GMT' . > log
#
# pre and post-branch logs:
# find . -name CVS -type d -exec touch '{}/Entries.Static' \;
# cvs log -d'2000-05-08 00:00:00 GMT<2000-05-29 00:00:00 GMT'
# cvs log -d'>2000-05-29 00:00:00 GMT' -r       
# find . -name CVS -type d -exec rm '{}/Entries.Static' \;
#

cat "$@" |

# mark each line with a datetime and line number, for sorting and merging
# We don't print anything from the -- or == line and the date:

awk '
	# store working directory
	$0 ~ /^Working file:/	{workingfile = "/" $3}

	($0 ~ /^====*$/ || $0 ~ /^----*$/) \
	{
		# print blank line to separate entries
		if (datetime != "")
		{
			printf ("%s| %10d|%s\n", datetime, NR, "");
			printf ("%s| %10d|%s\n", datetime, NR, "---");
		}
		datetime="";
	}

	# if we have a saved datetime, print filename, date line, and committer
	datetime != "" {printf ("%s| %10d| %s\n", datetime, NR, $0);}

	$1 == "date:"	\
	{
		# get entry date
		datetime=$2"-"$3
		if (workingfile != "")
		{
			# remove semicolon from committers name
			gsub(";", "", $5);
			printf ("%s| %10d|%s\n", datetime, NR-2, workingfile);
			printf ("%s| %10d|%s\n", datetime, NR-1, $0);
			# output name of committer
			printf ("%s| %10d|  %70s\n", datetime, NR+1, $5);
		}
	}

	/* clear working file */
	$0 ~ /^====*$/	{workingfile=""}' |

sort | cut -d'|' -f3 | cat |

# collect duplicate narratives

awk '   BEGIN   { slot = 0; oldslot=0; save_working = ""; }
	{
		# We have a filename, so we look at the previous
		# narrative to see if it is new narrative text.
		#
		if ($0 ~ /^\//)
		{
			# If there are a different number of narrative
			# lines, they can not possibly be the same.
			if (slot != oldslot)
				same = "N";
			else
			{
				same = "Y";
				for (i=1; i <= slot; i++)
				{
					if (oldnarr[i] != narr[i])
					{
						same = "N";
						break;
					}
				}
			}

			# dump out the old narrative if it is new
			if (same == "N")
			{
				if (oldslot)
					for (i=1; i <= oldslot; i++)
						print oldnarr[i];

				# save the current narrative
				for (i=1; i <= slot; i++)
					oldnarr[i] = narr[i];
				oldslot = slot;
			}
			slot = 0;

			# dump out the previous filename
			print save_working;

			# store the current filename for later printing
			save_working = $0;
		}
		# we have a narrative line
		else if ($1 != "date:")
		{
			# accumulate narrative
			narr[++slot] = $0;
		}
	}
	END	{
			# dump out the last filename
			print save_working;

			# dump out the last narrative
			for (i=1; i <= slot; i++)
				print narr[i];
		}'
