Skip to content

Commit 2c3af7e

Browse files
Matthew Ogilviegitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent abd66f2 commit 2c3af7e

File tree

1 file changed

+105
-71
lines changed

1 file changed

+105
-71
lines changed

git-cvsserver.perl

Lines changed: 105 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3157,45 +3157,10 @@ sub update
31573157
push @git_log_params, $self->{module};
31583158
}
31593159
# git-rev-list is the backend / plumbing version of git-log
3160-
open(GITLOG, '-|', 'git', 'rev-list', @git_log_params) or die "Cannot call git-rev-list: $!";
3161-
3162-
my @commits;
3163-
3164-
my %commit = ();
3165-
3166-
while ( <GITLOG> )
3167-
{
3168-
chomp;
3169-
if (m/^commit\s+(.*)$/) {
3170-
# on ^commit lines put the just seen commit in the stack
3171-
# and prime things for the next one
3172-
if (keys %commit) {
3173-
my %copy = %commit;
3174-
unshift @commits, \%copy;
3175-
%commit = ();
3176-
}
3177-
my @parents = split(m/\s+/, $1);
3178-
$commit{hash} = shift @parents;
3179-
$commit{parents} = \@parents;
3180-
} elsif (m/^(\w+?):\s+(.*)$/ && !exists($commit{message})) {
3181-
# on rfc822-like lines seen before we see any message,
3182-
# lowercase the entry and put it in the hash as key-value
3183-
$commit{lc($1)} = $2;
3184-
} else {
3185-
# message lines - skip initial empty line
3186-
# and trim whitespace
3187-
if (!exists($commit{message}) && m/^\s*$/) {
3188-
# define it to mark the end of headers
3189-
$commit{message} = '';
3190-
next;
3191-
}
3192-
s/^\s+//; s/\s+$//; # trim ws
3193-
$commit{message} .= $_ . "\n";
3194-
}
3195-
}
3196-
close GITLOG;
3197-
3198-
unshift @commits, \%commit if ( keys %commit );
3160+
open(my $gitLogPipe, '-|', 'git', 'rev-list', @git_log_params)
3161+
or die "Cannot call git-rev-list: $!";
3162+
my @commits=readCommits($gitLogPipe);
3163+
close $gitLogPipe;
31993164

32003165
# Now all the commits are in the @commits bucket
32013166
# ordered by time DESC. for each commit that needs processing,
@@ -3294,7 +3259,7 @@ sub update
32943259
}
32953260

32963261
# convert the date to CVS-happy format
3297-
$commit->{date} = "$2 $1 $4 $3 $5" if ( $commit->{date} =~ /^\w+\s+(\w+)\s+(\d+)\s+(\d+:\d+:\d+)\s+(\d+)\s+([+-]\d+)$/ );
3262+
my $cvsDate = convertToCvsDate($commit->{date});
32983263

32993264
if ( defined ( $lastpicked ) )
33003265
{
@@ -3303,7 +3268,7 @@ sub update
33033268
while ( <FILELIST> )
33043269
{
33053270
chomp;
3306-
unless ( /^:\d{6}\s+\d{3}(\d)\d{2}\s+[a-zA-Z0-9]{40}\s+([a-zA-Z0-9]{40})\s+(\w)$/o )
3271+
unless ( /^:\d{6}\s+([0-7]{6})\s+[a-f0-9]{40}\s+([a-f0-9]{40})\s+(\w)$/o )
33073272
{
33083273
die("Couldn't process git-diff-tree line : $_");
33093274
}
@@ -3313,11 +3278,7 @@ sub update
33133278

33143279
# $log->debug("File mode=$mode, hash=$hash, change=$change, name=$name");
33153280

3316-
my $git_perms = "";
3317-
$git_perms .= "r" if ( $mode & 4 );
3318-
$git_perms .= "w" if ( $mode & 2 );
3319-
$git_perms .= "x" if ( $mode & 1 );
3320-
$git_perms = "rw" if ( $git_perms eq "" );
3281+
my $dbMode = convertToDbMode($mode);
33213282

33223283
if ( $change eq "D" )
33233284
{
@@ -3327,11 +3288,11 @@ sub update
33273288
revision => $head->{$name}{revision} + 1,
33283289
filehash => "deleted",
33293290
commithash => $commit->{hash},
3330-
modified => $commit->{date},
3291+
modified => $cvsDate,
33313292
author => $commit->{author},
3332-
mode => $git_perms,
3293+
mode => $dbMode,
33333294
};
3334-
$self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
3295+
$self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $cvsDate, $commit->{author}, $dbMode);
33353296
}
33363297
elsif ( $change eq "M" || $change eq "T" )
33373298
{
@@ -3341,11 +3302,11 @@ sub update
33413302
revision => $head->{$name}{revision} + 1,
33423303
filehash => $hash,
33433304
commithash => $commit->{hash},
3344-
modified => $commit->{date},
3305+
modified => $cvsDate,
33453306
author => $commit->{author},
3346-
mode => $git_perms,
3307+
mode => $dbMode,
33473308
};
3348-
$self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
3309+
$self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $cvsDate, $commit->{author}, $dbMode);
33493310
}
33503311
elsif ( $change eq "A" )
33513312
{
@@ -3355,11 +3316,11 @@ sub update
33553316
revision => $head->{$name}{revision} ? $head->{$name}{revision}+1 : 1,
33563317
filehash => $hash,
33573318
commithash => $commit->{hash},
3358-
modified => $commit->{date},
3319+
modified => $cvsDate,
33593320
author => $commit->{author},
3360-
mode => $git_perms,
3321+
mode => $dbMode,
33613322
};
3362-
$self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
3323+
$self->insert_rev($name, $head->{$name}{revision}, $hash, $commit->{hash}, $cvsDate, $commit->{author}, $dbMode);
33633324
}
33643325
else
33653326
{
@@ -3382,7 +3343,7 @@ sub update
33823343
die("Couldn't process git-ls-tree line : $_");
33833344
}
33843345

3385-
my ( $git_perms, $git_type, $git_hash, $git_filename ) = ( $1, $2, $3, $4 );
3346+
my ( $mode, $git_type, $git_hash, $git_filename ) = ( $1, $2, $3, $4 );
33863347

33873348
$seen_files->{$git_filename} = 1;
33883349

@@ -3392,18 +3353,10 @@ sub update
33923353
$head->{$git_filename}{mode}
33933354
);
33943355

3395-
if ( $git_perms =~ /^\d\d\d(\d)\d\d/o )
3396-
{
3397-
$git_perms = "";
3398-
$git_perms .= "r" if ( $1 & 4 );
3399-
$git_perms .= "w" if ( $1 & 2 );
3400-
$git_perms .= "x" if ( $1 & 1 );
3401-
} else {
3402-
$git_perms = "rw";
3403-
}
3356+
my $dbMode = convertToDbMode($mode);
34043357

34053358
# unless the file exists with the same hash, we need to update it ...
3406-
unless ( defined($oldhash) and $oldhash eq $git_hash and defined($oldmode) and $oldmode eq $git_perms )
3359+
unless ( defined($oldhash) and $oldhash eq $git_hash and defined($oldmode) and $oldmode eq $dbMode )
34073360
{
34083361
my $newrevision = ( $oldrevision or 0 ) + 1;
34093362

@@ -3412,13 +3365,13 @@ sub update
34123365
revision => $newrevision,
34133366
filehash => $git_hash,
34143367
commithash => $commit->{hash},
3415-
modified => $commit->{date},
3368+
modified => $cvsDate,
34163369
author => $commit->{author},
3417-
mode => $git_perms,
3370+
mode => $dbMode,
34183371
};
34193372

34203373

3421-
$self->insert_rev($git_filename, $newrevision, $git_hash, $commit->{hash}, $commit->{date}, $commit->{author}, $git_perms);
3374+
$self->insert_rev($git_filename, $newrevision, $git_hash, $commit->{hash}, $cvsDate, $commit->{author}, $dbMode);
34223375
}
34233376
}
34243377
close FILELIST;
@@ -3431,10 +3384,10 @@ sub update
34313384
$head->{$file}{revision}++;
34323385
$head->{$file}{filehash} = "deleted";
34333386
$head->{$file}{commithash} = $commit->{hash};
3434-
$head->{$file}{modified} = $commit->{date};
3387+
$head->{$file}{modified} = $cvsDate;
34353388
$head->{$file}{author} = $commit->{author};
34363389

