@@ -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+
34753509sub insert_rev
34763510{
34773511 my $self = shift ;
0 commit comments