SF.net SVN: nagiosplug:[2270] nagiosplug/trunk/tools/git-notify

[email protected]
Newsgroups gmane.network.nagios.plugins.cvs
Message-ID <[email protected]>
Revision: 2270
          http://nagiosplug.svn.sourceforge.net/nagiosplug/?rev=2270&view=rev
Author:   dermoth
Date:     2009-10-24 21:01:16 +0000 (Sat, 24 Oct 2009)

Log Message:
-----------
git-notify: Don't generate duplicate notifications

Never notify on a given commit more than once, even if it's referenced
via multiple branch heads.  We make sure this won't happen simply by
maintaining a list of commits we notified about.  The file path used for
saving this list can be specified using the new "-t" option.  (The
contrib/hooks/post-receive-email script distributed with Git tries hard
to avoid such a list, but it doesn't get the necessary magic right.)

From: Holger Weiss <[email protected]>

Modified Paths:
--------------
    nagiosplug/trunk/tools/git-notify

Modified: nagiosplug/trunk/tools/git-notify
===================================================================
--- nagiosplug/trunk/tools/git-notify	2009-10-24 21:01:06 UTC (rev 2269)
+++ nagiosplug/trunk/tools/git-notify	2009-10-24 21:01:16 UTC (rev 2270)
@@ -3,6 +3,7 @@
 # Tool to send git commit notifications
 #
 # Copyright 2005 Alexandre Julliard
+# Copyright 2009 Nagios Plugins Development Team
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
@@ -19,6 +20,7 @@
 #   -n max    Set max number of individual mails to send
 #   -r name   Set the git repository name
 #   -s bytes  Set the maximum diff size in bytes (-1 for no limit)
+#   -t file   Set the file to use for reading and saving state
 #   -u url    Set the URL to the gitweb browser
 #   -i branch If at least one -i is given, report only for specified branches
 #   -x branch Exclude changes to the specified branch from reports
@@ -27,6 +29,7 @@
 
 use strict;
 use open ':utf8';
+use Fcntl ':flock';
 use Encode 'encode';
 use Cwd 'realpath';
 
@@ -76,6 +79,9 @@
 # branches to exclude
 my @exclude_list = split /\s+/, git_config( "notify.exclude" ) || "";
 
+# the state file we use (can be changed with the -t option)
+my $state_file = git_config( "notify.statefile" ) || "/var/tmp/git-notify.state";
+
 # Extra options to git rev-list
 my @revlist_options;
 
@@ -87,6 +93,7 @@
     print "   -n max    Set max number of individual mails to send\n";
     print "   -r name   Set the git repository name\n";
     print "   -s bytes  Set the maximum diff size in bytes (-1 for no limit)\n";
+    print "   -t file   Set the file to use for reading and saving state\n";
     print "   -u url    Set the URL to the gitweb browser\n";
     print "   -i branch If at least one -i is given, report only for specified branches\n";
     print "   -x branch Exclude changes to the specified branch from reports\n";
@@ -127,6 +134,59 @@
     return $revlist;
 }
 
+# append the given commit hashes to the state file
+sub save_commits($)
+{
+    my $commits = shift;
+
+    open STATE, ">>", $state_file or die "Cannot open $state_file: $!";
+    flock STATE, LOCK_EX or die "Cannot lock $state_file";
+    print STATE "$_\n" for @$commits;
+    flock STATE, LOCK_UN or die "Cannot unlock $state_file";
+    close STATE or die "Cannot close $state_file: $!";
+}
+
+# for the given range, return the new hashes and append them to the state file
+sub get_new_commits($$)
+{
+    my ($old_sha1, $new_sha1) = @_;
+    my ($seen, @args);
+    my $newrevs = [];
+
+    @args = ( "^$old_sha1" ) unless $old_sha1 eq '0' x 40;
+    push @args, $new_sha1, @exclude_list;
+
+    my $revlist = git_rev_list(@args);
+
+    if (not -e $state_file)  # initialize the state file with all hashes
+    {
+        save_commits(git_rev_list("--all", "--full-history"));
+        return $revlist;
+    }
+
+    open STATE, $state_file or die "Cannot open $state_file: $!";
+    flock STATE, LOCK_SH or die "Cannot lock $state_file";
+    while (<STATE>)
+    {
+        chomp;
+        die "Invalid commit: $_" if not /^[0-9a-f]{40}$/;
+        $seen->{$_} = 1;
+    }
+    flock STATE, LOCK_UN or die "Cannot unlock $state_file";
+    close STATE or die "Cannot close $state_file: $!";
+
+    # FIXME: if another git-notify process reads the $state_file at *this*
+    # point, that process might generate duplicates of our notifications.
+
+    save_commits($revlist);
+
+    foreach my $commit (@$revlist)
+    {
+        push @$newrevs, $commit unless $seen->{$commit};
+    }
+    return $newrevs;
+}
+
 # truncate the given string if it exceeds the specified number of characters
 sub truncate_str($$)
 {
@@ -217,6 +277,7 @@
         elsif ($arg eq '-n') { $max_individual_notices = shift @ARGV; }
         elsif ($arg eq '-r') { $repos_name = shift @ARGV; }
         elsif ($arg eq '-s') { $max_diff_size = shift @ARGV; }
+        elsif ($arg eq '-t') { $state_file = shift @ARGV; }
         elsif ($arg eq '-u') { $gitweb_url = shift @ARGV; }
         elsif ($arg eq '-i') { push @include_list, shift @ARGV; }
         elsif ($arg eq '-x') { push @exclude_list, shift @ARGV; }


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.