compat: Add simplified merge sort implementation from glibc
[gitweb.git] / git-cvsserver.perl
index ae7d51158912a00dd169c4f38c531f7dfbdba6dd..afe3d0b7fe4d643688e672f62844cc86ec64fab5 100755 (executable)
     }
     my $request = $1;
     $line = <STDIN>; chomp $line;
-    req_Root('root', $line) # reuse Root
-       or die "E Invalid root $line \n";
+    unless (req_Root('root', $line)) { # reuse Root
+       print "E Invalid root $line \n";
+       exit 1;
+    }
     $line = <STDIN>; chomp $line;
     unless ($line eq 'anonymous') {
        print "E Only anonymous user allowed via pserver\n";
@@ -1196,6 +1198,7 @@ sub req_ci
     $log->info("Lockless commit start, basing commit on '$tmpdir', index file is '$file_index'");
 
     $ENV{GIT_DIR} = $state->{CVSROOT} . "/";
+    $ENV{GIT_WORK_TREE} = ".";
     $ENV{GIT_INDEX_FILE} = $file_index;
 
     # Remember where the head was at the beginning.
@@ -1208,13 +1211,13 @@ sub req_ci
 
     chdir $tmpdir;
 
-    # populate the temporary index based
+    # populate the temporary index
     system("git-read-tree", $parenthash);
     unless ($? == 0)
     {
        die "Error running git-read-tree $state->{module} $file_index $!";
     }
-    $log->info("Created index '$file_index' with for head $state->{module} - exit status $?");
+    $log->info("Created index '$file_index' for head $state->{module} - exit status $?");
 
     my @committedfiles = ();
     my %oldmeta;
@@ -1234,7 +1237,7 @@ sub req_ci
 
         my ( $filepart, $dirpart ) = filenamesplit($filename);
 
-        # do a checkout of the file if it part of this tree
+       # do a checkout of the file if it is part of this tree
         if ($wrev) {
             system('git-checkout-index', '-f', '-u', $filename);
             unless ($? == 0) {
@@ -1321,11 +1324,11 @@ sub req_ci
         exit;
     }
 
-       # Check that this is allowed, just as we would with a receive-pack
-       my @cmd = ( $ENV{GIT_DIR}.'hooks/update', "refs/heads/$state->{module}",
+       ### Emulate git-receive-pack by running hooks/update
+       my @hook = ( $ENV{GIT_DIR}.'hooks/update', "refs/heads/$state->{module}",
                        $parenthash, $commithash );
-       if( -x $cmd[0] ) {
-               unless( system( @cmd ) == 0 )
+       if( -x $hook[0] ) {
+               unless( system( @hook ) == 0 )
                {
                        $log->warn("Commit failed (update hook declined to update ref)");
                        print "error 1 Commit failed (update hook declined)\n";
@@ -1334,6 +1337,7 @@ sub req_ci
                }
        }
 
+       ### Update the ref
        if (system(qw(git update-ref -m), "cvsserver ci",
                        "refs/heads/$state->{module}", $commithash, $parenthash)) {
                $log->warn("update-ref for $state->{module} failed.");
@@ -1341,6 +1345,24 @@ sub req_ci
                exit;
        }
 
+       ### Emulate git-receive-pack by running hooks/post-receive
+       my $hook = $ENV{GIT_DIR}.'hooks/post-receive';
+       if( -x $hook ) {
+               open(my $pipe, "| $hook") || die "can't fork $!";
+
+               local $SIG{PIPE} = sub { die 'pipe broke' };
+
+               print $pipe "$parenthash $commithash refs/heads/$state->{module}\n";
+
+               close $pipe || die "bad pipe: $! $?";
+       }
+
+       ### Then hooks/post-update
+       $hook = $ENV{GIT_DIR}.'hooks/post-update';
+       if (-x $hook) {
+               system($hook, "refs/heads/$state->{module}");
+       }
+
     $updater->update();
 
     # foreach file specified on the command line ...
@@ -1721,6 +1743,7 @@ sub req_annotate
     $log->info("Temp checkoutdir creation successful, basing annotate session work on '$tmpdir', index file is '$file_index'");
 
     $ENV{GIT_DIR} = $state->{CVSROOT} . "/";
+    $ENV{GIT_WORK_TREE} = ".";
     $ENV{GIT_INDEX_FILE} = $file_index;
 
     chdir $tmpdir;
@@ -2520,8 +2543,15 @@ sub update
                     if ($parent eq $lastpicked) {
                         next;
                     }
-                    my $base = safe_pipe_capture('git-merge-base',
+                   my $base = eval {
+                           safe_pipe_capture('git-merge-base',
                                                 $lastpicked, $parent);
+                   };
+                   # The two branches may not be related at all,
+                   # in which case merge base simply fails to find
+                   # any, but that's Ok.
+                   next if ($@);
+
                     chomp $base;
                     if ($base) {
                         my @merged;