Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2007-01-28 15:59:05 +0300
committerEric Wong <normalperson@yhbt.net>2007-02-23 11:57:10 +0300
commit2b27f6c8847ebee631e7ad17ac9986e461d7674b (patch)
treec927a6f524bf5ee52e1f379bd80c51df6cae1469 /git-svn.perl
parent2fa6a23efb200cea814add88ce1d1d193ba83860 (diff)
git-svn: correctly handle do_{switch,update} in deep directories
The do_update or do_switch functions in SVN only allow for a single path component; so 'path/to/deep/dir' would be interpreted as 'path'. SVN 1.4.x has a reparent function that can let us change the session to use a higher-level root of the repository, so we can use that for do_switch (which still doesn't seem to work in SVN 1.4.3 (a fix was attempted, but they missed the rest of the typemap changes needed in trunk...)). On the do_update side, we can use set_path on higher level directories and set them to a newer revision so they don't get updated. We can't do this with do_switch, either, because the relative path we're tracking can change (directory moving into a child of itself). Because of these changes, we need to double check that our Fetch editor is correctly performing stripping on any prefixed paths from update, otherwise we'll just die() because that would be a bug. Added a test case which helped me notice and fix problems with do_switch, too. Signed-off-by: Eric Wong <normalperson@yhbt.net>
Diffstat (limited to 'git-svn.perl')
-rwxr-xr-xgit-svn.perl46
1 files changed, 38 insertions, 8 deletions
diff --git a/git-svn.perl b/git-svn.perl
index 36e5c57adf..dcc7fd4603 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1153,7 +1153,7 @@ sub find_parent_branch {
if ($self->ra->can_do_switch) {
print STDERR "Following parent with do_switch\n";
# do_switch works with svn/trunk >= r22312, but that
- # is not included with SVN 1.4.2 (the latest version
+ # is not included with SVN 1.4.3 (the latest version
# at the moment), so we can't rely on it
$self->{last_commit} = $parent;
$ed = SVN::Git::Fetcher->new($self);
@@ -1621,7 +1621,10 @@ sub open_directory {
sub git_path {
my ($self, $path) = @_;
- $path =~ s!$self->{path_strip}!! if $self->{path_strip};
+ if ($self->{path_strip}) {
+ $path =~ s!$self->{path_strip}!! or
+ die "Failed to strip path '$path' ($self->{path_strip})\n";
+ }
$path;
}
@@ -2249,25 +2252,52 @@ sub gs_do_update {
my ($self, $rev_a, $rev_b, $path, $recurse, $editor) = @_;
my $pool = SVN::Pool->new;
$editor->set_path_strip($path);
- my $reporter = $self->do_update($rev_b, $path, $recurse,
- $editor, $pool);
+ my (@pc) = split m#/#, $path;
+ my $reporter = $self->do_update($rev_b, (@pc ? shift @pc : ''),
+ $recurse, $editor, $pool);
my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : ();
+
+ # Since we can't rely on svn_ra_reparent being available, we'll
+ # just have to do some magic with set_path to make it so
+ # we only want a partial path.
+ my $sp = '';
+ my $final = join('/', @pc);
+ while (@pc) {
+ $reporter->set_path($sp, $rev_b, 0, @lock, $pool);
+ $sp .= '/' if length $sp;
+ $sp .= shift @pc;
+ }
+ die "BUG: '$sp' != '$final'\n" if ($sp ne $final);
+
my $new = ($rev_a == $rev_b);
- $reporter->set_path('', $rev_a, $new, @lock, $pool);
+ $reporter->set_path($sp, $rev_a, $new, @lock, $pool);
+
$reporter->finish_report($pool);
$pool->clear;
$editor->{git_commit_ok};
}
+# this requires SVN 1.4.3 or later (do_switch didn't work before 1.4.3, and
+# svn_ra_reparent didn't work before 1.4)
sub gs_do_switch {
my ($self, $rev_a, $rev_b, $path, $recurse, $url_b, $editor) = @_;
my $pool = SVN::Pool->new;
- $editor->set_path_strip($path);
- my $reporter = $self->do_switch($rev_b, $path, $recurse,
- $url_b, $editor, $pool);
+
+ my $full_url = $self->{url};
+ my $old_url = $full_url;
+ $full_url .= "/$path" if length $path;
+ SVN::_Ra::svn_ra_reparent($self->{session}, $full_url, $pool);
+ $self->{url} = $full_url;
+
+ my $reporter = $self->do_switch($rev_b, '',
+ $recurse, $url_b, $editor, $pool);
my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : ();
$reporter->set_path('', $rev_a, 0, @lock, $pool);
$reporter->finish_report($pool);
+
+ SVN::_Ra::svn_ra_reparent($self->{session}, $old_url, $pool);
+ $self->{url} = $old_url;
+
$pool->clear;
$editor->{git_commit_ok};
}