#!/bin/sh # $PostgreSQL: pgsql/src/tools/pgcvslog,v 1.34 2007/10/01 02:59:03 momjian Exp $ # This utility is used to generate a compact list of changes # for each release, bjm 2000-02-22 # Usage: pgcvslog [-h] # -h is HTML output # All branches: # cvs log -d'>1999-06-14 00:00:00 GMT' . > log # # HEAD: # cvs log -d'>2000-05-29 00:00:00 GMT' -b . # # Branch: # cvs log -d'>2000-05-29 00:00:00 GMT' -rREL8_0_STABLE . # # Date range # cvs log -d'2005-05-08<2005-05-29' -rREL8_0_STABLE . # # To find branch time, look for "branches:" tag in CVS commit logs # e.g. "branches: 1.398.4;" matches "REL8_0_STABLE: 1.398.0.4". # # Remove these from the log file before processing to reduce the number # of unneeded log entries: # # /cvsroot/pgsql/doc/TODO # /cvsroot/pgsql/doc/FAQ # /cvsroot/pgsql/doc/src/FAQ/TODO.html # /cvsroot/pgsql/doc/src/FAQ/FAQ.html # if [ "X$1" = "X-h" ] then HTML="Y" shift else HTML="N" fi cat "$@" | # protect HTML input if in HTML mode if [ "$HTML" = "Y" ] then sed -e 's/\&/\&/g' \ -e 's/</\</g' \ -e 's/>/\>/g' \ -e 's/"/\"/g' else cat fi | # mark each line with a datetime and line number, for sorting and merging # we are just pre-processing the file at this point # We don't print anything from the -- or == line and the date: awk ' BEGIN {html="'"$HTML"'"; lineno = 0;} # store working directory $0 ~ /^Working file:/ {workingfile = "/" $3} # no need to show TODO or FAQ changes in the output $0 !~ /^====*$/ && (workingfile == "/doc/TODO" || workingfile == "/doc/src/FAQ/TODO.html" || workingfile == "/doc/FAQ" || workingfile == "/doc/src/FAQ/FAQ.html") \ {next} ($0 ~ /^====*$/ || $0 ~ /^----*$/) \ { # print blank line to separate entries if (datetime != "") { if (html != "Y") printf ("%s| %10d|%s\n", datetime, lineno++, ""); printf ("%s| %10d|", datetime, lineno++); if (html != "Y") printf ("%s\n", "---"); else printf ("<HR>\n"); } datetime=""; } # if we have a saved datetime, print filename, date line, and committer datetime != "" && $1 != "branches:" {printf ("%s| %10d| %s\n", datetime, lineno++, $0);} $1 == "date:" \ { # get entry date datetime=$2"-"$3 if (workingfile != "") { printf ("%s| %10d|", datetime, lineno++); if (html != "Y") printf ("%s%s\n", workingfile, back_branch); else printf ("<SMALL><FONT COLOR=\"red\">%s%s</FONT></SMALL>\n", workingfile, back_branch); # output name of committer # remove semicolon from committers name gsub("/", "-", $2); gsub(";", "", $3); gsub(";", "", $5); printf ("%s| %10d|", datetime, lineno++); if (html != "Y") printf ("%78s\n", $5); else printf ("<DIV ALIGN=\"right\"><SMALL><FONT COLOR=\"teal\">%s</FONT> <FONT COLOR=\"green\">%s</FONT></SMALL></DIV>\n", $5, $2); } } # mark back branches $1 == "revision" \ { if ($2 ~ /\..*\./ && del == "Y") back_branch=" <back-patch>" else back_branch = "" } /* clear working file */ $0 ~ /^====*$/ {workingfile=""}' | sort | cut -d'|' -f3 | # collect duplicate narratives # print file names as we get them, then print narrative when a new # narrative appears # have to save two narratives to compare them awk ' BEGIN { narr_slot = 0; oldnarr_slot=0; save_working = ""; html="'"$HTML"'"} { # We have a filename, so we look at the previous # narrative to see if it is new narrative text. if ($0 ~ "^/" || $0 ~ ">/") { # If there are a different number of narrative # lines, they cannot possibly be the same. if (narr_slot != oldnarr_slot) same = "N"; else { same = "Y"; for (i=1; i <= narr_slot; i++) { if (oldnarr[i] != narr[i]) { same = "N"; break; } } } # dump out the old narrative if it is new if (same == "N") { if (oldnarr_slot) for (i=1; i <= oldnarr_slot; i++) { print oldnarr[i]; if (html == "Y" && oldnarr[i] != "<HR>" && oldnarr[i] !~ "^<DIV ") print "<BR>"; } # save the current narrative for (i=1; i <= narr_slot; i++) oldnarr[i] = narr[i]; oldnarr_slot = narr_slot; } narr_slot = 0; # dump out the previous filename print save_working; if (html == "Y") print "<BR>"; # store the current filename for later printing save_working = $0; } else # we have a narrative line { # accumulate narrative narr[++narr_slot] = $0; } } END \ { # If there are a different number of narrative # lines, they can not possibly be the same. if (narr_slot != oldnarr_slot) same = "N"; else { same = "Y"; for (i=1; i <= narr_slot; i++) { if (oldnarr[i] != narr[i]) { same = "N"; break; } } } # dump out the old narrative if it is new if (same == "N") { if (oldnarr_slot) for (i=1; i <= oldnarr_slot; i++) { print oldnarr[i]; if (html == "Y" && oldnarr[i] != "<HR>" && oldnarr[i] !~ "^<DIV ") print "<BR>"; } } # dump out the last filename print save_working; if (html == "Y") print "<BR>"; # dump out the last narrative for (i=1; i <= narr_slot; i++) { print narr[i]; if (html == "Y" && narr[i] != "<HR>" && narr[i] !~ "^<DIV ") print "<BR>"; } }' | # add HTML wrapper if [ "$HTML" = "Y" ] then echo "<HTML>" echo "<HEAD>" echo "<TITLE>CVS</TITLE>" echo "</HEAD>" echo "<BODY>" cat echo "</BODY>" echo "</HTML>" else cat fi