All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mauro Carvalho Chehab <mchehab@redhat.com>
To: git@vger.kernel.org
Subject: Doubts about hot to properly write post-receive hook to send an email with a newly added patch
Date: Sat, 06 Mar 2010 12:55:35 -0300	[thread overview]
Message-ID: <4B927AF7.2060708@redhat.com> (raw)

I'm needing a post-receive hook that would send a copy to the patch author,
to the C/C recipients and to the ones that signed/acked/tested a patch.

The idea is to announce to the patch author and to the relevant parts that
a new patch were accepted on my -git tree, showing the patch/comments
after its addition at the tree.

So, I wrote a perl script for this (see enclosed) for it.

Unfortunately, I just found a serious bug: when I merge back from upstream, 
it sends a message also for all patch authors from upstream!

What's the better way to identify what patches came from a merge tree,
in order to remove them from the mailbomb queue?

Cheers,
Mauro


---

#!/usr/bin/perl
#
# License: GPLv2
#
use warnings;
use strict;
use Sys::Hostname;

$ENV{PATH} = '/usr/local/bin:/usr/bin:/bin';

my $debug = 0;
my $mail_cmd = "/usr/sbin/sendmail";
#
# Retrieve all info from git config
#
my $project_name = qx(git config mailnotify.project) || "untitled";
my $smtp_server  = qx(git config mailnotify.smtpserver) || "localhost";
my $from         = qx(git config mailnotify.from) || sprintf('%s@%s', $project_name, hostname());
my $to           = qx(git config mailnotify.to) || die("No mail To:");
my $cfgcc        = qx(git config mailnotify.cc) || "";
my $replyto      = qx(git config mailnotify.replyto) || "";
my $maxsize      = qx(git config mailnotify.maxsize) || "";
my $url          = qx(git config mailnotify.url) || "";

$project_name =~ s/\s+$//;
$smtp_server =~ s/\s+$//;
$from =~ s/\s+$//;
$to =~ s/\s+$//;
$cfgcc =~ s/\s+$//;
$replyto =~ s/\s+$//;
$maxsize =~ s/\s+$//;
$url =~ s/\s+$//;

#
# Get old revision, new revision and branch/tag name
#
my ($oldrev, $newrev, $refname);
if (scalar(@ARGV)) {
	($oldrev, $newrev, $refname) = @ARGV[ 0 .. 2 ];
} else {
	my $args = <STDIN>;
	($oldrev, $newrev, $refname) = split(" ", $args);
}
printf(STDERR "args:%s %s %s\n", $oldrev, $newrev, $refname) if ($debug);

#
# Get the complete revision name
#
$oldrev = qx(git rev-parse $oldrev);
$newrev = qx(git rev-parse $newrev);

chomp($oldrev);
chomp($newrev);
chomp($refname);

if ($debug) {
    printf(STDERR "oldrev:%s\n", $oldrev);
    printf(STDERR "newrev:%s\n", $newrev);
    printf(STDERR "refname:%s\n", $refname);
}

#
# Get branch name
#
my $branch = (split("/", $refname))[-1];

#
# get revisions
#
open REF, "git rev-list $oldrev..$newrev|";
while (<REF>) {
	my $ref= $_;

	my $author = qx(git log -1 --pretty=format:"%aN" $ref);
	my $data = qx(git log -1 --pretty=format:"%aD" $ref);
	my $subject = qx(git log -1 --pretty=format:"%s" $ref);
	$subject = sprintf("[git:%s/%s] %s", $project_name, $branch, $subject);

	my %copy;
	my $log = "";
	open IN, "git log -1 --pretty=email --stat $ref|";

	# Discard initial From line
	my $dumb=<IN>;

	while (<IN>) {
		next if (m/^Subject: /);
		next if (m/^Date: /);
		$log .= $_;

		if (m/(signed-off-by|author|from|accepted-by|tested-by|thanks-to|reviewed-by|cc|acked-by):\s*(.*)\s*\n$/i) {
			my $sob=$2;
			if ($sob =~ m/\s*(.*)\s*<(.*)>/) {
				my $name = $1;
				my $email = $2;
				$name =~ s/^\s+//;
				$name =~ s/\s+$//;
				$name =~ s/^\"(.*)\"$/$1/;
				$name="" if ($name =~ m/\@/);
				$copy{"$email"} = $name;
			} elsif ($sob =~ m/([^\s]+\@[^\s+]+)/) {
				my $email = $1;
				$copy{"$email"} = "" if (!exists($copy{"$email"}));
			}
		}
	}
	close IN;

	my $cc = $cfgcc;
	while (my ($key,$value) = each(%copy) ) {
		next if ($key =~ m/stable\@kernel.org/);
		if ($value ne "") {
			$cc .= ", $value <$key>";
		} else {
			$cc .= ", $key";
		}
	}
	$cc =~ s/^, //;
	$cc =~ s/\s+/ /g;

	my $diff = qx(git show --pretty=format:"" $ref);

	my $header = "Subject: $subject\nFrom: Patch from $author <$from>\nTo: $to\nData: $data\n";
	$header .= "Cc: $cc\n" if ($cc);

	if ($replyto) {
		$header .= "Mail-followup-to: $replyto\n";
		$header .= "Forward-to: $replyto\n";
		$header .= "Reply-to: $replyto\n";
	}

	my $email = "$header\n$log\n---\n\n";
	$email   .= "$url?a=commitdiff;h=$ref" if ($url);
	if ($maxsize && length($diff) > $maxsize) {
		$diff = "<diff discarded since it is too big>\n"
	}
	$email .= $diff;

	if (!$debug) {
		open(MAIL, "| $mail_cmd -t");
		print MAIL $email;
		close MAIL;
	} else {
		print $email;
	}
}

close REF;

                 reply	other threads:[~2010-03-06 20:59 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4B927AF7.2060708@redhat.com \
    --to=mchehab@redhat.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.