SVN-Mirror
view release on metacpan or search on metacpan
lib/SVN/Mirror/Ra.pm view on Meta::CPAN
}
sub switch {
my ($self, $url) = @_;
my $ra = $self->_new_ra (url => $url);
# XXX: get proper uuid like init_state
die "uuid is different" unless $ra->get_uuid eq $self->{source_uuid};
# warn "===> switching from $self->{source} to $url";
# get a txn, change rsource and rsource_uuidto new url
}
sub get_latest_rev {
my ($self, $ra) = @_;
# don't care about real last-modified rev num unless in skip to mode.
return $ra->get_latest_revnum
unless $self->{skip_to};
my ($rev, $headrev);
my $offset = 2;
# there were once get_log2, but it then was refactored by the svn_ra
# overhaul. We have to check the version.
# also, it's harmful to make use of the limited get_log for svn 1.2
# vs svnserve 1.1, it retrieves all logs and leave the connection
# in an inconsistent state.
if ($SVN::Core::VERSION ge '1.2.0' && $self->{rsource} !~ m/^svn/) {
$ra->get_log ([''], $ra->get_latest_revnum, 0, 1, 0, 1,
sub { $rev = $_[1] });
}
else {
until (defined $rev) {
$headrev = $ra->get_latest_revnum
unless defined $headrev;
$headrev -= $offset;
$ra->get_log ([''], -1, $headrev,
($SVN::Core::VERSION ge '1.2.0') ? (0) : (),
0, 1,
sub { $rev = $_[1] unless defined $rev});
if ( $offset < $headrev ) {
$offset*=2;
}
else {
$offset = 2;
}
}
}
die 'fatal: unable to find last-modified revision'
unless defined $rev;
return $rev;
}
sub run {
my $self = shift;
my $ra = $self->_new_ra;
my $latestrev = $self->get_latest_rev ($ra);
$self->lock ('sync');
$self->load_fromrev;
# there were code here to use find_local_rev, but it will get base that
# is too old for use, if there are relocate happening.
# but this might cause race condition, while we also have lock now, need
# to take a closer look.
$self->{headrev} = $self->{fs}->youngest_rev;
if ($self->{skip_to} && $self->{skip_to} =~ m/^HEAD(?:-(\d+))?/) {
$self->{skip_to} = $latestrev - ($1 || 0);
}
my $startrev = ($self->{skip_to} || 0);
$startrev = $self->{fromrev}+1 if $self->{fromrev}+1 > $startrev;
my $endrev = shift || -1;
if ($endrev && $endrev =~ m/^HEAD(?:-(\d+))?/) {
$endrev = $latestrev - ($1 || 0);
}
$endrev = $latestrev if $endrev == -1;
print "Syncing $self->{source}".($self->_relayed ? " via $self->{rsource}\n" : "\n");
$self->unlock ('sync'), return
unless $endrev == -1 || $startrev <= $endrev;
print "Retrieving log information from $startrev to $endrev\n";
my $firsttime = 1;
eval {
$ra->get_log ([''], $startrev, $endrev,
($SVN::Core::VERSION ge '1.2.0') ? (0) : (),
1, 1,
sub {
my ($paths, $rev, $author, $date, $msg, $pool) = @_;
# for the first time, skip_to might not hit
# active revision in the tree. adjust to make it so.
if ($firsttime) {
$self->{skip_to} = $rev if defined $self->{skip_to};
$firsttime = 0;
}
# move the anchor detection stuff to &mirror ?
if (defined $self->{skip_to} && $rev <= $self->{skip_to}) {
# XXX: get the logs for skipped changes
$self->{rev_incomplete} = 1;
$author = 'svm';
$msg = sprintf('SVM: skipping changes %d-%d for %s',
$self->{fromrev}, $rev, $self->{rsource});
}
else {
delete $self->{rev_incomplete};
}
$self->mirror($self->{fromrev}, $paths, $rev, $author,
$date, $msg, $pool);
$self->{fromrev} = $rev;
});
};
delete $self->{cached_ra};
delete $self->{cached_ra_url};
$self->unlock ('sync');
return unless $@;
if ($@ =~ /no item/) {
print "Mirror source already removed.\n";
undef $@;
( run in 0.989 second using v1.01-cache-2.11-cpan-5511b514fd6 )