[svk-commit] r2716 - in trunk: lib/SVK lib/SVK/Merge t

nobody at bestpractical.com nobody at bestpractical.com
Wed Mar 26 04:28:20 EDT 2008


Author: clkao
Date: Wed Mar 26 04:28:20 2008
New Revision: 2716

Modified:
   trunk/   (props changed)
   trunk/lib/SVK/Merge.pm
   trunk/lib/SVK/Merge/Info.pm
   trunk/t/05svm.t

Log:
- Merge //mirror/svk/branches/merge_perf to //mirror/svk/trunk

Modified: trunk/lib/SVK/Merge.pm
==============================================================================
--- trunk/lib/SVK/Merge.pm	(original)
+++ trunk/lib/SVK/Merge.pm	Wed Mar 26 04:28:20 2008
@@ -203,7 +203,8 @@
     my $repos = $self->{repos};
     my $fs = $repos->fs;
     my $yrev = $fs->youngest_rev;
-    my ($srcinfo, $dstinfo) = map {$self->find_merge_sources ($_)} ($src, $dst);
+    my ($srcinfo2, $dstinfo2) = map {$self->find_merge_sources2($_)} ($src, $dst);
+    my $joint_info = $srcinfo2->intersect($dstinfo2)->resolve($src->depot);
     my ($basepath, $baserev, $baseentry);
     my ($merge_base, $merge_baserev) = $self->{merge_base} ?
 	split(/:/, $self->{merge_base}) : ('', undef);
