[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Svncopy.pl problem pinning new externals formats

From: Darío B <darizotas_at_gmail.com>
Date: Tue, 5 Jun 2012 16:38:28 +0200

After all these months, I've been able to retake the activity with this
script and I have done several modifications that resolve the issues
related to the new format of the svn:externals property (further
information in the chapter "Externals Definitions" of the svn-book).

Environment:
Windows 2003 R2 (64bit)
SVN 1.6.17

I am going to explain every issue I have found and the modifications that I
have done to resolve them. At the end of this email you'll find the patch
file for svncopy.pl.in (svn 1.6.17).

Issues:
1. --file option. Svncopy.pl doesn't work properly with the --file. See the
main function and
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=462&dsMessageId=983363

2. New external format not supported. Svncopy.pl.in only supports the old
format, that is, absolute URLs. Relative URLs are not supported (see
function UpdateExternalsOnDir).

3. Problems retrieving the last revision from an external definition which
is defined as a relative URL. The function LatestRevision rises an error.

4. Windows doesn't work well with special characters such as: ^/. If you
try to execute 'svn log -q ^/your_external_url', it will result in an
error. The URL must be quoted.

Modifications:
1. Change at line 10. It reads the file given to use it as commentary.

2. Changes at lines 41-65. I have defined the regular expressions (for sure
they can be improved) to support relative URLs as well.

3. Changes at lines 25-27. If the external is defined using a relative
path, the command 'svn log -q EXTERNAL_RELATIVE_URL' requires that the
current working directory must be a working copy. In other case, it's
unable to connect to the proper repository (a non-versioned directory has
no svn information).

4. Change at line 92. Quotes the external URL.

After these explanations, you can find the patch file pasted below (or
enclosed to this message). I hope anybody can test it so that I can submit
a bug.

--- svncopy.modified.pl.in 2012-06-05 11:47:56.000000000 +-0200
+++ svncopy.pl.in 2012-03-05 13:19:46.000000000 +-0200
@@ -89,13 +89,13 @@
 GetOptions( "pin-externals|tag|t" => \$pin_externals,
             "update-externals|branch|b" => \$update_externals,
             "message|m=s" => \$message,
             "revision|r=s" => \$revision,
             "verbose!" => \$verbose,
             "quiet|q" => sub { $verbose = 0; push( @svn_options, "--quiet"
) },
- "file|F=s" => sub { open FILE, $_[1]; my @content = <FILE>;
$message = join("\n", @content, "\n"); close FILE; },
+ "file|F=s" => sub { push( @svn_options, "--file", $_[1] ) },
             "username=s" => sub { push( @svn_options, "--username", $_[1]
) },
             "password=s" => sub { push( @svn_options, "--password", $_[1]
) },
             "no_auth_cache" => sub { push( @svn_options, "--no-auth-cache"
) },
             "force-log" => sub { push( @svn_options, "--force-log" ) },
             "encoding=s" => sub { push( @svn_options, "--encoding", $_[1]
) },
             "config-dir=s" => sub { push( @svn_options, "--config-dir",
$_[1] ) },
@@ -397,15 +397,12 @@
   my ( $sourceref, $destination, $work_dir, $msgref ) = @_;
   my @commandline = ();
   my $msg;
   my @dirfiles;
   my %extlist;

- # Changes to the working directory in order to avoid errors trying to
retrieve the last
- # revision from a relative URL. This directory change does not affect to
absolute URLs.
- chdir( $work_dir );
   # Check the externals on this directory and subdirectories
   info( "Checking '$work_dir'\n" );
   %extlist = GetRecursiveExternals( $work_dir );

   # And do the update
   while ( my ( $subdir, $exts ) = each ( %extlist ) )
@@ -445,37 +442,14 @@
   my %changed;

   # Do any updating required
   foreach my $external ( @externals )
     {
       chomp( $external );
- # -rREV EXTERNAL
- $rev_pattern = '(?:-r\s*(\d+)\s+)?((?:\w+:|\^|\.{2})?/[/\-\.\w]+)';
- # EXTERNAL_at_REV
- $peg_pattern = '((?:\w+:|\^|\.{2})?/[/\-\.\w]+)(?:@(\d+))?';
- my ( $ext_dir, $spacing, $ext_rev, $ext_val );
-
- # New format: -rREV EXTERNAL DIR
- if ( $external =~ m"^$rev_pattern(\s+)(.*)" )
- {
- ( $ext_dir, $spacing, $ext_rev, $ext_val ) = ( $4, $3, $1, $2 );
- }
- # New format: EXTERNAL_at_REV DIR
- elsif ( $external =~ m"^$peg_pattern(\s+)(.*)" )
- {
- ( $ext_dir, $spacing, $ext_rev, $ext_val ) = ( $4, $3, $2, $1 );
- }
- # Old externals format
- elsif ( $external =~ m"^(\S+)(\s+)(?:-r\s*(\d+)\s+)?(.*)" )
- {
- ( $ext_dir, $spacing, $ext_rev, $ext_val ) = ( $1, $2, $3, $4 );
- }
- else
- {
- next;
- }
+ next unless ( $external =~ m"^(\S+)(\s+)(?:-r\s*(\d+)\s+)?(.*)" );
+ my ( $ext_dir, $spacing, $ext_rev, $ext_val ) = ( $1, $2, $3, $4 );

       info( " - Found $ext_dir => '$ext_val'" );
       info( " ($ext_rev)" ) if $ext_rev;
       info( "\n" );

       $externals_hash{ "$ext_val" } = $ext_rev;
@@ -489,25 +463,25 @@
               foreach my $source ( @sources )
                 {
                   my $dest_dir = DestinationSubdir( $source, $destination
);
                   #info( "Checking against '$source'\n" );
                   if ( $ext_val =~ s|^$source|$dest_dir| )
                     {
- $external = "$ext_val$spacing$ext_dir";
+ $external = "$ext_dir$spacing$ext_val";
                       info( " - updated '$old_external' to '$external'\n"
);
                       $changed{$old_external} = $external;
                     }
                 }
             }
           elsif ( $pin_externals )
             {
               # Find the last revision of the destination and pin to that.
               my $old_external = $external;
- my $rev = LatestRevision( '"'.$ext_val.'"', $revision );
+ my $rev = LatestRevision( $ext_val, $revision );
               #info( "Pinning '$ext_val' to '$rev'\n" );
- $external = "$ext_val\@$rev$spacing$ext_dir";
+ $external = "$ext_dir -r $rev$spacing$ext_val";
               info( " - updated '$old_external' to '$external'\n" );
               $changed{$old_external} = $external;
             }
         }
       push( @new_externals, $external );
     }

