Fourth batch
[gitweb.git] / perl / Git / SVN / Ra.pm
index 5bc5b4e594e350fe302a2b58fc1c4b6d3be84a77..56ad9870bcfdfae68bd0fb5b57aa73e208bcb0fd 100644 (file)
@@ -2,7 +2,7 @@ package Git::SVN::Ra;
 use vars qw/@ISA $config_dir $_ignore_refs_regex $_log_window_size/;
 use strict;
 use warnings;
-use SVN::Client;
+use Memoize;
 use Git::SVN::Utils qw(
        canonicalize_url
        canonicalize_path
@@ -41,6 +41,7 @@ END
 }
 
 sub _auth_providers () {
+       require SVN::Client;
        my @rv = (
          SVN::Client::get_simple_provider(),
          SVN::Client::get_ssl_server_trust_file_provider(),
@@ -76,6 +77,44 @@ ()
        \@rv;
 }
 
+sub prepare_config_once {
+       SVN::_Core::svn_config_ensure($config_dir, undef);
+       my ($baton, $callbacks) = SVN::Core::auth_open_helper(_auth_providers);
+       my $config = SVN::Core::config_get_config($config_dir);
+       my $conf_t = $config->{'config'};
+
+       no warnings 'once';
+       # The usage of $SVN::_Core::SVN_CONFIG_* variables
+       # produces warnings that variables are used only once.
+       # I had not found the better way to shut them up, so
+       # the warnings of type 'once' are disabled in this block.
+       if (SVN::_Core::svn_config_get_bool($conf_t,
+           $SVN::_Core::SVN_CONFIG_SECTION_AUTH,
+           $SVN::_Core::SVN_CONFIG_OPTION_STORE_PASSWORDS,
+           1) == 0) {
+               my $val = '1';
+               if (::compare_svn_version('1.9.0') < 0) { # pre-SVN r1553823
+                       my $dont_store_passwords = 1;
+                       $val = bless \$dont_store_passwords, "_p_void";
+               }
+               SVN::_Core::svn_auth_set_parameter($baton,
+                   $SVN::_Core::SVN_AUTH_PARAM_DONT_STORE_PASSWORDS,
+                   $val);
+       }
+       if (SVN::_Core::svn_config_get_bool($conf_t,
+           $SVN::_Core::SVN_CONFIG_SECTION_AUTH,
+           $SVN::_Core::SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
+           1) == 0) {
+               $Git::SVN::Prompt::_no_auth_cache = 1;
+       }
+
+       return ($config, $baton, $callbacks);
+} # no warnings 'once'
+
+INIT {
+       Memoize::memoize '_auth_providers';
+       Memoize::memoize 'prepare_config_once';
+}
 
 sub new {
        my ($class, $url) = @_;
@@ -84,34 +123,8 @@ sub new {
 
        ::_req_svn();
 
-       SVN::_Core::svn_config_ensure($config_dir, undef);
-       my ($baton, $callbacks) = SVN::Core::auth_open_helper(_auth_providers);
-       my $config = SVN::Core::config_get_config($config_dir);
        $RA = undef;
-       my $dont_store_passwords = 1;
-       my $conf_t = ${$config}{'config'};
-       {
-               no warnings 'once';
-               # The usage of $SVN::_Core::SVN_CONFIG_* variables
-               # produces warnings that variables are used only once.
-               # I had not found the better way to shut them up, so
-               # the warnings of type 'once' are disabled in this block.
-               if (SVN::_Core::svn_config_get_bool($conf_t,
-                   $SVN::_Core::SVN_CONFIG_SECTION_AUTH,
-                   $SVN::_Core::SVN_CONFIG_OPTION_STORE_PASSWORDS,
-                   1) == 0) {
-                       SVN::_Core::svn_auth_set_parameter($baton,
-                           $SVN::_Core::SVN_AUTH_PARAM_DONT_STORE_PASSWORDS,
-                           bless (\$dont_store_passwords, "_p_void"));
-               }
-               if (SVN::_Core::svn_config_get_bool($conf_t,
-                   $SVN::_Core::SVN_CONFIG_SECTION_AUTH,
-                   $SVN::_Core::SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
-                   1) == 0) {
-                       $Git::SVN::Prompt::_no_auth_cache = 1;
-               }
-       } # no warnings 'once'
-
+       my ($config, $baton, $callbacks) = prepare_config_once();
        my $self = SVN::Ra->new(url => $url, auth => $baton,
                              config => $config,
                              pool => SVN::Pool->new,
@@ -166,7 +179,17 @@ sub get_dir {
                }
        }
        my $pool = SVN::Pool->new;
-       my ($d, undef, $props) = $self->SUPER::get_dir($dir, $r, $pool);
+       my ($d, undef, $props);
+
+       if (::compare_svn_version('1.4.0') >= 0) {
+               # n.b. in addition to being potentially more efficient,
+               # this works around what appears to be a bug in some
+               # SVN 1.8 versions
+               my $kind = 1; # SVN_DIRENT_KIND
+               ($d, undef, $props) = $self->get_dir2($dir, $r, $kind, $pool);
+       } else {
+               ($d, undef, $props) = $self->SUPER::get_dir($dir, $r, $pool);
+       }
        my %dirents = map { $_ => { kind => $d->{$_}->kind } } keys %$d;
        $pool->clear;
        if ($r != $cache->{r}) {
@@ -228,7 +251,10 @@ sub get_log {
        $ret;
 }
 
+# uncommon, only for ancient SVN (<= 1.4.2)
 sub trees_match {
+       require IO::File;
+       require SVN::Client;
        my ($self, $url1, $rev1, $url2, $rev2) = @_;
        my $ctx = SVN::Client->new(auth => _auth_providers);
        my $out = IO::File->new_tmpfile;
@@ -372,6 +398,9 @@ sub longest_common_path {
 sub gs_fetch_loop_common {
        my ($self, $base, $head, $gsv, $globs) = @_;
        return if ($base > $head);
+       # Make sure the cat_blob open2 FileHandle is created before calling
+       # SVN::Pool::new_default so that it does not incorrectly end up in the pool.
+       $::_repository->_open_cat_blob_if_needed;
        my $gpool = SVN::Pool->new_default;
        my $ra_url = $self->url;
        my $reload_ra = sub {
@@ -577,7 +606,7 @@ sub minimize_url {
                        my $latest = $ra->get_latest_revnum;
                        $ra->get_log("", $latest, 0, 1, 0, 1, sub {});
                };
-       } while ($@ && ($c = shift @components));
+       } while ($@ && defined($c = shift @components));
 
        return canonicalize_url($url);
 }