+package Git::SVN::Ra;
+use vars qw/@ISA $config_dir/;
+use strict;
+use warnings;
+my ($can_do_switch);
+
+BEGIN {
+ # enforce temporary pool usage for some simple functions
+ my $e;
+ foreach (qw/get_latest_revnum rev_proplist get_file
+ check_path get_dir get_uuid get_repos_root/) {
+ $e .= "sub $_ {
+ my \$self = shift;
+ my \$pool = SVN::Pool->new;
+ my \@ret = \$self->SUPER::$_(\@_,\$pool);
+ \$pool->clear;
+ wantarray ? \@ret : \$ret[0]; }\n";
+ }
+ eval $e;
+}
+
+sub new {
+ my ($class, $url) = @_;
+ SVN::_Core::svn_config_ensure($config_dir, undef);
+ my ($baton, $callbacks) = SVN::Core::auth_open_helper([
+ SVN::Client::get_simple_provider(),
+ SVN::Client::get_ssl_server_trust_file_provider(),
+ SVN::Client::get_simple_prompt_provider(
+ \&Git::SVN::Prompt::simple, 2),
+ SVN::Client::get_ssl_client_cert_prompt_provider(
+ \&Git::SVN::Prompt::ssl_client_cert, 2),
+ SVN::Client::get_ssl_client_cert_pw_prompt_provider(
+ \&Git::SVN::Prompt::ssl_client_cert_pw, 2),
+ SVN::Client::get_username_provider(),
+ SVN::Client::get_ssl_server_trust_prompt_provider(
+ \&Git::SVN::Prompt::ssl_server_trust),
+ SVN::Client::get_username_prompt_provider(
+ \&Git::SVN::Prompt::username, 2),
+ ]);
+ my $config = SVN::Core::config_get_config($config_dir);
+ my $self = SVN::Ra->new(url => $url, auth => $baton,
+ config => $config,
+ pool => SVN::Pool->new,
+ auth_provider_callbacks => $callbacks);
+ $self->{svn_path} = $url;
+ $self->{repos_root} = $self->get_repos_root;
+ $self->{svn_path} =~ s#^\Q$self->{repos_root}\E/*##;
+ bless $self, $class;
+}
+
+sub DESTROY {
+ my $self = shift;
+ $self->{pool}->clear if $self->{pool};
+ $self->SUPER::DESTROY(@_);
+}
+
+sub dup {
+ my ($self) = @_;
+ my $dup = SVN::Ra->new(pool => SVN::Pool->new,
+ map { $_ => $self->{$_} } qw/config url
+ auth auth_provider_callbacks repos_root svn_path/);
+ bless $dup, ref $self;
+}
+
+sub get_log {
+ my ($self, @args) = @_;
+ my $pool = SVN::Pool->new;
+ $args[4]-- if $args[4] && ! $::_follow_parent;
+ splice(@args, 3, 1) if ($SVN::Core::VERSION le '1.2.0');
+ my $ret = $self->SUPER::get_log(@args, $pool);
+ $pool->clear;
+ $ret;
+}
+
+sub get_commit_editor {
+ my ($self, $msg, $cb, $pool) = @_;
+ my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef, 0) : ();
+ $self->SUPER::get_commit_editor($msg, $cb, @lock, $pool);
+}
+
+sub uuid {
+ my ($self) = @_;
+ $self->{uuid} ||= $self->get_uuid;
+}
+
+sub gs_do_update {
+ my ($self, $rev_a, $rev_b, $path, $recurse, $editor) = @_;
+ my $pool = SVN::Pool->new;
+ my $reporter = $self->do_update($rev_b, $path, $recurse,
+ $editor, $pool);
+ my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : ();
+ my $new = ($rev_a == $rev_b);
+ $reporter->set_path($path, $rev_a, $new, @lock, $pool);
+ $reporter->finish_report($pool);
+ $pool->clear;
+ $editor->{git_commit_ok};
+}
+
+sub gs_do_switch {
+ my ($self, $rev_a, $rev_b, $path, $recurse, $url_b, $editor) = @_;
+ my $pool = SVN::Pool->new;
+ my $reporter = $self->do_switch($rev_b, $path, $recurse,
+ $url_b, $editor, $pool);
+ my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : ();
+ $reporter->set_path($path, $rev_a, 0, @lock, $pool);
+ $reporter->finish_report($pool);
+ $pool->clear;
+ $editor->{git_commit_ok};
+}
+
+sub can_do_switch {
+ my $self = shift;
+ unless (defined $can_do_switch) {
+ my $pool = SVN::Pool->new;
+ my $rep = eval {
+ $self->do_switch(1, '', 0, $self->{url},
+ SVN::Delta::Editor->new, $pool);
+ };
+ if ($@) {
+ $can_do_switch = 0;
+ } else {
+ $rep->abort_report($pool);
+ $can_do_switch = 1;
+ }
+ $pool->clear;
+ }
+ $can_do_switch;
+}
+