contrib / continuous / post-receive-cinotifyon commit get_ref_states: strdup entries and free util in stale list (92f676f)
   1#!/usr/bin/perl
   2#
   3# A hook that notifies its companion cidaemon through a simple
   4# queue file that a ref has been updated via a push (actually
   5# by a receive-pack running on the server).
   6#
   7# See cidaemon for per-repository configuration details.
   8#
   9# To use this hook, add it as the post-receive hook, make it
  10# executable, and set its configuration options.
  11#
  12
  13local $ENV{PATH} = '/opt/git/bin';
  14
  15use strict;
  16use warnings;
  17use File::Spec;
  18use Storable qw(retrieve nstore);
  19use Fcntl ':flock';
  20
  21my $git_dir = File::Spec->rel2abs($ENV{GIT_DIR});
  22my $queue_name = `git config --get builder.queue`;chop $queue_name;
  23$queue_name =~ m,^([^\s]+)$,; $queue_name = $1; # untaint
  24unless ($queue_name) {
  25        1 while <STDIN>;
  26        print STDERR "\nerror: builder.queue not set.  Not enqueing.\n\n";
  27        exit;
  28}
  29my $queue_lock = "$queue_name.lock";
  30
  31my @skip;
  32open S, "git config --get-all builder.skip|";
  33while (<S>) {
  34        chop;
  35        push @skip, $_;
  36}
  37close S;
  38
  39my @new_branch_base;
  40open S, "git config --get-all builder.newBranchBase|";
  41while (<S>) {
  42        chop;
  43        push @new_branch_base, $_;
  44}
  45close S;
  46
  47sub skip ($)
  48{
  49        local $_ = shift;
  50        foreach my $p (@skip) {
  51                return 1 if /^$p/;
  52        }
  53        0;
  54}
  55
  56open LOCK, ">$queue_lock" or die "Can't open $queue_lock: $!";
  57flock LOCK, LOCK_EX;
  58
  59my $queue = -f $queue_name ? retrieve $queue_name : [];
  60my %existing;
  61foreach my $r (@$queue) {
  62        my ($gd, $ref) = @$r;
  63        $existing{$gd}{$ref} = $r;
  64}
  65
  66my @new_branch_commits;
  67my $loaded_new_branch_commits = 0;
  68
  69while (<STDIN>) {
  70        chop;
  71        my ($old, $new, $ref) = split / /, $_, 3;
  72
  73        next if $old eq $new;
  74        next if $new =~ /^0{40}$/;
  75        next if skip $ref;
  76
  77        my $r = $existing{$git_dir}{$ref};
  78        if ($r) {
  79                $r->[3] = $new;
  80        } else {
  81                if ($old =~ /^0{40}$/) {
  82                        if (!$loaded_new_branch_commits && @new_branch_base) {
  83                                open M,'-|','git','show-ref',@new_branch_base;
  84                                while (<M>) {
  85                                        ($_) = split / /, $_;
  86                                        push @new_branch_commits, $_;
  87                                }
  88                                close M;
  89                                $loaded_new_branch_commits = 1;
  90                        }
  91                        $old = [@new_branch_commits];
  92                } else {
  93                        $old = [$old];
  94                }
  95
  96                $r = [$git_dir, $ref, $old, $new];
  97                $existing{$git_dir}{$ref} = $r;
  98                push @$queue, $r;
  99        }
 100}
 101nstore $queue, $queue_name;
 102
 103flock LOCK, LOCK_UN;
 104close LOCK;