summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4a87db0)
raw | patch | inline | side by side (parent: 4a87db0)
author | Eric Wong <normalperson@yhbt.net> | |
Wed, 10 Jan 2007 09:22:38 +0000 (01:22 -0800) | ||
committer | Eric Wong <normalperson@yhbt.net> | |
Fri, 23 Feb 2007 08:57:08 +0000 (00:57 -0800) |
Force some svn_ra functions to use a temporary pool via wrapper
This cleans up the code a bit by removing explicit instances of
pool allocation and deallocation and providing wrapper functions
that make use of temporary pools.
I've also added an explicit pool usage when creating the commit
editor for commit-diff where get_commit_editor can be called
multiple times with the same pool previously.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
This cleans up the code a bit by removing explicit instances of
pool allocation and deallocation and providing wrapper functions
that make use of temporary pools.
I've also added an explicit pool usage when creating the commit
editor for commit-diff where get_commit_editor can be called
multiple times with the same pool previously.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
git-svn.perl | patch | blob | history |
diff --git a/git-svn.perl b/git-svn.perl
index fcef05c2eec30a116cb7d7a44d3d5ebf087759a2..5a3a8777097e135ab072000df4d2b844fd913c5b 100755 (executable)
--- a/git-svn.perl
+++ b/git-svn.perl
use warnings;
use strict;
use vars qw/ $AUTHOR $VERSION
- $SVN_URL $SVN_INFO $SVN_WC $SVN_UUID
+ $SVN_URL
$GIT_SVN_INDEX $GIT_SVN
$GIT_DIR $GIT_SVN_DIR $REVDB/;
$AUTHOR = 'Eric Wong <normalperson@yhbt.net>';
if ($SVN::Core::VERSION lt '1.1.0') {
fatal "Need SVN::Core 1.1.0 or better (got $SVN::Core::VERSION)\n";
}
+push @Git::SVN::Ra::ISA, 'SVN::Ra';
push @SVN::Git::Editor::ISA, 'SVN::Delta::Editor';
push @SVN::Git::Fetcher::ISA, 'SVN::Delta::Editor';
use Carp qw/croak/;
my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,
$_find_copies_harder, $_l, $_cp_similarity, $_cp_remote,
$_repack, $_repack_nr, $_repack_flags, $_q,
- $_message, $_file, $_follow_parent, $_no_metadata,
+ $_message, $_file, $_no_metadata,
$_template, $_shared, $_no_default_regex, $_no_graft_copy,
$_limit, $_verbose, $_incremental, $_oneline, $_l_fmt, $_show_commit,
$_version, $_upgrade, $_authors, $_branch_all_refs, @_opt_m,
$_merge, $_strategy, $_dry_run, $_ignore_nodate, $_non_recursive,
- $_config_dir,
$_pager, $_color, $_prefix);
my (@_branch_from, %tree_map, %users, %rusers, %equiv);
my ($_svn_can_do_switch);
my @repo_path_split_cache;
+use vars qw/$_follow_parent/;
my %fc_opts = ( 'no-ignore-externals' => \$_no_ignore_ext,
'branch|b=s' => \@_branch_from,
'no-metadata' => \$_no_metadata,
'quiet|q' => \$_q,
'username=s' => \$Git::SVN::Prompt::_username,
- 'config-dir=s' => \$_config_dir,
+ 'config-dir=s' => \$Git::SVN::Ra::config_dir,
'no-auth-cache' => \$Git::SVN::Prompt::_no_auth_cache,
'ignore-nodate' => \$_ignore_nodate,
'repack-flags|repack-args|repack-opts=s' => \$_repack_flags);
{ %multi_opts, %init_opts,
'revision|r=i' => \$_revision,
'username=s' => \$Git::SVN::Prompt::_username,
- 'config-dir=s' => \$_config_dir,
+ 'config-dir=s' => \$Git::SVN::Ra::config_dir,
'no-auth-cache' => \$Git::SVN::Prompt::_no_auth_cache,
'prefix=s' => \$_prefix,
} ],
my ($rev_list, $ctx) = command_output_pipe("rev-list",
"refs/remotes/$GIT_SVN");
my $latest;
+ my $svn_uuid;
while (<$rev_list>) {
chomp;
my $c = $_;
# if we merged or otherwise started elsewhere, this is
# how we break out of it
- next if (defined $SVN_UUID && ($uuid ne $SVN_UUID));
+ next if (defined $svn_uuid && ($uuid ne $svn_uuid));
next if (defined $SVN_URL && defined $url && ($url ne $SVN_URL));
unless (defined $latest) {
croak "SVN repository location required: $url\n";
}
$SVN_URL ||= $url;
- $SVN_UUID ||= $uuid;
+ $svn_uuid ||= $uuid;
setup_git_svn();
$latest = $rev;
}
sub fetch_lib {
my (@parents) = @_;
$SVN_URL ||= file_to_s("$GIT_SVN_DIR/info/url");
- $SVN ||= libsvn_connect($SVN_URL);
+ $SVN ||= Git::SVN::Ra->new($SVN_URL);
my ($last_rev, $last_commit) = svn_grab_base_rev();
my ($base, $head) = libsvn_parse_revision($last_rev);
if ($base > $head) {
# after processing a revision and SVN stuff seems to leak
my $inc = 1000;
my ($min, $max) = ($base, $head < $base+$inc ? $head : $base+$inc);
- read_uuid();
if (defined $last_commit) {
unless (-e $GIT_SVN_INDEX) {
command_noisy('read-tree', $last_commit);
# performance sucks with it enabled, so it's much
# faster to fetch revision ranges instead of relying
# on the limiter.
- libsvn_get_log(libsvn_dup_ra($SVN), [''],
- $min, $max, 0, 1, 1,
+ $SVN->dup->get_log([''], $min, $max, 0, 1, 1,
sub {
my $log_msg;
if ($last_commit) {
$min = $max + 1;
$max += $inc;
$max = $head if ($max > $head);
- $SVN = libsvn_connect($SVN_URL);
+ $SVN = Git::SVN::Ra->new($SVN_URL);
}
restore_index($index);
return { revision => $last_rev, commit => $last_commit };
" current: $fetched->{revision}\n";
exit 1;
}
- read_uuid();
- my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef, 0) : ();
my $commit_msg = "$GIT_SVN_DIR/.svn-commit.tmp.$$";
my $repo;
# can't track down... (it's probably in the SVN code)
defined(my $pid = open my $fh, '-|') or croak $!;
if (!$pid) {
+ my $pool = SVN::Pool->new;
my $ed = SVN::Git::Editor->new(
{ r => $r_last,
- ra => libsvn_dup_ra($SVN),
+ ra => $SVN->dup,
c => $c,
svn_path => $SVN->{svn_path},
},
$log_msg->{msg},
$r_last,
$cmt_last)
- },
- @lock)
+ }, $pool)
);
my $mods = libsvn_checkout_tree($cmt_last, $c, $ed);
if (@$mods == 0) {
} else {
$ed->close_edit;
}
+ $pool->clear;
exit 0;
}
my ($r_new, $cmt_new, $no);
sub show_ignore {
$SVN_URL ||= file_to_s("$GIT_SVN_DIR/info/url");
my $repo;
- $SVN ||= libsvn_connect($SVN_URL);
+ $SVN ||= Git::SVN::Ra->new($SVN_URL);
my $r = defined $_revision ? $_revision : $SVN->get_latest_revnum;
libsvn_traverse_ignore(\*STDOUT, '', $r);
}
$_message ||= get_commit_message($tb,
"$GIT_DIR/.svn-commit.tmp.$$")->{msg};
}
- $SVN ||= libsvn_connect($SVN_URL);
+ $SVN ||= Git::SVN::Ra->new($SVN_URL);
if ($r eq 'HEAD') {
$r = $SVN->get_latest_revnum;
} elsif ($r !~ /^\d+$/) {
die "revision argument: $r not understood by git-svn\n";
}
- my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef, 0) : ();
my $rev_committed;
+ my $pool = SVN::Pool->new;
my $ed = SVN::Git::Editor->new({ r => $r,
- ra => libsvn_dup_ra($SVN),
+ ra => $SVN->dup,
c => $tb,
svn_path => $SVN->{svn_path}
},
sub {
$rev_committed = $_[0];
print "Committed $_[0]\n";
- }, @lock)
+ },
+ $pool)
);
eval {
my $mods = libsvn_checkout_tree($ta, $tb, $ed);
$ed->close_edit;
}
};
+ $pool->clear;
fatal "$@\n" if $@;
$_message = $_file = undef;
return $rev_committed;
my $tree_paths = $l_map->{$u};
my $pfx = common_prefix([keys %$tree_paths]);
my ($repo, $path) = repo_path_split($u.$pfx);
- $SVN = libsvn_connect($repo);
+ $SVN = Git::SVN::Ra->new($repo);
my ($base, $head) = libsvn_parse_revision();
my $inc = 1000;
my $eh = $SVN::Error::handler;
$SVN::Error::handler = \&libsvn_skip_unknown_revs;
while (1) {
- my $pool = SVN::Pool->new;
- libsvn_get_log(libsvn_dup_ra($SVN), [$path],
- $min, $max, 0, 2, 1,
+ $SVN->dup->get_log([$path], $min, $max, 0, 2, 1,
sub {
libsvn_graft_file_copies($grafts, $tree_paths,
$path, @_);
- }, $pool);
- $pool->clear;
+ });
last if ($max >= $head);
$min = $max + 1;
$max += $inc;
}
}
-sub read_uuid {
- return if $SVN_UUID;
- my $pool = SVN::Pool->new;
- $SVN_UUID = $SVN->get_uuid($pool);
- $pool->clear;
-}
-
sub verify_ref {
my ($ref) = @_;
eval { command_oneline([ 'rev-parse', '--verify', $ref ],
return ($u, $full_url);
}
}
- my $tmp = libsvn_connect($full_url);
+ my $tmp = Git::SVN::Ra->new($full_url);
return ($tmp->{repos_root}, $tmp->{svn_path});
}
}
next if $skip;
my ($url_p, $r_p, $uuid_p) = cmt_metadata($p);
- next if (($SVN_UUID eq $uuid_p) &&
+ next if (($SVN->uuid eq $uuid_p) &&
($log_msg->{revision} > $r_p));
next if (defined $url_p && defined $SVN_URL &&
- ($SVN_UUID eq $uuid_p) &&
+ ($SVN->uuid eq $uuid_p) &&
($url_p eq $SVN_URL));
push @tmp_parents, $p;
}
or croak $!;
print $msg_fh $log_msg->{msg} or croak $!;
unless ($_no_metadata) {
- print $msg_fh "\ngit-svn-id: $SVN_URL\@$log_msg->{revision}",
- " $SVN_UUID\n" or croak $!;
+ print $msg_fh "\ngit-svn-id: $SVN_URL\@$log_msg->{revision} ",
+ $SVN->uuid,"\n" or croak $!;
}
$msg_fh->flush == 0 or croak $!;
close $msg_fh or croak $!;
$author = '(no author)';
}
my ($name,$email) = defined $users{$author} ? @{$users{$author}}
- : ($author,"$author\@$SVN_UUID");
+ : ($author,$author . '@' . $SVN->uuid);
$ENV{GIT_AUTHOR_NAME} = $ENV{GIT_COMMITTER_NAME} = $name;
$ENV{GIT_AUTHOR_EMAIL} = $ENV{GIT_COMMITTER_EMAIL} = $email;
$ENV{GIT_AUTHOR_DATE} = $ENV{GIT_COMMITTER_DATE} = $log_msg->{date};
$REVDB = "$GIT_SVN_DIR/.rev_db";
$GIT_SVN_INDEX = "$GIT_SVN_DIR/index";
$SVN_URL = undef;
- $SVN_WC = "$GIT_SVN_DIR/tree";
%tree_map = ();
}
package main;
-sub libsvn_connect {
- my ($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::username, 2),
- ]);
- my $config = SVN::Core::config_get_config($_config_dir);
- my $ra = SVN::Ra->new(url => $url, auth => $baton,
- config => $config,
- pool => SVN::Pool->new,
- auth_provider_callbacks => $callbacks);
- $ra->{svn_path} = $url;
- $ra->{repos_root} = $ra->get_repos_root;
- $ra->{svn_path} =~ s#^\Q$ra->{repos_root}\E/*##;
- push @repo_path_split_cache, qr/^(\Q$ra->{repos_root}\E)/;
- return $ra;
-}
-
-sub libsvn_can_do_switch {
- unless (defined $_svn_can_do_switch) {
- my $pool = SVN::Pool->new;
- my $rep = eval {
- $SVN->do_switch(1, '', 0, $SVN->{url},
- SVN::Delta::Editor->new, $pool);
- };
- if ($@) {
- $_svn_can_do_switch = 0;
- } else {
- $rep->abort_report($pool);
- $_svn_can_do_switch = 1;
- }
- $pool->clear;
- }
- $_svn_can_do_switch;
-}
-
-sub libsvn_dup_ra {
- my ($ra) = @_;
- SVN::Ra->new(map { $_ => $ra->{$_} } qw/config url
- auth auth_provider_callbacks repos_root svn_path/);
-}
-
sub uri_encode {
my ($f) = @_;
$f =~ s#([^a-zA-Z0-9\*!\:_\./\-])#uc sprintf("%%%02x",ord($1))#eg;
}
# revprops (make this optional? it's an extra network trip...)
- my $pool = SVN::Pool->new;
- my $rp = $SVN->rev_proplist($rev, $pool);
+ my $rp = $SVN->rev_proplist($rev);
foreach (sort keys %$rp) {
next if /^svn:(?:author|date|log)$/;
print $un " rev_prop: ", uri_encode($_), ' ',
uri_encode($rp->{$_}), "\n";
}
- $pool->clear;
close $un or croak $!;
{ revision => $rev, date => "+0000 $Y-$m-$d $H:$M:$S",
sub libsvn_fetch {
my ($last_commit, $paths, $rev, $author, $date, $msg) = @_;
- my $pool = SVN::Pool->new;
my $ed = SVN::Git::Fetcher->new({ c => $last_commit, q => $_q });
- my $reporter = $SVN->do_update($rev, '', 1, $ed, $pool);
- my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : ();
my (undef, $last_rev, undef) = cmt_metadata($last_commit);
- $reporter->set_path('', $last_rev, 0, @lock, $pool);
- $reporter->finish_report($pool);
- $pool->clear;
- unless ($ed->{git_commit_ok}) {
+ unless ($SVN->gs_do_update($last_rev, $rev, '', 1, $ed)) {
die "SVN connection failed somewhere...\n";
}
libsvn_log_entry($rev, $author, $date, $msg, [$last_commit], $ed);
sub libsvn_traverse_ignore {
my ($fh, $path, $r) = @_;
$path =~ s#^/+##g;
- my $pool = SVN::Pool->new;
- my ($dirent, undef, $props) = $SVN->get_dir($path, $r, $pool);
+ my ($dirent, undef, $props) = $SVN->get_dir($path, $r);
my $p = $path;
$p =~ s#^\Q$SVN->{svn_path}\E/##;
print $fh length $p ? "\n# $p\n" : "\n# /\n";
next if $dirent->{$_}->kind != $SVN::Node::dir;
libsvn_traverse_ignore($fh, "$path/$_", $r);
}
- $pool->clear;
}
sub revisions_eq {
return 1 if $r0 == $r1;
my $nr = 0;
# should be OK to use Pool here (r1 - r0) should be small
- my $pool = SVN::Pool->new;
- libsvn_get_log($SVN, [$path], $r0, $r1,
- 0, 0, 1, sub {$nr++}, $pool);
- $pool->clear;
+ $SVN->get_log([$path], $r0, $r1, 0, 0, 1, sub {$nr++});
return 0 if ($nr > 1);
return 1;
}
unlink $GIT_SVN_INDEX;
print STDERR "Found branch parent: ($GIT_SVN) $parent\n";
command_noisy('read-tree', $parent);
- unless (libsvn_can_do_switch()) {
+ unless ($SVN->can_do_switch) {
return _libsvn_new_tree($paths, $rev, $author, $date,
$msg, [$parent]);
}
# do_switch works with svn/trunk >= r22312, but that is not
# included with SVN 1.4.2 (the latest version at the moment),
# so we can't rely on it.
- my $ra = libsvn_connect("$url/$branch_from");
+ my $ra = Git::SVN::Ra->new("$url/$branch_from");
my $ed = SVN::Git::Fetcher->new({c => $parent, q => $_q });
- my $pool = SVN::Pool->new;
- my $reporter = $ra->do_switch($rev, '', 1, $SVN->{url},
- $ed, $pool);
- my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : ();
- $reporter->set_path('', $r0, 0, @lock, $pool);
- $reporter->finish_report($pool);
- $pool->clear;
- unless ($ed->{git_commit_ok}) {
- die "SVN connection failed somewhere...\n";
- }
+ $ra->gs_do_switch($r0, $rev, '', 1, $SVN->{url}, $ed) or
+ die "SVN connection failed somewhere...\n";
return libsvn_log_entry($rev, $author, $date, $msg, [$parent]);
}
print STDERR "Nope, branch point not imported or unknown\n";
return undef;
}
-sub libsvn_get_log {
- my ($ra, @args) = @_;
- $args[4]-- if $args[4] && ! $_follow_parent;
- if ($SVN::Core::VERSION le '1.2.0') {
- splice(@args, 3, 1);
- }
- $ra->get_log(@args);
-}
-
sub libsvn_new_tree {
if (my $log_entry = libsvn_find_parent_branch(@_)) {
return $log_entry;
sub _libsvn_new_tree {
my ($paths, $rev, $author, $date, $msg, $parents) = @_;
- my $pool = SVN::Pool->new;
my $ed = SVN::Git::Fetcher->new({q => $_q});
- my $reporter = $SVN->do_update($rev, '', 1, $ed, $pool);
- my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : ();
- $reporter->set_path('', $rev, 1, @lock, $pool);
- $reporter->finish_report($pool);
- $pool->clear;
- unless ($ed->{git_commit_ok}) {
+ unless ($SVN->gs_do_update($rev, $rev, '', 1, $ed)) {
die "SVN connection failed somewhere...\n";
}
libsvn_log_entry($rev, $author, $date, $msg, $parents, $ed);
sub libsvn_ls_fullurl {
my $fullurl = shift;
- my $ra = libsvn_connect($fullurl);
+ my $ra = Git::SVN::Ra->new($fullurl);
my @ret;
- my $pool = SVN::Pool->new;
my $r = defined $_revision ? $_revision : $ra->get_latest_revnum;
- my ($dirent, undef, undef) = $ra->get_dir('', $r, $pool);
+ my ($dirent, undef, undef) = $ra->get_dir('', $r);
foreach my $d (sort keys %$dirent) {
if ($dirent->{$d}->kind == $SVN::Node::dir) {
push @ret, "$d/"; # add '/' for compat with cli svn
}
}
- $pool->clear;
return @ret;
}
-
sub libsvn_skip_unknown_revs {
my $err = shift;
my $errno = $err->apr_err();
sub open_or_add_dir {
my ($self, $full_path, $baton) = @_;
- my $p = SVN::Pool->new;
- my $t = $self->{ra}->check_path($full_path, $self->{r}, $p);
- $p->clear;
+ my $t = $self->{ra}->check_path($full_path, $self->{r});
if ($t == $SVN::Node::none) {
return $self->add_directory($full_path, $baton,
undef, -1, $self->{pool});
$self->{pool}->clear;
}
+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;
+}
+
__END__
Data structures: