[svk-commit] r2633 - in trunk: lib/SVK lib/SVK/Editor t

nobody at bestpractical.com nobody at bestpractical.com
Sat Dec 15 08:22:32 EST 2007


Author: clkao
Date: Sat Dec 15 08:22:32 2007
New Revision: 2633

Modified:
   trunk/   (props changed)
   trunk/lib/SVK/Editor/Merge.pm
   trunk/lib/SVK/Merge.pm
   trunk/t/07smerge-copy.t
   trunk/t/07smerge-cpreplace.t

Log:
When merging a copy with modification to the copied source, it
may cause a checksum error because we are using the current active
txn as inspector, where it doesn't really account for local
modification for the copy source.

 r3839 at mtl (orig r2630):  clkao | 2007-12-15 17:10:49 +0800
 - Create branch smcp-base-bug
 r3840 at mtl (orig r2631):  clkao | 2007-12-15 17:12:21 +0800
 make resolve_base returns an appropriate inspector and use it.
 r3841 at mtl (orig r2632):  clkao | 2007-12-15 21:02:14 +0800
 when using inspector to check with the copysource base paths, we need to
 use non-txn inspector so we don't get fooled by nodes we touch during
 the current merge.
 


Modified: trunk/lib/SVK/Editor/Merge.pm
==============================================================================
--- trunk/lib/SVK/Editor/Merge.pm	(original)
+++ trunk/lib/SVK/Editor/Merge.pm	Sat Dec 15 08:22:32 2007
@@ -58,7 +58,7 @@
 use autouse 'SVK::Util'
     => qw( slurp_fh md5_fh tmpfile devnull abs2rel );
 
-__PACKAGE__->mk_accessors(qw(inspector notify storage ticket cb_merged));
+__PACKAGE__->mk_accessors(qw(inspector static_inspector notify storage ticket cb_merged));
 
 use Class::Autouse qw(SVK::Inspector::Root SVK::Notify
 		      Data::Hierarchy IO::Digest);
@@ -280,7 +280,7 @@
 	if (defined $arg[0]) {
 	    $self->{notify}->hist_status ($path, '+');
 	    @arg = $self->resolve_copy($path, @arg);
-	    $self->{info}{$path}{baseinfo} = [$self->_resolve_base($path)];
+	    $self->{info}{$path}{baseinfo} = [$self->resolve_base($path, 0, $pool)];
 	    $self->{info}{$path}{fpool} = $pool;
 	}
 	$self->{storage_baton}{$path} =
@@ -307,13 +307,24 @@
 	    $entry->{".${key}_rev"});
 }
 
