Anthony Foglia wrote:
I have found a bug in the svncopy.pl script that fails to properly
handle fully-contained externals when branching and copying from a
single source. When branching from a single source, the externals are
updated to directories that do not exist.
I've figured out where the problem is and have attached a patch
(single_source_and_branching.patch) that correctly rewrites the
externals when branching using Bradey Honsinger's patch.
There is still another bug with his patch that is probably too
complicated for my perl skills. When you use svncopy.pl to copy from a
single source to a destination folder that already exists, like "svn
copy" it makes a subdirectory named with the last component of the
source directory. But when it tries to fix the externals, it checks out
the destination directory (as passed on the command-line), and any of
its siblings, and tries to change the externals in those directories.
So, if you have a repository of the form
repos/
branches/
release_2.0/
tags/
release_1.0/
And you do
$ svncopy.pl --tag repos/branches/release_2.0 repos/tags
The script will make repos/tags/release_2.0, but checkout repos/tags and
try to change all the externals in there, including those in release_1.0.
The workaround is to make sure the source is always a non-existent
directory, and let the script create it. So the above command should be.
$ svncopy.pl --tag repos/branches/release_2.0 repos/tags/release_2.0
--
Anthony Foglia
Princeton Consultants
(609) 987-8787 x233
diff --git a/svncopy.README b/svncopy.README
index f85c784..215545b 100644
--- a/svncopy.README
+++ b/svncopy.README
@@ -237,13 +237,13 @@ branches/
foo1.c
foo2.c
X common -r 4997 http://svn/repos/trunk/common
- X inc http://svn/repos/branches/3.2_bugfix/trunk/inc
+ X inc http://svn/repos/branches/3.2_bugfix/inc
proj_bar/
bar1.c
bar2.c
bar2.h
- X common http://svn/repos/branches/3.2_bugfix/trunk/common
- X inc http://svn/repos/branches/3.2_bugfix/trunk/inc
+ X common http://svn/repos/branches/3.2_bugfix/common
+ X inc http://svn/repos/branches/3.2_bugfix/inc
X public http://someserver/repos/public
The svn:externals are now pointing to the corresponding directories in the
diff --git a/svncopy.pl.in b/svncopy.pl.in
index 4a6ddb8..c03cac2 100644
--- a/svncopy.pl.in
+++ b/svncopy.pl.in
@@ -527,6 +527,8 @@ sub UpdateExternalsOnDir
my @new_externals;
my %changed;
+ $multiple_sources = scalar( @sources ) > 1;
+
# Do any updating required
foreach my $external ( @externals )
{
@@ -548,7 +550,15 @@ sub UpdateExternalsOnDir
my $old_external = $external;
foreach my $source ( @sources )
{
- my $dest_dir = DestinationSubdir( $source, $destination );
+ my $dest_dir;
+ if ( $multiple_sources )
+ {
+ $dest_dir = DestinationSubdir( $source, $destination );
+ }
+ else
+ {
+ $dest_dir = $destination;
+ }
#info( "Checking against '$source'\n" );
if ( $ext_val =~ s|^$source|$dest_dir| )
{
diff --git a/testsvncopy.pl.in b/testsvncopy.pl.in
index 59057c2..9125ac3 100644
--- a/testsvncopy.pl.in
+++ b/testsvncopy.pl.in
@@ -190,7 +190,7 @@ sub testUpdateExternals
update => 1,
ext_dir => "dir1",
expected_externals => [
- "DIR2 $testURL/dest/dirA/dir2",
+ "DIR2 $testURL/dest/dir2",
"DIR2Pin -r __PINREV__ $testURL/source/dirA/dir2",
"DIR3 $testURL/source/dirB/dir3",
"DIR4 $testURL/wibble/dirA/dir2"