@@ -218,15 +219,13 @@
 	if $merge_base && $merge_baserev;
 
     if ($merge_base) {
-        my %allowed = map { ($_ =~ /:(.*)$/) => $_ }
-            grep exists $srcinfo->{$_} && exists $dstinfo->{$_},
-            keys %{ { %$srcinfo, %$dstinfo } };
+        my %allowed = map { ($_ =~ /:(.*)$/) => $_ } sort keys %$joint_info;
 
         unless ($allowed{$merge_base}) {
 	    die loc("base '%1' is not allowed without revision specification.\nUse one of the next or provide revision:%2\n",
                 $merge_base, (join '', map "\n    $_", sort keys %allowed) );
         }
-	my $rev = min ($srcinfo->{$allowed{$merge_base}}, $dstinfo->{$allowed{$merge_base}});
+	my $rev = $joint_info->{$allowed{$merge_base}};
 	return ($src->as_depotpath->new
 		(path => $merge_base, revision => $rev, targets => undef),
 		$rev);
@@ -237,10 +236,9 @@
 
     my @preempt_result;
 
-    for (grep {exists $srcinfo->{$_} && exists $dstinfo->{$_}}
-	 (sort keys %{ { %$srcinfo, %$dstinfo } })) {
+    for (sort keys %{$joint_info}) {
 	my ($path) = m/:(.*)$/;
-	my $rev = min ($srcinfo->{$_}, $dstinfo->{$_});
+	my $rev = $joint_info->{$_};
 
 	# when the base is one of src or dst, make sure the base is
 	# still the same node (not removed and replaced)
@@ -256,7 +254,7 @@
             if ($path eq $dst->path &&
                 $src->is_merged_from($dst->mclone(revision => $rev))) {
 
-                my ($base, $from) = $self->_mk_base_and_from( $src, $dstinfo, $basepath, $baserev );
+                my ($base, $from) = $self->_mk_base_and_from( $src, $dstinfo2, $basepath, $baserev );
                 # this takes precedence than other potential base or
                 # rebasable base that is on src.
                 if (my $rebased = $self->_rebase2( $src, $dst, $base)) {
@@ -264,7 +262,7 @@
                 }
             }
             elsif ($path eq $src->path && $dst->is_merged_from($src->mclone(revision => $rev))) {
-                my ($base, $from) = $self->_mk_base_and_from( $src, $dstinfo, $basepath, $baserev );
+                my ($base, $from) = $self->_mk_base_and_from( $src, $dstinfo2, $basepath, $baserev );
                 $base = $self->_rebase2( $dst, $src, $base) || $base;
                 @preempt_result = ($base, $from);
             }
@@ -284,6 +282,8 @@
 
     # XXX: document this, cf t/07smerge-foreign.t
     if ($basepath ne $src->path && $basepath ne $dst->path) {
+        my ($srcinfo, $dstinfo) = map {$self->find_merge_sources ($_)} ($src, $dst);
+
 	my ($fromrev, $torev) = ($srcinfo->{$baseentry}, $dstinfo->{$baseentry});
 	($fromrev, $torev) = ($torev, $fromrev) if $torev < $fromrev;
 	if (my ($mrev, $merge) =
@@ -296,12 +296,12 @@
 		if $minfo->subset_of ($srcinfo) && $minfo->subset_of ($dstinfo);
 	}
     }
-    return $self->_mk_base_and_from( $src, $dstinfo, $basepath, $baserev );
+    return $self->_mk_base_and_from( $src, $dstinfo2, $basepath, $baserev );
 }
 
 sub _mk_base_and_from {
     my $self = shift;
-    my ($src, $dstinfo, $basepath, $baserev) = @_;
+    my ($src, $dstinfo2, $basepath, $baserev) = @_;
 
     my $base = $src->as_depotpath->new
 	(path => $basepath, revision => $baserev, targets => undef);
@@ -310,7 +310,8 @@
 
     # When /A:1 is copied to /B:2, then removed, /B:2 copied to /A:5
     # the fromrev shouldn't be /A:1, as it confuses the copy detection during merge.
-    my $from = $dstinfo->{$src->depot->repos->fs->get_uuid.':'.$src->path};
+    my $from = $dstinfo2->{$src->universal->ukey};
+    $from = $from->local($src->depot)->revision if $from;
     if ($from) {
 	my ($toroot, $fromroot) = $src->nearest_copy;
 	$from = 0 if $toroot && $from < $toroot->revision_root_revision;
@@ -374,6 +375,27 @@
     return $minfo;
 }
 
+sub find_merge_sources2 {
+    my ($self, $target) = @_;
+    my $pool = SVN::Pool->new_default;
+    my $info = $self->merge_info ($target->new);
+
+    $target = $target->new->as_depotpath ($self->{xd}{checkout}->get ($target->copath. 1)->{revision})
+	if $target->isa('SVK::Path::Checkout');
+    $info->add_target($target);
+
+    return $info if !$target->root->check_path($target->path);
+
+    for (reverse $target->copy_ancestors) {
+	my ($path, $rev) = @$_;
+        # XXX: short circuit it when we have the ancestor already.
+        my $t = $target->mclone( targets => undef, path => $path, revision => $rev)->universal;
+        $info->add_target( $t )
+            if !$info->{ $t->ukey } || $info->{ $t->ukey }->rev < $t->rev;
+    }
+    return $info;
+}
+
 sub _get_new_ticket {
     my ($self, $srcinfo) = @_;
     my $dstinfo = $self->merge_info($self->{dst});

Modified: trunk/lib/SVK/Merge/Info.pm
==============================================================================
--- trunk/lib/SVK/Merge/Info.pm	(original)
+++ trunk/lib/SVK/Merge/Info.pm	Wed Mar 26 04:28:20 2008
@@ -181,12 +181,27 @@
     return $new;
 }
 
+sub intersect {
+    my ($self, $other) = @_;
+    # bring merge history up to date as from source
+    my $new = SVK::Merge::Info->new;
+    for ( keys %{ { %$self, %$other } } ) {
+        if ( $self->{$_} && $other->{$_} ) {
+            $new->{$_} = $self->{$_}{rev} < $other->{$_}{rev}
+                ? $self->{$_}
+                : $other->{$_};
+        }
+    }
+    return $new;
+}
+
 =item resolve
 
 =cut
 
 sub resolve {
     my ( $self, $depot ) = @_;
+
     my $uuid = $depot->repos->fs->get_uuid;
     return {
         map {

Modified: trunk/t/05svm.t
==============================================================================
--- trunk/t/05svm.t	(original)
+++ trunk/t/05svm.t	Wed Mar 26 04:28:20 2008
@@ -98,7 +98,7 @@
         "Syncing $uri/A-99",
         'Retrieving log information from 1 to 28',
         'Committed revision 13 from revision 28.',
-        'Auto-merging (10, 13) /m-99 to /m-99-copy (base /m-99:10).',
+        'Auto-merging (0, 13) /m-99 to /m-99-copy (base /:0).',
         'A   Q',
         'A   Q/qz',
         'A   T',


More information about the svk-commit mailing list