+sub resolve_base {
+    my ($self, $path, $orig, $pool) = @_;
+    my ($basepath, $fromrev) = $self->_resolve_base($path, $orig);
+    if ($basepath) {
+	# if the inspector is involving copy base, we can't use
+	# $self->inspector, as it represent the current txn
+	return ($basepath, $fromrev, $self->static_inspector);
+    }
+
+    return ($path, undef, $self->inspector) 
+}
+
 sub open_file {
     my ($self, $path, $pdir, $rev, $pool) = @_;
     # modified but rm locally - tag for conflict?
-    my ($basepath, $fromrev) = $self->_resolve_base($path);
-    $basepath = $path unless defined $basepath;
-    if (defined $pdir && $self->inspector->exist($basepath, $pool) == $SVN::Node::file) {
-	$self->{info}{$path}{baseinfo} = [$basepath, $fromrev]
+    my ($basepath, $fromrev, $inspector) = $self->resolve_base($path);
+    if (defined $pdir && $inspector->exist($basepath, $pool) == $SVN::Node::file) {
+	$self->{info}{$path}{baseinfo} = [$basepath, $fromrev, $inspector]
 	    if defined $fromrev;
 	$self->{info}{$path}{open} = [$pdir, $rev];
 	$self->{info}{$path}{fpool} = $pool;
@@ -420,10 +431,10 @@
     return unless $path;
 
     my $info = $self->{info}{$path};
-    my ($basepath, $fromrev) = $info->{baseinfo} ? @{$info->{baseinfo}} : ($path);
+    my ($basepath, $fromrev, $inspector) = $info->{baseinfo} ? @{$info->{baseinfo}} : ($path, undef, $self->inspector);
     my $fh = $info->{fh} = {};
     my $pool = $info->{fpool};
-    if ($pool && ($fh->{local} = $self->inspector->localmod($basepath, $checksum || '', $pool))) {
+    if ($pool && ($fh->{local} = $inspector->localmod($basepath, $checksum || '', $pool))) {
 	# retrieve base
 	unless ($info->{addmerge}) {
 	    $fh->{base} = [$self->_retrieve_base($path, $pool)];
@@ -541,7 +552,7 @@
     my $fh = $info->{fh};
     my $iod;
 
-    my ($basepath, $fromrev) = $info->{baseinfo} ? @{$info->{baseinfo}} : ($path);
+    my ($basepath, $fromrev, $inspector) = $info->{baseinfo} ? @{$info->{baseinfo}} : ($path, undef, $self->inspector);
     no warnings 'uninitialized';
     my $storagebase_checksum = $fh->{local}[CHECKSUM];
     if ($fromrev) {
@@ -555,7 +566,7 @@
 	$self->_merge_file_unchanged ($path, $checksum, $pool), return
 	    if $checksum eq $storagebase_checksum;
 
-	my $eol = $self->inspector->localprop($basepath, 'svn:eol-style', $pool);
+	my $eol = $inspector->localprop($basepath, 'svn:eol-style', $pool);
 	my $eol_layer = SVK::XD::get_eol_layer({'svn:eol-style' => $eol}, '>');
 	$eol_layer = '' if $eol_layer eq ':raw';
 	$self->prepare_fh ($fh, $eol_layer);
@@ -589,7 +600,7 @@
 	    if ($basepath ne $path) {
 		$checksum = $self->{base_root}->fs->revision_root($fromrev, $pool)->file_md5_checksum($basepath, $pool);
 	    }
-	    elsif (my $local = $self->inspector->localmod($basepath, $checksum, $pool)) {
+	    elsif (my $local = $inspector->localmod($basepath, $checksum, $pool)) {
 		$checksum = $local->[CHECKSUM];
 		close $local->[FH];
 	    }
@@ -668,10 +679,9 @@
     unless ($self->{open_nonexist}) {
 	return undef unless defined $pdir;
 
-	my ($basepath, $fromrev) = $self->_resolve_base($path);
-	$basepath = $path unless defined $basepath;
+	my ($basepath, $fromrev, $inspector) = $self->resolve_base($path);
 
-	unless ($self->inspector->exist($basepath, $pool) || $self->{open_nonexist}) {
+	unless ($inspector->exist($basepath, $pool) || $self->{open_nonexist}) {
 	    ++$self->{skipped};
 	    $self->{notify}->flush ($path);
 	    return undef;
@@ -708,22 +718,21 @@
 sub _merge_file_delete {
     my ($self, $path, $rpath, $pdir, $pool) = @_;
 
-    my ($basepath, $fromrev) = $self->_resolve_base($path);
-    $basepath = $path unless defined $basepath;
+    my ($basepath, $fromrev, $inspector) = $self->resolve_base($path);
     
     my $no_base;
     my $md5 = $self->{base_root}->check_path ($rpath, $pool)?
         $self->{base_root}->file_md5_checksum ($rpath, $pool)
         : do { $no_base = 1; require Digest::MD5; Digest::MD5::md5_hex('') };
 
-    return undef unless $self->inspector->localmod ($basepath, $md5, $pool);
+    return undef unless $inspector->localmod ($basepath, $md5, $pool);
     return {} unless $self->{resolve};
 
     my $fh = $self->{info}{$path}->{fh} || {};
     $fh->{base} ||= [$no_base? (tmpfile('base-')): ($self->_retrieve_base($path, $pool))];
     $fh->{new} = [tmpfile('new-')];
     $fh->{local} = [tmpfile('local-')];
-    my ($tmp) = $self->inspector->localmod($basepath, '', $pool);
+    my ($tmp) = $inspector->localmod($basepath, '', $pool);
     slurp_fh ( $tmp->[FH], $fh->{local}[FH]);
     seek $fh->{local}[FH], 0, 0;
     $fh->{local}[CHECKSUM] = $tmp->[CHECKSUM];
@@ -888,10 +897,9 @@
     my ($self, $path, $revision, $pdir, $pool) = @_;
     no warnings 'uninitialized';
     $pool = SVN::Pool->new_default($pool);
-    my ($basepath, $fromrev) = $self->_resolve_base($path);
-    $basepath = $path unless defined $basepath;
+    my ($basepath, $fromrev, $inspector) = $self->resolve_base($path);
 
-    return unless defined $pdir && $self->inspector->exist($basepath);
+    return unless defined $pdir && $inspector->exist($basepath);
     my $rpath = $basepath =~ m{^/} ? $basepath :
 	$self->{base_anchor} eq '/' ? "/$basepath" : "$self->{base_anchor}/$basepath";
     my $torm;

Modified: trunk/lib/SVK/Merge.pm
==============================================================================
--- trunk/lib/SVK/Merge.pm	(original)
+++ trunk/lib/SVK/Merge.pm	Sat Dec 15 08:22:32 2007
@@ -543,6 +543,7 @@
     my $meditor = SVK::Editor::Merge->new
 	( anchor => $src->path_anchor,
 	  repospath => $src->repospath, # for stupid copyfrom url
+	  static_inspector => $self->{dst}->inspector,
 	  base_anchor => $base->path_anchor,
 	  base_root => $base_root,
 	  target => $target,

Modified: trunk/t/07smerge-copy.t
==============================================================================
--- trunk/t/07smerge-copy.t	(original)
+++ trunk/t/07smerge-copy.t	Sat Dec 15 08:22:32 2007
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-use Test::More tests => 25;
+use Test::More tests => 26;
 use strict;
 use File::Path;
 use Cwd;
@@ -215,6 +215,11 @@
 	   qr'New merge ticket: .*:/local-many:40',
 	   qr'New merge ticket: .*:/trunk:3',
 	   'Committed revision 41.']);
+is_output($svk, 'cat', ['//trunk-3/B/de'],
+	  ['modify on D/de',
+	   'modify on B/de',
+	   'file de added later',
+	   'modify this on trunk']);
 
 is_output($svk, 'diff', ['-sr40:41', '//'],
 	  ['M + trunk-3/B/de',

Modified: trunk/t/07smerge-cpreplace.t
==============================================================================
--- trunk/t/07smerge-cpreplace.t	(original)
+++ trunk/t/07smerge-cpreplace.t	Sat Dec 15 08:22:32 2007
@@ -17,28 +17,24 @@
 
 # r2 - remove file B
 
-$svk->rm(-m => 'r5 - remove file A/me', "//V/A/me");
+#$svk->rm(-m => 'r5 - remove file A/me', "//V/A/me");
 
 $svk->checkout('//V',$copath);
 # r3 - cp B at 1 to C with modification,
 $svk->cp('//V/A/me' => "$copath/Cme", -r => 4 );
 
-append_file("$copath/Cme", "mmmmmm\n");
+append_file("$copath/Cme", "mmmmmmxx\n");
 $svk->ci(-m => 'r8 - modify Cme', $copath);
-# cp A at 2 to B
-$svk->cp('//V/A/D/de' => "$copath/A/me", -r => 5);
+# cp A at 2 to B, if we comment these two out, 
+#$svk->cp('//V/A/D/de' => "$copath/A/me", -r => 5);
 append_file("$copath/A/me", "mmmmmm\n");
-
 $svk->ci(-m => 'some copy with mods', $copath);
 
-TODO: {
-    local $TODO = 'not yet';
 is_output($svk, 'smerge', [-m => 'go', '//V', '//X'],
-	  ['Auto-merging (3, 7) /V to /X (base /V:3).',
-	   'R + A/me',
-	   'R + Cme',
-	   qr'New merge ticket: .*:/V:7',
-	   'Committed revision 8']);
-}
+	  ['Auto-merging (3, 6) /V to /X (base /V:3).',
+	   'U   A/me',
+	   'A + Cme',
+	   qr'New merge ticket: .*:/V:6',
+	   'Committed revision 7.']);
 
 1;


More information about the svk-commit mailing list