diff options
-rwxr-xr-x | tools/git-notify | 90 |
1 files changed, 68 insertions, 22 deletions
diff --git a/tools/git-notify b/tools/git-notify index 6d5a564..9ab012e 100755 --- a/tools/git-notify +++ b/tools/git-notify | |||
@@ -47,6 +47,9 @@ my $cia_address = "cia\@cia.navi.cx"; | |||
47 | # debug mode | 47 | # debug mode |
48 | my $debug = 0; | 48 | my $debug = 0; |
49 | 49 | ||
50 | # number of generated (non-CIA) notifications | ||
51 | my $sent_notices = 0; | ||
52 | |||
50 | # configuration parameters | 53 | # configuration parameters |
51 | 54 | ||
52 | # base URL of the gitweb repository browser (can be set with the -u option) | 55 | # base URL of the gitweb repository browser (can be set with the -u option) |
@@ -272,6 +275,28 @@ sub get_object_info($) | |||
272 | return %info; | 275 | return %info; |
273 | } | 276 | } |
274 | 277 | ||
278 | # send a ref change notice to a mailing list | ||
279 | sub send_ref_notice($$@) | ||
280 | { | ||
281 | my ($ref, $action, @notice) = @_; | ||
282 | my ($reftype, $refname) = ($ref =~ /^refs\/(head|tag)s\/(.+)/); | ||
283 | |||
284 | $reftype =~ s/^head$/branch/; | ||
285 | |||
286 | @notice = (format_table( | ||
287 | "Module: $repos_name", | ||
288 | ($reftype eq "tag" ? "Tag:" : "Branch:") . $refname, | ||
289 | @notice, | ||
290 | ($action ne "removed" and $gitweb_url) | ||
291 | ? "URL: $gitweb_url/?a=shortlog;h=$ref" : undef), | ||
292 | "", | ||
293 | "The $refname $reftype has been $action."); | ||
294 | |||
295 | mail_notification($commitlist_address, "$refname $reftype $action", | ||
296 | "text/plain; charset=us-ascii", @notice); | ||
297 | $sent_notices++; | ||
298 | } | ||
299 | |||
275 | # send a commit notice to a mailing list | 300 | # send a commit notice to a mailing list |
276 | sub send_commit_notice($$) | 301 | sub send_commit_notice($$) |
277 | { | 302 | { |
@@ -315,6 +340,7 @@ sub send_commit_notice($$) | |||
315 | mail_notification($commitlist_address, | 340 | mail_notification($commitlist_address, |
316 | $info{"author_name"} . ": " . ${$info{"log"}}[0], | 341 | $info{"author_name"} . ": " . ${$info{"log"}}[0], |
317 | "text/plain; charset=UTF-8", @notice); | 342 | "text/plain; charset=UTF-8", @notice); |
343 | $sent_notices++; | ||
318 | } | 344 | } |
319 | 345 | ||
320 | # send a commit notice to the CIA server | 346 | # send a commit notice to the CIA server |
@@ -383,44 +409,64 @@ sub send_global_notice($$$) | |||
383 | } | 409 | } |
384 | 410 | ||
385 | mail_notification($commitlist_address, "New commits on branch $ref", "text/plain; charset=UTF-8", @$notice); | 411 | mail_notification($commitlist_address, "New commits on branch $ref", "text/plain; charset=UTF-8", @$notice); |
412 | $sent_notices++; | ||
386 | } | 413 | } |
387 | 414 | ||
388 | # send all the notices | 415 | # send all the notices |
389 | sub send_all_notices($$$) | 416 | sub send_all_notices($$$) |
390 | { | 417 | { |
391 | my ($old_sha1, $new_sha1, $ref) = @_; | 418 | my ($old_sha1, $new_sha1, $ref) = @_; |
419 | my ($reftype, $refname, $action, @notice); | ||
392 | 420 | ||
393 | $ref =~ s/^refs\/heads\///; | 421 | return if ($ref =~ /^refs\/remotes\// |
422 | or (@include_list && !grep {$_ eq $ref} @include_list)); | ||
423 | die "The name \"$ref\" doesn't sound like a local branch or tag" | ||
424 | if not (($reftype, $refname) = ($ref =~ /^refs\/(head|tag)s\/(.+)/)); | ||
394 | 425 | ||
395 | return if (@include_list && !grep {$_ eq $ref} @include_list); | 426 | if ($new_sha1 eq '0' x 40) |
396 | |||
397 | if ($old_sha1 eq '0' x 40) # new ref | ||
398 | { | 427 | { |
399 | send_commit_notice( $ref, $new_sha1 ) if $commitlist_address; | 428 | $action = "removed"; |
400 | return; | 429 | @notice = ( "Old SHA1: $old_sha1" ); |
401 | } | 430 | } |
402 | 431 | elsif ($old_sha1 eq '0' x 40) | |
403 | my @commits = (); | ||
404 | |||
405 | open LIST, "-|" or exec "git", "rev-list", @revlist_options, "^$old_sha1", "$new_sha1", @exclude_list or die "cannot exec git-rev-list"; | ||
406 | while (<LIST>) | ||
407 | { | 432 | { |
408 | chomp; | 433 | $action = "created"; |
409 | die "invalid commit $_" unless /^[0-9a-f]{40}$/; | 434 | @notice = ( "SHA1: $new_sha1" ); |
410 | unshift @commits, $_; | ||
411 | } | 435 | } |
412 | close LIST; | 436 | elsif ($reftype eq "tag") |
413 | 437 | { | |
414 | if (@commits > $max_individual_notices) | 438 | $action = "updated"; |
439 | @notice = ( "Old SHA1: $old_sha1", "New SHA1: $new_sha1" ); | ||
440 | } | ||
441 | elsif (not grep( $_ eq $old_sha1, @{ git_rev_list( $new_sha1, "--full-history" ) } )) | ||
415 | { | 442 | { |
416 | send_global_notice( $ref, $old_sha1, $new_sha1 ) if $commitlist_address; | 443 | $action = "rewritten"; |
417 | return; | 444 | @notice = ( "Old SHA1: $old_sha1", "New SHA1: $new_sha1" ); |
418 | } | 445 | } |
419 | 446 | ||
420 | foreach my $commit (@commits) | 447 | send_ref_notice( $ref, $action, @notice ) if ($commitlist_address and $action); |
448 | |||
449 | unless ($reftype eq "tag" or $new_sha1 eq '0' x 40) | ||
421 | { | 450 | { |
422 | send_commit_notice( $ref, $commit ) if $commitlist_address; | 451 | my $commits = get_new_commits ( $old_sha1, $new_sha1 ); |
423 | send_cia_notice( $ref, $commit ) if $cia_project_name; | 452 | |
453 | if (@$commits > $max_individual_notices) | ||
454 | { | ||
455 | send_global_notice( $refname, $old_sha1, $new_sha1 ) if $commitlist_address; | ||
456 | } | ||
457 | else | ||
458 | { | ||
459 | foreach my $commit (@$commits) | ||
460 | { | ||
461 | send_commit_notice( $refname, $commit ) if $commitlist_address; | ||
462 | send_cia_notice( $refname, $commit ) if $cia_project_name; | ||
463 | } | ||
464 | } | ||
465 | if ($sent_notices == 0 and $commitlist_address) | ||
466 | { | ||
467 | @notice = ( "Old SHA1: $old_sha1", "New SHA1: $new_sha1" ); | ||
468 | send_ref_notice( $ref, "modified", @notice ); | ||
469 | } | ||
424 | } | 470 | } |
425 | } | 471 | } |
426 | 472 | ||