2012/3/28 Darío B <darizotas_at_gmail.com>

> First of all, sorry for re-sending the email (I pressed the button that I
> shouldn't) and for this quite long email.
>
> Reading the svn-book you can see that SVN 1.6 and newer versions support a
> new format of the svn:externals property. That format also supports
> relative URLs (for further information, please read "Externals Definitions"
> chapter of the svn-book). Let's go straight to the point. We can define the
> svn:externals as follows:
>
> New formats:
> URL[@REV] subdir
> [-rREV] URL subdir
>
> Old format:
> subdir [-rREV] URL
>
> Example:
> ^/tools/trunk tools
>
> As you can see, the URL stars with ^/, which means: "Relative to the root
> repository in which the svn:externals property is versioned."
>
> Said that, I could check the code for svncopy.pl only supports the old
> format so I modified the code as follows (please, *don't pay attention to
> the modification of the --file option* that is not related with this
> issue. For more information about that check
> http://subversion.tigris.org/issues/show_bug.cgi?id=4151):
>
> --- svncopy.pl.in 2011-11-06 11:40:42.000000000 +-0200
> +++ svncopy.modified.pl.in 2012-03-27 16:38:01.000000000 +-0200
> @@ -89,13 +89,13 @@
> GetOptions( "pin-externals|tag|t" => \$pin_externals,
> "update-externals|branch|b" => \$update_externals,
> "message|m=s" => \$message,
> "revision|r=s" => \$revision,
> "verbose!" => \$verbose,
> "quiet|q" => sub { $verbose = 0; push( @svn_options,
> "--quiet" ) },
> - "file|F=s" => sub { push( @svn_options, "--file", $_[1] ) },
> + "file|F=s" => sub { open FILE, $_[1]; my @content = <FILE>;
> $message = join("\n", @content, "\n"); close FILE; },
> "username=s" => sub { push( @svn_options, "--username", $_[1]
> ) },
> "password=s" => sub { push( @svn_options, "--password", $_[1]
> ) },
> "no_auth_cache" => sub { push( @svn_options,
> "--no-auth-cache" ) },
> "force-log" => sub { push( @svn_options, "--force-log" ) },
> "encoding=s" => sub { push( @svn_options, "--encoding", $_[1]
> ) },
> "config-dir=s" => sub { push( @svn_options, "--config-dir",
> $_[1] ) },
> @@ -442,14 +442,37 @@
> my %changed;
>
> # Do any updating required
> foreach my $external ( @externals )
> {
> chomp( $external );
> - next unless ( $external =~ m"^(\S+)(\s+)(?:-r\s*(\d+)\s+)?(.*)" );
> - my ( $ext_dir, $spacing, $ext_rev, $ext_val ) = ( $1, $2, $3, $4 );
> + # -rREV EXTERNAL
> + $rev_pattern = '(?:-r\s*(\d+)\s+)?((?:\w+:|\^|\.{2})?/[/\-\.\w]+)';
> + # EXTERNAL_at_REV
> + $peg_pattern = '((?:\w+:|\^|\.{2})?/[/\-\.\w]+)(?:@(\d+))?';
> + my ( $ext_dir, $spacing, $ext_rev, $ext_val );
> +
> + # New format: -rREV EXTERNAL DIR
> + if ( $external =~ m"^$rev_pattern(\s+)(.*)" )
> + {
> + ( $ext_dir, $spacing, $ext_rev, $ext_val ) = ( $4, $3, $1, $2 );
> + }
> + # New format: EXTERNAL_at_REV DIR
> + elsif ( $external =~ m"^$peg_pattern(\s+)(.*)" )
> + {
> + ( $ext_dir, $spacing, $ext_rev, $ext_val ) = ( $4, $3, $2, $1 );
> + }
> + # Old externals format
> + elsif ( $external =~ m"^(\S+)(\s+)(?:-r\s*(\d+)\s+)?(.*)" )
> + {
> + ( $ext_dir, $spacing, $ext_rev, $ext_val ) = ( $1, $2, $3, $4 );
> + }
> + else
> + {
> + next;
> + }
>
> info( " - Found $ext_dir => '$ext_val'" );
> info( " ($ext_rev)" ) if $ext_rev;
> info( "\n" );
>
> $externals_hash{ "$ext_val" } = $ext_rev;
> @@ -463,25 +486,25 @@
> foreach my $source ( @sources )
> {
> my $dest_dir = DestinationSubdir( $source, $destination
> );
> #info( "Checking against '$source'\n" );
> if ( $ext_val =~ s|^$source|$dest_dir| )
> {
> - $external = "$ext_dir$spacing$ext_val";
> + $external = "$ext_val$spacing$ext_dir";
> info( " - updated '$old_external' to '$external'\n"
> );
> $changed{$old_external} = $external;
> }
> }
> }
> elsif ( $pin_externals )
> {
> # Find the last revision of the destination and pin to that.
> my $old_external = $external;
> my $rev = LatestRevision( $ext_val, $revision );
> #info( "Pinning '$ext_val' to '$rev'\n" );
> - $external = "$ext_dir -r $rev$spacing$ext_val";
> + $external = "$ext_val@$rev$spacing$ext_dir";
> info( " - updated '$old_external' to '$external'\n" );
> $changed{$old_external} = $external;
> }
> }
> push( @new_externals, $external );
> }
>
> Done this modification, svncopy.pl is able to parse the new format, but
> when it triea to retrieve the last revision to pin/tag the svn:externals
> property it gets the following error:
> output:
> =================================================================
> === Copying from:
> === @SVN_REPOS_URL@/project/trunk
> ===
> === Copying to:
> === @SVN_REPOS_URL@/project/tags/1.2
> ===
> === - tagging (pinning all svn:externals definitions to current revision)
> ===
> Using temporary directory @WINDOWS_PATH_WITHOUT_SPACES@\svncopy_s9f2iCF4XC
> Creating intermediate directories (if necessary)
> > @SVN_BINDIR@\svn.exe mkdir --username dborrin --password 47019559
> --file @WINDOWS_PATH_WITHOUT_SPACES@\svncopy_s9f2iCF4XC\4PcZt8u3s4
> @SVN_REPOS_URL@/project/tags/1.2
>
> Checking out destination directory '@SVN_REPOS_URL@/1.2'
> > @SVN_BINDIR@\svn.exe co --username dborrin --password 47019559
> @SVN_REPOS_URL@/project/tags/1.2 @WINDOWS_PATH_WITHOUT_SPACES@
> \svncopy_s9f2iCF4XC/1.2
> > @SVN_BINDIR@\svn.exe copy --username dborrin --password 47019559
> @SVN_REPOS_URL@/project/trunk @WINDOWS_PATH_WITHOUT_SPACES@
> \svncopy_s9f2iCF4XC/1.2
>
> Checking '@WINDOWS_PATH_WITHOUT_SPACES@\svncopy_s9f2iCF4XC/1.2'
> > @SVN_BINDIR@\svn.exe propget --username dborrin --password 4701955
> 9 -R svn:externals @WINDOWS_PATH_WITHOUT_SPACES@\svncopy_s9f2iCF4XC/1.2
> - Found tools => '^/tools/dev/trunk'
> svncopy.pl: LatestRevision: log -q on '^/tools/dev/trunk' failed
> - updated '^/tools/dev/trunk tools' to '^/tools/dev/trunk tools'
> '^/tools/dev/trunk tools' => '^/tools/dev/trunk tools'
> > @SVN_BINDIR@\svn.exe propset --username dborrin --password 4701955
> 9 --file @WINDOWS_PATH_WITHOUT_SPACES@\svncopy_s9f2iCF4XC\hCruix1TvX
> svn:externals
> @WINDOWS_PATH_WITHOUT_SPACES@\svncopy_s9f2iCF4XC\1.2\prueba\www
> > @SVN_BINDIR@\svn.exe commit --username dborrin --password 47019559
> --file @WINDOWS_PATH_WITHOUT_SPACES@\svncopy_s9f2iCF4XC\0LOmYKSwY4
> @WINDOWS_PATH_WITHOUT_SPACES@\svncopy_s9f2iCF4XC/1.2
> === ... copy complete
> =================================================================
> Leaving @WINDOWS_PATH_WITHOUT_SPACES@\svncopy_s9f2iCF4XC for inspection
>
> *****************************************************************
> Errors:
> svncopy.pl: LatestRevision: log -q on '^/tools/dev/trunk' failed
>
> input:
> svn:externals = ^/tools/trunk tools
>
> I hope this clarifies the situation. I attach again the modified file and
> the patch as well.
>
>
> Darío.
>
>
> 2012/3/27 Julian Foad <julianfoad_at_btopenworld.com>
>
>> darizotas_at_gmail.com wrote on Thursday, 22 March 2012:
>>
>> > I am migrating my repos to svn 1.6.17 and i'd like to change the format
>> of
>> > the property svn:externals to the new ones supported from 1.6 version.
>> >
>> > The problem is that if I change the externals to the new supported
>> formats,
>> > svncopy.pl stops working. I have seen that this script only works with
>> the old
>> > format, therefore I modified the method UpdateExternalsOnDir (see the
>> attached
>> > file, svncopy.modified.pl.in). But after doing that, svncopy is not
>> able to get
>> > the latest revision. E.g. svn:externals = ^/tools/calc/trunk calc.
>> >
>> > Can anybody help me?
>>
>> Please explain the problem in more detail. It's easier for us to see
>> what you changed in svncopy if you show us a diff. What do you mean by
>> "svncopy is not able to get the latest revision"? What is the input and
>> the output?
>>
>> - Julian
>>
>
>

Received on 2012-06-05 16:39:07 CEST

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.