[svk-commit] r2994 - branches/seek_deleted_to/lib/SVK
nobody at bestpractical.com
nobody at bestpractical.com
Tue Jul 15 20:28:16 EDT 2008
Author: ruz
Date: Tue Jul 15 20:27:42 2008
New Revision: 2994
Modified:
branches/seek_deleted_to/lib/SVK/Path.pm
Log:
* add _seek_to_by_anchor in SVK::Path
** seek_to variant that search the path when path not exist,
but one of its anchors does
** follow copies as seek_to
** descend if a path shows up
** fix failing test
Modified: branches/seek_deleted_to/lib/SVK/Path.pm
==============================================================================
--- branches/seek_deleted_to/lib/SVK/Path.pm (original)
+++ branches/seek_deleted_to/lib/SVK/Path.pm Tue Jul 15 20:27:42 2008
@@ -54,7 +54,8 @@
use SVK::I18N;
use autouse 'SVK::Util' => qw( get_anchor catfile abs2rel
IS_WIN32 get_depot_anchor
- uri_escape );
+ uri_escape traverse_history );
+
use Class::Autouse qw(SVK::Editor::Dynamic SVK::Editor::TxnCleanup SVK::Editor::Tee);
use SVN::Delta;
@@ -771,15 +772,76 @@
sub seek_to {
my ($self, $revision) = @_;
- if ($revision < $self->revision) {
- while (my ($toroot, $fromroot, $path) = $self->nearest_copy) {
- last if $toroot->revision_root_revision <= $revision;
- $self = $self->mclone( path => $path,
- revision => $fromroot->revision_root_revision );
- }
+ return $self->mclone( revision => $revision )
+ if $revision >= $self->revision;
+
+ # if the path not exist then we should trace back history and watch copies
+ # and descedants
+ if ( $self->root->check_path( $self->path ) == $SVN::Node::none ) {
+ # find a parent that exist
+ my $tmp = $self->mclone( path_anchor => $self->path, targets => undef );
+ while ( $tmp->root->check_path( $tmp->path_anchor ) == $SVN::Node::none ) {
+ $tmp->anchorify;
+ }
+ my $res = $tmp->_seek_to_by_anchor( $revision );
+ return $res if $res;
}
- return $self->mclone( revision => $revision );
+ while (my ($toroot, $fromroot, $path) = $self->nearest_copy) {
+ last if $toroot->revision_root_revision <= $revision;
+ $self = $self->mclone( path => $path,
+ revision => $fromroot->revision_root_revision );
+ }
+ return $self->mclone( revision => $revision )
+}
+
+sub _seek_to_by_anchor {
+ my ($self, $revision) = @_;
+
+ my $anchor = $self->path_anchor;
+
+ my ($found_at_rev, $switch_to) = (undef, undef);
+ traverse_history (
+ root => $self->root,
+ path => $anchor,
+ cross => 1,
+ callback => sub {
+ my ($path, $rev) = @_;
+ if ($path ne $anchor) {
+ $anchor = $self->path_anchor( $path );
+ }
+
+ if ( $self->as_depotpath( $rev )->root->check_path( $self->path ) != $SVN::Node::none ) {
+ $found_at_rev = $rev < $revision? $revision : $rev;
+ return 0;
+ }
+ return 0 if $rev < $revision;
+
+ my @target = split m{/}, $self->path_target;
+ return 1 if @target < 2;
+
+ my @left = (shift @target);
+ my @right = (@target);
+
+ while ( @right >= 1 ) {
+ my $deanchored = $self->mclone(
+ path_anchor => $self->path_anchor .'/'. join( '/', @left ),
+ targets => [ join '/', @right ],
+ revision => $rev,
+ _root => undef,
+ );
+ if ( $deanchored->root->check_path( $deanchored->path_anchor ) == $SVN::Node::none ) {
+ last;
+ }
+ $switch_to = $deanchored;
+ push @left, shift @right;
+ }
+ return $switch_to? 0 : 1;
+ },
+ );
+ return $switch_to->_seek_to_by_anchor( $revision ) if $switch_to;
+ return $self->mclone( path => $self->path, targets => undef, revision => $found_at_rev )->seek_to( $revision )
+ if defined $found_at_rev;
}
*path_anchor = __PACKAGE__->make_accessor('path');
More information about the svk-commit
mailing list