cvsserver: factor out git-log parsing logic
Some field conversion was already duplicated, and more calls will be added soon. Signed-off-by: Matthew Ogilvie <mmogilvi_git@miniinfo.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
abd66f2207
commit
2c3af7e748
@ -3157,45 +3157,10 @@ sub update
|
|||||||
push @git_log_params, $self->{module};
|
push @git_log_params, $self->{module};
|
||||||
}
|
}
|
||||||
# git-rev-list is the backend / plumbing version of git-log
|
# git-rev-list is the backend / plumbing version of git-log
|
||||||
open(GITLOG, '-|', 'git', 'rev-list', @git_log_params) or die "Cannot call git-rev-list: $!";
|
open(my $gitLogPipe, '-|', 'git', 'rev-list', @git_log_params)
|
||||||
|
or die "Cannot call git-rev-list: $!";
|
||||||
my @commits;
|
my @commits=readCommits($gitLogPipe);
|
||||||
|
close $gitLogPipe;
|
||||||
my %commit = ();
|
|
||||||
|
|
||||||
while ( <GITLOG> )
|
|
||||||
{
|
|
||||||
chomp;
|
|
||||||
if (m/^commit\s+(.*)$/) {
|
|
||||||
# on ^commit lines put the just seen commit in the stack
|
|
||||||
# and prime things for the next one
|
|
||||||
if (keys %commit) {
|
|
||||||
my %copy = %commit;
|
|
||||||
unshift @commits, \%copy;
|
|
||||||
%commit = ();
|
|
||||||
}
|
|
||||||
my @parents = split(m/\s+/, $1);
|
|
||||||
$commit{hash} = shift @parents;
|
|
||||||
$commit{parents} = \@parents;
|
|
||||||
} elsif (m/^(\w+?):\s+(.*)$/ && !exists($commit{message})) {
|
|
||||||
# on rfc822-like lines seen before we see any message,
|
|
||||||
# lowercase the entry and put it in the hash as key-value
|
|
||||||
$commit{lc($1)} = $2;
|
|
||||||
} else {
|
|
||||||
# message lines - skip initial empty line
|
|
||||||
# and trim whitespace
|
|
||||||
if (!exists($commit{message}) && m/^\s*$/) {
|
|
||||||
# define it to mark the end of headers
|
|
||||||
$commit{message} = '';
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
s/^\s+//; s/\s+$//; # trim ws
|
|
||||||
$commit{message} .= $_ . "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close GITLOG;
|
|
||||||
|
|
||||||
unshift @commits, \%commit if ( keys %commit );
|
|
||||||
|
|
||||||
# Now all the commits are in the @commits bucket
|
# Now all the commits are in the @commits bucket
|
||||||
# ordered by time DESC. for each commit that needs processing,
|
# ordered by time DESC. for each commit that needs processing,
|
||||||
@ -3294,7 +3259,7 @@ sub update
|
|||||||
}
|
}
|
||||||
|
|
||||||
# convert the date to CVS-happy format
|
# convert the date to CVS-happy format
|
||||||
$commit->{date} = "$2 $1 $4 $3 $5" if ( $commit->{date} =~ /^\w+\s+(\w+)\s+(\d+)\s+(\d+:\d+:\d+)\s+(\d+)\s+([+-]\d+)$/ );
|
my $cvsDate = convertToCvsDate($commit->{date});
|
||||||
|
|
||||||
if ( defined ( $lastpicked ) )
|
if ( defined ( $lastpicked ) )
|
||||||
{
|
{
|
||||||
@ -3303,7 +3268,7 @@ sub update
|
|||||||
while ( <FILELIST> )
|
while ( <FILELIST> )
|
||||||
{
|
{
|
||||||
chomp;
|
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 )
|
unless ( /^:\d{6}\s+([0-7]{6})\s+[a-f0-9]{40}\s+([a-f0-9]{40})\s+(\w)$/o )
|
||||||
{
|
{
|
||||||
die("Couldn't process git-diff-tree line : $_");
|
die("Couldn't process git-diff-tree line : $_");
|
||||||
}
|
}
|
||||||
@ -3313,11 +3278,7 @@ sub update
|
|||||||
|
|
||||||
# $log->debug("File mode=$mode, hash=$hash, change=$change, name=$name");
|
# $log->debug("File mode=$mode, hash=$hash, change=$change, name=$name");
|
||||||
|
|
||||||
my $git_perms = "";
|
my $dbMode = convertToDbMode($mode);
|
||||||
$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 ( $change eq "D" )
|
if ( $change eq "D" )
|
||||||
{
|
{
|
||||||
@ -3327,11 +3288,11 @@ sub update
|
|||||||
revision => $head->{$name}{revision} + 1,
|
revision => $head->{$name}{revision} + 1,
|
||||||
filehash => "deleted",
|
filehash => "deleted",
|
||||||
commithash => $commit->{hash},
|
commithash => $commit->{hash},
|
||||||
modified => $commit->{date},
|
modified => $cvsDate,
|
||||||
author => $commit->{author},
|
author => $commit->{author},
|
||||||
mode => $git_perms,
|
mode => $dbMode,
|
||||||
};
|
};
|
||||||
$self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
|
$self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $cvsDate, $commit->{author}, $dbMode);
|
||||||
}
|
}
|
||||||
elsif ( $change eq "M" || $change eq "T" )
|
elsif ( $change eq "M" || $change eq "T" )
|
||||||
{
|
{
|
||||||
@ -3341,11 +3302,11 @@ sub update
|
|||||||
revision => $head->{$name}{revision} + 1,
|
revision => $head->{$name}{revision} + 1,
|
||||||
filehash => $hash,
|
filehash => $hash,
|
||||||
commithash => $commit->{hash},
|
commithash => $commit->{hash},
|
||||||
modified => $commit->{date},
|
modified => $cvsDate,
|
||||||
author => $commit->{author},
|
author => $commit->{author},
|
||||||
mode => $git_perms,
|
mode => $dbMode,
|
||||||
};
|
};
|
||||||
$self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
|
$self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $cvsDate, $commit->{author}, $dbMode);
|
||||||
}
|
}
|
||||||
elsif ( $change eq "A" )
|
elsif ( $change eq "A" )
|
||||||
{
|
{
|
||||||
@ -3355,11 +3316,11 @@ sub update
|
|||||||
revision => $head->{$name}{revision} ? $head->{$name}{revision}+1 : 1,
|
revision => $head->{$name}{revision} ? $head->{$name}{revision}+1 : 1,
|
||||||
filehash => $hash,
|
filehash => $hash,
|
||||||
commithash => $commit->{hash},
|
commithash => $commit->{hash},
|
||||||
modified => $commit->{date},
|
modified => $cvsDate,
|
||||||
author => $commit->{author},
|
author => $commit->{author},
|
||||||
mode => $git_perms,
|
mode => $dbMode,
|
||||||
};
|
};
|
||||||
$self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
|
$self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $cvsDate, $commit->{author}, $dbMode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3382,7 +3343,7 @@ sub update
|
|||||||
die("Couldn't process git-ls-tree line : $_");
|
die("Couldn't process git-ls-tree line : $_");
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $git_perms, $git_type, $git_hash, $git_filename ) = ( $1, $2, $3, $4 );
|
my ( $mode, $git_type, $git_hash, $git_filename ) = ( $1, $2, $3, $4 );
|
||||||
|
|
||||||
$seen_files->{$git_filename} = 1;
|
$seen_files->{$git_filename} = 1;
|
||||||
|
|
||||||
@ -3392,18 +3353,10 @@ sub update
|
|||||||
$head->{$git_filename}{mode}
|
$head->{$git_filename}{mode}
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( $git_perms =~ /^\d\d\d(\d)\d\d/o )
|
my $dbMode = convertToDbMode($mode);
|
||||||
{
|
|
||||||
$git_perms = "";
|
|
||||||
$git_perms .= "r" if ( $1 & 4 );
|
|
||||||
$git_perms .= "w" if ( $1 & 2 );
|
|
||||||
$git_perms .= "x" if ( $1 & 1 );
|
|
||||||
} else {
|
|
||||||
$git_perms = "rw";
|
|
||||||
}
|
|
||||||
|
|
||||||
# unless the file exists with the same hash, we need to update it ...
|
# unless the file exists with the same hash, we need to update it ...
|
||||||
unless ( defined($oldhash) and $oldhash eq $git_hash and defined($oldmode) and $oldmode eq $git_perms )
|
unless ( defined($oldhash) and $oldhash eq $git_hash and defined($oldmode) and $oldmode eq $dbMode )
|
||||||
{
|
{
|
||||||
my $newrevision = ( $oldrevision or 0 ) + 1;
|
my $newrevision = ( $oldrevision or 0 ) + 1;
|
||||||
|
|
||||||
@ -3412,13 +3365,13 @@ sub update
|
|||||||
revision => $newrevision,
|
revision => $newrevision,
|
||||||
filehash => $git_hash,
|
filehash => $git_hash,
|
||||||
commithash => $commit->{hash},
|
commithash => $commit->{hash},
|
||||||
modified => $commit->{date},
|
modified => $cvsDate,
|
||||||
author => $commit->{author},
|
author => $commit->{author},
|
||||||
mode => $git_perms,
|
mode => $dbMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
$self->insert_rev($git_filename, $newrevision, $git_hash, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
|
$self->insert_rev($git_filename, $newrevision, $git_hash, $commit->{hash}, $cvsDate, $commit->{author}, $dbMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close FILELIST;
|
close FILELIST;
|
||||||
@ -3431,10 +3384,10 @@ sub update
|
|||||||
$head->{$file}{revision}++;
|
$head->{$file}{revision}++;
|
||||||
$head->{$file}{filehash} = "deleted";
|
$head->{$file}{filehash} = "deleted";
|
||||||
$head->{$file}{commithash} = $commit->{hash};
|
$head->{$file}{commithash} = $commit->{hash};
|
||||||
$head->{$file}{modified} = $commit->{date};
|
$head->{$file}{modified} = $cvsDate;
|
||||||
$head->{$file}{author} = $commit->{author};
|
$head->{$file}{author} = $commit->{author};
|
||||||
|
|
||||||
$self->insert_rev($file, $head->{$file}{revision}, $head->{$file}{filehash}, $commit->{hash}, $commit->{date}, $commit->{author}, $head->{$file}{mode});
|
$self->insert_rev($file, $head->{$file}{revision}, $head->{$file}{filehash}, $commit->{hash}, $cvsDate, $commit->{author}, $head->{$file}{mode});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# END : "Detect deleted files"
|
# END : "Detect deleted files"
|
||||||
@ -3472,6 +3425,87 @@ sub update
|
|||||||
$self->{dbh}->commit() or die "Failed to commit changes to SQLite";
|
$self->{dbh}->commit() or die "Failed to commit changes to SQLite";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub readCommits
|
||||||
|
{
|
||||||
|
my $pipeHandle = shift;
|
||||||
|
my @commits;
|
||||||
|
|
||||||
|
my %commit = ();
|
||||||
|
|
||||||
|
while ( <$pipeHandle> )
|
||||||
|
{
|
||||||
|
chomp;
|
||||||
|
if (m/^commit\s+(.*)$/) {
|
||||||
|
# on ^commit lines put the just seen commit in the stack
|
||||||
|
# and prime things for the next one
|
||||||
|
if (keys %commit) {
|
||||||
|
my %copy = %commit;
|
||||||
|
unshift @commits, \%copy;
|
||||||
|
%commit = ();
|
||||||
|
}
|
||||||
|
my @parents = split(m/\s+/, $1);
|
||||||
|
$commit{hash} = shift @parents;
|
||||||
|
$commit{parents} = \@parents;
|
||||||
|
} elsif (m/^(\w+?):\s+(.*)$/ && !exists($commit{message})) {
|
||||||
|
# on rfc822-like lines seen before we see any message,
|
||||||
|
# lowercase the entry and put it in the hash as key-value
|
||||||
|
$commit{lc($1)} = $2;
|
||||||
|
} else {
|
||||||
|
# message lines - skip initial empty line
|
||||||
|
# and trim whitespace
|
||||||
|
if (!exists($commit{message}) && m/^\s*$/) {
|
||||||
|
# define it to mark the end of headers
|
||||||
|
$commit{message} = '';
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
s/^\s+//; s/\s+$//; # trim ws
|
||||||
|
$commit{message} .= $_ . "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unshift @commits, \%commit if ( keys %commit );
|
||||||
|
|
||||||
|
return @commits;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub convertToCvsDate
|
||||||
|
{
|
||||||
|
my $date = shift;
|
||||||
|
# Convert from: "git rev-list --pretty" formatted date
|
||||||
|
# Convert to: "the format specified by RFC822 as modified by RFC1123."
|
||||||
|
# Example: 26 May 1997 13:01:40 -0400
|
||||||
|
if( $date =~ /^\w+\s+(\w+)\s+(\d+)\s+(\d+:\d+:\d+)\s+(\d+)\s+([+-]\d+)$/ )
|
||||||
|
{
|
||||||
|
$date = "$2 $1 $4 $3 $5";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $date;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub convertToDbMode
|
||||||
|
{
|
||||||
|
my $mode = shift;
|
||||||
|
|
||||||
|
# NOTE: The CVS protocol uses a string similar "u=rw,g=rw,o=rw",
|
||||||
|
# but the database "mode" column historically (and currently)
|
||||||
|
# only stores the "rw" (for user) part of the string.
|
||||||
|
# FUTURE: It might make more sense to persist the raw
|
||||||
|
# octal mode (or perhaps the final full CVS form) instead of
|
||||||
|
# this half-converted form, but it isn't currently worth the
|
||||||
|
# backwards compatibility headaches.
|
||||||
|
|
||||||
|
$mode=~/^\d\d(\d)\d{3}$/;
|
||||||
|
my $userBits=$1;
|
||||||
|
|
||||||
|
my $dbMode = "";
|
||||||
|
$dbMode .= "r" if ( $userBits & 4 );
|
||||||
|
$dbMode .= "w" if ( $userBits & 2 );
|
||||||
|
$dbMode .= "x" if ( $userBits & 1 );
|
||||||
|
$dbMode = "rw" if ( $dbMode eq "" );
|
||||||
|
|
||||||
|
return $dbMode;
|
||||||
|
}
|
||||||
|
|
||||||
sub insert_rev
|
sub insert_rev
|
||||||
{
|
{
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user