git-svn: extract reusable code into utility functions
Extacted canonicalize_path() in the main package. Created new Git::SVN::Util package with an md5sum() function. A new package was created so that Digest::MD5 did not have to be loaded in the main package. Replaced code in the SVN::Git::Editor and SVN::Git::Fetcher packages with calls to md5sum(). Extracted the format_svn_date(), parse_git_date() and set_local_timezone() functions within the Git::SVN::Log package. Signed-off-by: David D. Kilzer <ddkilzer@kilzer.net> Acked-by: Eric Wong <normalperson@yhbt.net>
This commit is contained in:
parent
8d92f24852
commit
b2b3ada7fc
96
git-svn.perl
96
git-svn.perl
@ -48,7 +48,8 @@ BEGIN {
|
|||||||
foreach (qw/command command_oneline command_noisy command_output_pipe
|
foreach (qw/command command_oneline command_noisy command_output_pipe
|
||||||
command_input_pipe command_close_pipe/) {
|
command_input_pipe command_close_pipe/) {
|
||||||
for my $package ( qw(SVN::Git::Editor SVN::Git::Fetcher
|
for my $package ( qw(SVN::Git::Editor SVN::Git::Fetcher
|
||||||
Git::SVN::Migration Git::SVN::Log Git::SVN),
|
Git::SVN::Migration Git::SVN::Log Git::SVN
|
||||||
|
Git::SVN::Util),
|
||||||
__PACKAGE__) {
|
__PACKAGE__) {
|
||||||
*{"${package}::$_"} = \&{"Git::$_"};
|
*{"${package}::$_"} = \&{"Git::$_"};
|
||||||
}
|
}
|
||||||
@ -583,6 +584,17 @@ sub cmd_create_ignore {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub canonicalize_path {
|
||||||
|
my ($path) = @_;
|
||||||
|
# File::Spec->canonpath doesn't collapse x/../y into y (for a
|
||||||
|
# good reason), so let's do this manually.
|
||||||
|
$path =~ s#/+#/#g;
|
||||||
|
$path =~ s#/\.(?:/|$)#/#g;
|
||||||
|
$path =~ s#/[^/]+/\.\.##g;
|
||||||
|
$path =~ s#/$##g;
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
# get_svnprops(PATH)
|
# get_svnprops(PATH)
|
||||||
# ------------------
|
# ------------------
|
||||||
# Helper for cmd_propget and cmd_proplist below.
|
# Helper for cmd_propget and cmd_proplist below.
|
||||||
@ -600,12 +612,7 @@ sub get_svnprops {
|
|||||||
|
|
||||||
# canonicalize the path (otherwise libsvn will abort or fail to
|
# canonicalize the path (otherwise libsvn will abort or fail to
|
||||||
# find the file)
|
# find the file)
|
||||||
# File::Spec->canonpath doesn't collapse x/../y into y (for a
|
$path = canonicalize_path($path);
|
||||||
# good reason), so let's do this manually.
|
|
||||||
$path =~ s#/+#/#g;
|
|
||||||
$path =~ s#/\.(?:/|$)#/#g;
|
|
||||||
$path =~ s#/[^/]+/\.\.##g;
|
|
||||||
$path =~ s#/$##g;
|
|
||||||
|
|
||||||
my $r = (defined $_revision ? $_revision : $gs->ra->get_latest_revnum);
|
my $r = (defined $_revision ? $_revision : $gs->ra->get_latest_revnum);
|
||||||
my $props;
|
my $props;
|
||||||
@ -1043,6 +1050,27 @@ sub linearize_history {
|
|||||||
(\@linear_refs, \%parents);
|
(\@linear_refs, \%parents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
package Git::SVN::Util;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Digest::MD5;
|
||||||
|
|
||||||
|
sub md5sum {
|
||||||
|
my $arg = shift;
|
||||||
|
my $ref = ref $arg;
|
||||||
|
my $md5 = Digest::MD5->new();
|
||||||
|
if ($ref eq 'GLOB' || $ref eq 'IO::File') {
|
||||||
|
$md5->addfile($arg) or croak $!;
|
||||||
|
} elsif ($ref eq 'SCALAR') {
|
||||||
|
$md5->add($$arg) or croak $!;
|
||||||
|
} elsif (!$ref) {
|
||||||
|
$md5->add($arg) or croak $!;
|
||||||
|
} else {
|
||||||
|
::fatal "Can't provide MD5 hash for unknown ref type: '", $ref, "'";
|
||||||
|
}
|
||||||
|
return $md5->hexdigest();
|
||||||
|
}
|
||||||
|
|
||||||
package Git::SVN;
|
package Git::SVN;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
@ -2610,7 +2638,6 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
use Carp qw/croak/;
|
use Carp qw/croak/;
|
||||||
use IO::File qw//;
|
use IO::File qw//;
|
||||||
use Digest::MD5;
|
|
||||||
|
|
||||||
# file baton members: path, mode_a, mode_b, pool, fh, blob, base
|
# file baton members: path, mode_a, mode_b, pool, fh, blob, base
|
||||||
sub new {
|
sub new {
|
||||||
@ -2762,9 +2789,7 @@ sub apply_textdelta {
|
|||||||
|
|
||||||
if (defined $exp) {
|
if (defined $exp) {
|
||||||
seek $base, 0, 0 or croak $!;
|
seek $base, 0, 0 or croak $!;
|
||||||
my $md5 = Digest::MD5->new;
|
my $got = Git::SVN::Util::md5sum($base);
|
||||||
$md5->addfile($base);
|
|
||||||
my $got = $md5->hexdigest;
|
|
||||||
die "Checksum mismatch: $fb->{path} $fb->{blob}\n",
|
die "Checksum mismatch: $fb->{path} $fb->{blob}\n",
|
||||||
"expected: $exp\n",
|
"expected: $exp\n",
|
||||||
" got: $got\n" if ($got ne $exp);
|
" got: $got\n" if ($got ne $exp);
|
||||||
@ -2783,9 +2808,7 @@ sub close_file {
|
|||||||
if (my $fh = $fb->{fh}) {
|
if (my $fh = $fb->{fh}) {
|
||||||
if (defined $exp) {
|
if (defined $exp) {
|
||||||
seek($fh, 0, 0) or croak $!;
|
seek($fh, 0, 0) or croak $!;
|
||||||
my $md5 = Digest::MD5->new;
|
my $got = Git::SVN::Util::md5sum($fh);
|
||||||
$md5->addfile($fh);
|
|
||||||
my $got = $md5->hexdigest;
|
|
||||||
if ($got ne $exp) {
|
if ($got ne $exp) {
|
||||||
die "Checksum mismatch: $path\n",
|
die "Checksum mismatch: $path\n",
|
||||||
"expected: $exp\n got: $got\n";
|
"expected: $exp\n got: $got\n";
|
||||||
@ -2837,7 +2860,6 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
use Carp qw/croak/;
|
use Carp qw/croak/;
|
||||||
use IO::File;
|
use IO::File;
|
||||||
use Digest::MD5;
|
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
my ($class, $opts) = @_;
|
my ($class, $opts) = @_;
|
||||||
@ -3141,11 +3163,9 @@ sub chg_file {
|
|||||||
$fh->flush == 0 or croak $!;
|
$fh->flush == 0 or croak $!;
|
||||||
seek $fh, 0, 0 or croak $!;
|
seek $fh, 0, 0 or croak $!;
|
||||||
|
|
||||||
my $md5 = Digest::MD5->new;
|
my $exp = Git::SVN::Util::md5sum($fh);
|
||||||
$md5->addfile($fh) or croak $!;
|
|
||||||
seek $fh, 0, 0 or croak $!;
|
seek $fh, 0, 0 or croak $!;
|
||||||
|
|
||||||
my $exp = $md5->hexdigest;
|
|
||||||
my $pool = SVN::Pool->new;
|
my $pool = SVN::Pool->new;
|
||||||
my $atd = $self->apply_textdelta($fbat, undef, $pool);
|
my $atd = $self->apply_textdelta($fbat, undef, $pool);
|
||||||
my $got = SVN::TxDelta::send_stream($fh, @$atd, $pool);
|
my $got = SVN::TxDelta::send_stream($fh, @$atd, $pool);
|
||||||
@ -3859,6 +3879,29 @@ sub run_pager {
|
|||||||
exec $pager or ::fatal "Can't run pager: $! ($pager)";
|
exec $pager or ::fatal "Can't run pager: $! ($pager)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub format_svn_date {
|
||||||
|
return strftime("%Y-%m-%d %H:%M:%S %z (%a, %d %b %Y)", localtime(shift));
|
||||||
|
}
|
||||||
|
|
||||||
|
sub parse_git_date {
|
||||||
|
my ($t, $tz) = @_;
|
||||||
|
# Date::Parse isn't in the standard Perl distro :(
|
||||||
|
if ($tz =~ s/^\+//) {
|
||||||
|
$t += tz_to_s_offset($tz);
|
||||||
|
} elsif ($tz =~ s/^\-//) {
|
||||||
|
$t -= tz_to_s_offset($tz);
|
||||||
|
}
|
||||||
|
return $t;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub set_local_timezone {
|
||||||
|
if (defined $TZ) {
|
||||||
|
$ENV{TZ} = $TZ;
|
||||||
|
} else {
|
||||||
|
delete $ENV{TZ};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub tz_to_s_offset {
|
sub tz_to_s_offset {
|
||||||
my ($tz) = @_;
|
my ($tz) = @_;
|
||||||
$tz =~ s/(\d\d)$//;
|
$tz =~ s/(\d\d)$//;
|
||||||
@ -3879,13 +3922,7 @@ sub get_author_info {
|
|||||||
$dest->{t} = $t;
|
$dest->{t} = $t;
|
||||||
$dest->{tz} = $tz;
|
$dest->{tz} = $tz;
|
||||||
$dest->{a} = $au;
|
$dest->{a} = $au;
|
||||||
# Date::Parse isn't in the standard Perl distro :(
|
$dest->{t_utc} = parse_git_date($t, $tz);
|
||||||
if ($tz =~ s/^\+//) {
|
|
||||||
$t += tz_to_s_offset($tz);
|
|
||||||
} elsif ($tz =~ s/^\-//) {
|
|
||||||
$t -= tz_to_s_offset($tz);
|
|
||||||
}
|
|
||||||
$dest->{t_utc} = $t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub process_commit {
|
sub process_commit {
|
||||||
@ -3939,8 +3976,7 @@ sub show_commit_normal {
|
|||||||
my ($c) = @_;
|
my ($c) = @_;
|
||||||
print commit_log_separator, "r$c->{r} | ";
|
print commit_log_separator, "r$c->{r} | ";
|
||||||
print "$c->{c} | " if $show_commit;
|
print "$c->{c} | " if $show_commit;
|
||||||
print "$c->{a} | ", strftime("%Y-%m-%d %H:%M:%S %z (%a, %d %b %Y)",
|
print "$c->{a} | ", format_svn_date($c->{t_utc}), ' | ';
|
||||||
localtime($c->{t_utc})), ' | ';
|
|
||||||
my $nr_line = 0;
|
my $nr_line = 0;
|
||||||
|
|
||||||
if (my $l = $c->{l}) {
|
if (my $l = $c->{l}) {
|
||||||
@ -3980,11 +4016,7 @@ sub cmd_show_log {
|
|||||||
my (@args) = @_;
|
my (@args) = @_;
|
||||||
my ($r_min, $r_max);
|
my ($r_min, $r_max);
|
||||||
my $r_last = -1; # prevent dupes
|
my $r_last = -1; # prevent dupes
|
||||||
if (defined $TZ) {
|
set_local_timezone();
|
||||||
$ENV{TZ} = $TZ;
|
|
||||||
} else {
|
|
||||||
delete $ENV{TZ};
|
|
||||||
}
|
|
||||||
if (defined $::_revision) {
|
if (defined $::_revision) {
|
||||||
if ($::_revision =~ /^(\d+):(\d+)$/) {
|
if ($::_revision =~ /^(\d+):(\d+)$/) {
|
||||||
($r_min, $r_max) = ($1, $2);
|
($r_min, $r_max) = ($1, $2);
|
||||||
|
Loading…
Reference in New Issue
Block a user