use strict;
use warnings;
+use bytes;
use Fcntl;
use File::Temp qw/tempdir tempfile/;
return 0;
}
- my @gitvars = `git-repo-config -l`;
+ my @gitvars = `git-config -l`;
if ($?) {
- print "E problems executing git-repo-config on the server -- this is not a git repository or the PATH is not set correctly.\n";
+ print "E problems executing git-config on the server -- this is not a git repository or the PATH is not set correctly.\n";
print "E \n";
- print "error 1 - problem executing git-repo-config\n";
+ print "error 1 - problem executing git-config\n";
return 0;
}
foreach my $line ( @gitvars )
print "MT newline\n";
next;
}
- elsif ( !defined($wrev) || $wrev == 0 )
+ elsif ( (!defined($wrev) || $wrev == 0) && (!defined($meta->{revision}) || $meta->{revision} == 0) )
{
- $log->info("Tell the client the file will be added");
+ $log->info("Tell the client the file is scheduled for addition");
print "MT text A \n";
print "MT fname $filename\n";
print "MT newline\n";
}
else {
- $log->info("Updating '$filename' $wrev");
+ $log->info("Updating '$filename' to ".$meta->{revision});
print "MT +updated\n";
print "MT text U \n";
print "MT fname $filename\n";
$log->debug("Temporary directory for merge is $dir");
- my $return = system("merge", $file_local, $file_old, $file_new);
+ my $return = system("git", "merge-file", $file_local, $file_old, $file_new);
$return >>= 8;
if ( $return == 0 )
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}",
+ $parenthash, $commithash );
+ if( -x $cmd[0] ) {
+ unless( system( @cmd ) == 0 )
+ {
+ $log->warn("Commit failed (update hook declined to update ref)");
+ print "error 1 Commit failed (update hook declined)\n";
+ close LOCKFILE;
+ unlink($lockfile);
+ chdir "/";
+ exit;
+ }
+ }
+
print LOCKFILE $commithash;
$updater->update();
$filename = filecleanup($filename);
my $meta = $updater->getmeta($filename);
+ unless (defined $meta->{revision}) {
+ $meta->{revision} = 1;
+ }
my ( $filepart, $dirpart ) = filenamesplit($filename, 1);
$log->debug("Checked-in $dirpart : $filename");
- if ( $meta->{filehash} eq "deleted" )
+ if ( defined $meta->{filehash} && $meta->{filehash} eq "deleted" )
{
print "Remove-entry $dirpart\n";
print "$filename\n";
mode TEXT NOT NULL
)
");
+ $self->{dbh}->do("
+ CREATE INDEX revision_ix1
+ ON revision (name,revision)
+ ");
+ $self->{dbh}->do("
+ CREATE INDEX revision_ix2
+ ON revision (name,commithash)
+ ");
}
- # Construct the revision table if required
+ # Construct the head table if required
unless ( $self->{tables}{head} )
{
$self->{dbh}->do("
mode TEXT NOT NULL
)
");
+ $self->{dbh}->do("
+ CREATE INDEX head_ix1
+ ON head (name)
+ ");
}
# Construct the properties table if required
# first lets get the commit list
$ENV{GIT_DIR} = $self->{git_path};
- my $commitinfo = `git-cat-file commit $self->{module} 2>&1`;
+ my $commitsha1 = `git rev-parse $self->{module}`;
+ chomp $commitsha1;
+
+ my $commitinfo = `git cat-file commit $self->{module} 2>&1`;
unless ( $commitinfo =~ /tree\s+[a-zA-Z0-9]{40}/ )
{
die("Invalid module '$self->{module}'");
my $git_log;
my $lastcommit = $self->_get_prop("last_commit");
+ if (defined $lastcommit && $lastcommit eq $commitsha1) { # up-to-date
+ return 1;
+ }
+
# Start exclusive lock here...
$self->{dbh}->begin_work() or die "Cannot lock database for BEGIN";
if ( defined ( $lastpicked ) )
{
- my $filepipe = open(FILELIST, '-|', 'git-diff-tree', '-r', $lastpicked, $commit->{hash}) or die("Cannot call git-diff-tree : $!");
+ my $filepipe = open(FILELIST, '-|', 'git-diff-tree', '-z', '-r', $lastpicked, $commit->{hash}) or die("Cannot call git-diff-tree : $!");
+ local ($/) = "\0";
while ( <FILELIST> )
{
- unless ( /^:\d{6}\s+\d{3}(\d)\d{2}\s+[a-zA-Z0-9]{40}\s+([a-zA-Z0-9]{40})\s+(\w)\s+(.*)$/o )
+ chomp;
+ unless ( /^:\d{6}\s+\d{3}(\d)\d{2}\s+[a-zA-Z0-9]{40}\s+([a-zA-Z0-9]{40})\s+(\w)$/o )
{
die("Couldn't process git-diff-tree line : $_");
}
+ my ($mode, $hash, $change) = ($1, $2, $3);
+ my $name = <FILELIST>;
+ chomp($name);
- # $log->debug("File mode=$1, hash=$2, change=$3, name=$4");
+ # $log->debug("File mode=$mode, hash=$hash, change=$change, name=$name");
my $git_perms = "";
- $git_perms .= "r" if ( $1 & 4 );
- $git_perms .= "w" if ( $1 & 2 );
- $git_perms .= "x" if ( $1 & 1 );
+ $git_perms .= "r" if ( $mode & 4 );
+ $git_perms .= "w" if ( $mode & 2 );
+ $git_perms .= "x" if ( $mode & 1 );
$git_perms = "rw" if ( $git_perms eq "" );
- if ( $3 eq "D" )
+ if ( $change eq "D" )
{
- #$log->debug("DELETE $4");
- $head->{$4} = {
- name => $4,
- revision => $head->{$4}{revision} + 1,
+ #$log->debug("DELETE $name");
+ $head->{$name} = {
+ name => $name,
+ revision => $head->{$name}{revision} + 1,
filehash => "deleted",
commithash => $commit->{hash},
modified => $commit->{date},
author => $commit->{author},
mode => $git_perms,
};
- $self->insert_rev($4, $head->{$4}{revision}, $2, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
+ $self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
}
- elsif ( $3 eq "M" )
+ elsif ( $change eq "M" )
{
- #$log->debug("MODIFIED $4");
- $head->{$4} = {
- name => $4,
- revision => $head->{$4}{revision} + 1,
- filehash => $2,
+ #$log->debug("MODIFIED $name");
+ $head->{$name} = {
+ name => $name,
+ revision => $head->{$name}{revision} + 1,
+ filehash => $hash,
commithash => $commit->{hash},
modified => $commit->{date},
author => $commit->{author},
mode => $git_perms,
};
- $self->insert_rev($4, $head->{$4}{revision}, $2, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
+ $self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
}
- elsif ( $3 eq "A" )
+ elsif ( $change eq "A" )
{
- #$log->debug("ADDED $4");
- $head->{$4} = {
- name => $4,
+ #$log->debug("ADDED $name");
+ $head->{$name} = {
+ name => $name,
revision => 1,
- filehash => $2,
+ filehash => $hash,
commithash => $commit->{hash},
modified => $commit->{date},
author => $commit->{author},
mode => $git_perms,
};
- $self->insert_rev($4, $head->{$4}{revision}, $2, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
+ $self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
}
else
{
- $log->warn("UNKNOWN FILE CHANGE mode=$1, hash=$2, change=$3, name=$4");
+ $log->warn("UNKNOWN FILE CHANGE mode=$mode, hash=$hash, change=$change, name=$name");
die;
}
}
# this is used to detect files removed from the repo
my $seen_files = {};
- my $filepipe = open(FILELIST, '-|', 'git-ls-tree', '-r', $commit->{hash}) or die("Cannot call git-ls-tree : $!");
+ my $filepipe = open(FILELIST, '-|', 'git-ls-tree', '-z', '-r', $commit->{hash}) or die("Cannot call git-ls-tree : $!");
+ local $/ = "\0";
while ( <FILELIST> )
{
- unless ( /^(\d+)\s+(\w+)\s+([a-zA-Z0-9]+)\s+(.*)$/o )
+ chomp;
+ unless ( /^(\d+)\s+(\w+)\s+([a-zA-Z0-9]+)\t(.*)$/o )
{
die("Couldn't process git-ls-tree line : $_");
}