Permalink
Browse files

Add new changelog-email and out/changelog.pl scripts.

This is intended to be used to send emails listing the most recent changes.
Run with the "--mark" parameter to update the set of revs so that they don't
get sent again last time.
  • Loading branch information...
1 parent 511ab30 commit 7bed91b3bf4b72d43ca5f699dbee71ea4263f5f7 @apenwarr committed Sep 12, 2008
Showing with 358 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +13 −0 changed-revs.sh
  3. +31 −0 changelog-email
  4. +57 −0 out/changelog.css
  5. +251 −0 out/changelog.pl
  6. +5 −0 revdetail.sh
View
@@ -3,6 +3,7 @@
/out/pass
/out/refs
/out/ignore
+/out/lastlog
/out/revcache
/out/describe
/build
View
@@ -0,0 +1,13 @@
+#!/bin/bash
+DIR=$(dirname $0)
+cd "$DIR/build"
+
+git rev-list --first-parent --pretty='format:%H %ce %s' "$@" |
+ while read commit email comment; do
+ [ "$commit" = "commit" ] && continue
+ if [ -f ../out/lastlog/$commit ]; then
+ # we've already printed a changelog for this one
+ break;
+ fi
+ echo "$commit $email $comment"
+ done
View
@@ -0,0 +1,31 @@
+#!/bin/bash
+DIR=$(dirname $0)
+cd "$DIR" || exit 5
+
+
+EMAIL=$(git var GIT_AUTHOR_IDENT | sed 's/^.*<\(.*\)>.*$/\1/')
+if [ -r out/changelog-email-from ]; then
+ EMAIL=$(cat out/changelog-email-from)
+fi
+
+PROJ=Git
+if [ -r out/project-name ]; then
+ PROJ=$(cat out/project-name)
+fi
+
+DATE=$(date +%Y-%m-%d)
+
+cat <<-EOF
+ From: ChangeLog Script <$EMAIL>
+ To: (undisclosed recipients);
+ Subject: Changes in $PROJ for $DATE
+ Content-Type: text/html
+ Precedence: bulk
+ Importance: low
+ X-This-Is-Git-Changelog: yes
+ List-id: <git-changelog-script>
+
+EOF
+
+cd out || exit 6
+exec ./changelog.pl "$@"
View
@@ -0,0 +1,57 @@
+body {
+ font-family: verdana, sans-serif;
+}
+
+div.listings {
+ display: block;
+ padding: 0px;
+}
+
+.listings div {
+ display: block;
+ margin: 0pt 0pt 20pt 0pt;
+ padding: 0pt;
+}
+
+.listings .svtitle {
+ font-weight: bold;
+ display: inline;
+}
+
+.listings .svtitle b {
+ text-decoration: underline;
+}
+
+.listings .svdate {
+ color: #666666;
+ margin: 0pt 0pt 0pt 10pt;
+ padding: 0pt;
+ display: inline;
+}
+
+.listings ul {
+ margin: 0pt 0pt 0pt 20pt;
+ padding: 0pt 0pt 0pt 0pt;
+}
+
+.listings .svcommentary {
+ display: block;
+ color: #666666;
+ font-family: andale mono, verdana, sans-serif;
+ font-size: smaller;
+ margin: 0pt 0pt 0pt 0pt;
+ padding: 0pt 0pt 5pt 0pt;
+}
+
+.listings .svcommentary p {
+ margin: 0pt 0pt 0pt 0pt;
+ padding: 0pt 0pt 0pt 0pt;
+}
+
+.listings .svtext {
+ display: block;
+}
+
+.listings p_title {
+ font-weight: bold;
+}
View
@@ -0,0 +1,251 @@
+#!/usr/bin/perl -w
+use strict;
+use lib "./out";
+use Autobuilder;
+
+$|=1;
+
+my $mark = 0;
+if (@ARGV>=1 && $ARGV[0] eq "--mark") {
+ $mark = 1;
+}
+
+if (!$mark) {
+ print STDERR
+ "WARNING: not updating last-seen pointers. Try --mark if\n"
+ . " you don't want to see the same commits next time.\n";
+}
+
+my %skipmarks = ();
+
+sub run_cmd(@)
+{
+ my @cmdline = @_;
+
+ open(my $fh, "-|", @cmdline)
+ or die("Can't run $cmdline[0]: $!\n");
+ my @out = <$fh>;
+ chomp @out;
+ close $fh;
+ return @out;
+}
+
+sub list_branches()
+{
+ my @out = ();
+ foreach my $s (run_cmd('../branches.sh')) {
+ my $print = $s;
+ $print =~ s{^.*/}{};
+
+ push @out, "$print $s";
+ }
+
+ my @out2 = ();
+ foreach my $s (sort { lc($a) cmp lc($b) } @out)
+ {
+ my ($branchword, $branch) = split(" ", $s, 2);
+ push @out2, $branch;
+ }
+
+ return @out2;
+}
+
+# returns revs from newest to oldest
+sub changed_revs($)
+{
+ my $branch = shift;
+ my @out = ();
+ foreach my $rs (run_cmd('../changed-revs.sh', $branch))
+ {
+ my ($rev, $junk) = split(" ", $rs, 2);
+ last if $skipmarks{$rev};
+ push @out, $rev;
+ }
+ return @out;
+}
+
+sub revdetail($)
+{
+ my $rev = shift;
+
+ my $who = "UNKNOWN";
+ my $date = "UNKNOWN";
+ my $log = "";
+ my @filenames = ();
+
+ my $inlog = 0;
+
+ foreach my $line (run_cmd('../revdetail.sh', $rev)) {
+ if ($inlog && $line =~ /^\S/) {
+ push @filenames, $line;
+ } elsif ($line =~ /^author (.*) <(.*)> (\d+)/) {
+ $who = $2;
+ my $ticks = $3;
+
+ $who =~ s/\@.*//;
+
+ my @tm = localtime($ticks);
+ $date = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
+ 1900+$tm[5], $tm[4], $tm[3],
+ $tm[2], $tm[1], $tm[0]);
+ } elsif ($line =~ /^$/) {
+ $inlog = 1;
+ } elsif ($line =~ /^ (.*)/) {
+ $log .= "$1\n";
+ $inlog = 1;
+ }
+ }
+
+ $log =~ s/^\s*git-svn-id:.*$//mg;
+ $log =~ s/^\s*//;
+ $log =~ s/\s*$//;
+ $log =~ s/\n/<br>\n/g;
+
+ return $rev, $who, $date, \@filenames, $log;
+}
+
+sub revformat(@)
+{
+ my ($rev, $who, $date, $_filenames, $log) = @_;
+ my @filenames = @{$_filenames};
+
+ my @out = ();
+
+ my $commitlink = commitlink($rev, shorten($rev, 7, ""));
+ my $filenames = join('<br>', sort @filenames);
+ push @out, qq{
+ <div>
+ <span class='svtitle'>$commitlink by <b>$who</b></span>
+ <span class='svdate'>$date</span>
+ <ul>
+ <div class='svcommentary'>$filenames</div>
+ <div class='svtext'>$log</div>
+ </ul>
+ </div>
+ };
+
+ return join('', @out);
+}
+
+sub nicebranch($)
+{
+ my $branch = shift;
+ $branch =~ s{^remotes/}{};
+ $branch =~ s{^origin/}{};
+ return $branch;
+}
+
+
+# When we want to mark the most recent revision on a branch as being
+# printed, we actually mark a few revisions starting from the most recent.
+#
+# We could mark them *all*, but that would be unnecessarily many marks.
+#
+# However, marking more than one helps with tags that are just slightly
+# different (eg. a version number commit) from some other branch's history.
+# It happens a lot with git-svn, because "made a copy" in svn is an extra
+# commit, and that's how you make an svn tag. Without our slightly funny
+# behaviour here, listing all the commits in tag 1.0 wouldn't mark
+# *anything* dirty in 1.0a, which is no good.
+sub mark_rev(@)
+{
+ my @revs = @_;
+
+ mkdir("lastlog");
+ for (my $i = 0; $i < @revs && $i < 5; $i++) {
+ my $rev = $revs[$i];
+ $skipmarks{$rev} = 1;
+ if ($mark) {
+ open my $fh, ">lastlog/$rev"
+ or die("lastlog/$rev: $!\n");
+ close $fh;
+ }
+ }
+}
+
+
+
+my $style = catfile("changelog.css");
+my $projname = project_name() || "Git project";
+my @ltm = localtime();
+my $title = sprintf("%s changes for %04d-%02d-%02d", $projname,
+ $ltm[5]+1900, $ltm[4], $ltm[3]);
+print qq{<html>
+ <head>
+ <style type="text/css">
+ $style
+ </style>
+ <title>$title</title>
+ </head>
+ <body>
+};
+
+
+my %changelogs = ();
+my @branches = list_branches();
+
+foreach my $branch (@branches)
+{
+ printf STDERR "%40s: ", $branch;
+ my $nicebranch = nicebranch($branch);
+ my @revs = changed_revs($branch);
+
+ my $revcount = scalar(@revs);
+ if (!$revcount) {
+ print STDERR " Empty.\n";
+ next;
+ }
+
+ # otherwise, actually do the changelog
+ my @log = ();
+
+ push @log, qq{
+ <a name="$branch">
+ <h1>$nicebranch:</h1>
+ <div class="listings">
+ };
+
+ print STDERR " $revcount\n";
+ if ($revcount > 25) {
+ my $commitlink = commitlink($revs[0], shorten($revs[0], 7, ""));
+ push @log, qq{
+ <div>
+ <span class='svtitle'>$commitlink</span>
+ <ul>
+ <span class='svtext'>Too many commits ($revcount) to print them all here.</span>
+ </ul>
+ </div>
+ };
+ } else {
+ foreach my $rev (@revs) {
+ push @log, revformat(revdetail($rev));
+ }
+ }
+
+ $changelogs{$branch} = join('', @log);
+ mark_rev(@revs);
+}
+
+
+if (keys %changelogs) {
+ print "<h1>There were changes in these branches:</h1> <ul>\n";
+ foreach my $branch (@branches) {
+ next if !defined($changelogs{$branch});
+ my $nicebranch = nicebranch($branch);
+ print "<li><a name='toc-$branch'><a href='#$branch'>"
+ . "$nicebranch</a></a></li>\n";
+ }
+ print "</ul>";
+
+ foreach my $branch (@branches) {
+ next if !defined($changelogs{$branch});
+ print $changelogs{$branch};
+ }
+} else {
+ print "No recent changes.\n";
+}
+
+
+print "</body></html>\n\n";
+
+exit 0;
View
@@ -0,0 +1,5 @@
+#!/bin/bash
+DIR=$(dirname $0)
+cd "$DIR/build"
+
+git log --first-parent --name-only --pretty=raw --no-walk "$@" -- | cat

0 comments on commit 7bed91b

Please sign in to comment.