3437-
$self->insert_rev($file, $head->{$file}{revision}, $head->{$file}{filehash}, $commit->{hash}, $commit->{date}, $commit->{author}, $head->{$file}{mode});
3390+
$self->insert_rev($file, $head->{$file}{revision}, $head->{$file}{filehash}, $commit->{hash}, $cvsDate, $commit->{author}, $head->{$file}{mode});
34383391
}
34393392
}
34403393
# END : "Detect deleted files"
@@ -3472,6 +3425,87 @@ sub update
34723425
$self->{dbh}->commit() or die "Failed to commit changes to SQLite";
34733426
}
34743427

3428+
sub readCommits
3429+
{
3430+
my $pipeHandle = shift;
3431+
my @commits;
3432+
3433+
my %commit = ();
3434+
3435+
while ( <$pipeHandle> )
3436+
{
3437+
chomp;
3438+
if (m/^commit\s+(.*)$/) {
3439+
# on ^commit lines put the just seen commit in the stack
3440+
# and prime things for the next one
3441+
if (keys %commit) {
3442+
my %copy = %commit;
3443+
unshift @commits, \%copy;
3444+
%commit = ();
3445+
}
3446+
my @parents = split(m/\s+/, $1);
3447+
$commit{hash} = shift @parents;
3448+
$commit{parents} = \@parents;
3449+
} elsif (m/^(\w+?):\s+(.*)$/ && !exists($commit{message})) {
3450+
# on rfc822-like lines seen before we see any message,
3451+
# lowercase the entry and put it in the hash as key-value
3452+
$commit{lc($1)} = $2;
3453+
} else {
3454+
# message lines - skip initial empty line
3455+
# and trim whitespace
3456+
if (!exists($commit{message}) && m/^\s*$/) {
3457+
# define it to mark the end of headers
3458+
$commit{message} = '';
3459+
next;
3460+
}
3461+
s/^\s+//; s/\s+$//; # trim ws
3462+
$commit{message} .= $_ . "\n";
3463+
}
3464+
}
3465+
3466+
unshift @commits, \%commit if ( keys %commit );
3467+
3468+
return @commits;
3469+
}
3470+
3471+
sub convertToCvsDate
3472+
{
3473+
my $date = shift;
3474+
# Convert from: "git rev-list --pretty" formatted date
3475+
# Convert to: "the format specified by RFC822 as modified by RFC1123."
3476+
# Example: 26 May 1997 13:01:40 -0400
3477+
if( $date =~ /^\w+\s+(\w+)\s+(\d+)\s+(\d+:\d+:\d+)\s+(\d+)\s+([+-]\d+)$/ )
3478+
{
3479+
$date = "$2 $1 $4 $3 $5";
3480+
}
3481+
3482+
return $date;
3483+
}
3484+
3485+
sub convertToDbMode
3486+
{
3487+
my $mode = shift;
3488+
3489+
# NOTE: The CVS protocol uses a string similar "u=rw,g=rw,o=rw",
3490+
# but the database "mode" column historically (and currently)
3491+
# only stores the "rw" (for user) part of the string.
3492+
# FUTURE: It might make more sense to persist the raw
3493+
# octal mode (or perhaps the final full CVS form) instead of
3494+
# this half-converted form, but it isn't currently worth the
3495+
# backwards compatibility headaches.
3496+
3497+
$mode=~/^\d\d(\d)\d{3}$/;
3498+
my $userBits=$1;
3499+
3500+
my $dbMode = "";
3501+
$dbMode .= "r" if ( $userBits & 4 );
3502+
$dbMode .= "w" if ( $userBits & 2 );
3503+
$dbMode .= "x" if ( $userBits & 1 );
3504+
$dbMode = "rw" if ( $dbMode eq "" );
3505+
3506+
return $dbMode;
3507+
}
3508+
34753509
sub insert_rev
34763510
{
34773511
my $self = shift;

0 commit comments

Comments
 (0)