Skip to content

Commit 0b2af45

Browse files
saittamEric Wong
authored andcommitted
git-svn: Fix branch detection when repository root is inaccessible
For the case of multiple projects sharing a single SVN repository, it is common practice to create the standard SVN directory layout within a subdirectory for each project. In such setups, access control is often used to limit what projects a given user may access. git-svn failed to detect branches (e.g. when passing --stdlayout to clone) because it relied on having access to the root directory in the repository. This patch solves this problem by making git-svn use paths relative to the given repository URL instead of the repository root. Signed-off-by: Mattias Nissler <[email protected]> Acked-by: Eric Wong <[email protected]>
1 parent 3c49a03 commit 0b2af45

File tree

2 files changed

+21
-30
lines changed

2 files changed

+21
-30
lines changed

git-svn.perl

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -876,10 +876,6 @@ sub cmd_multi_init {
876876
usage(1);
877877
}
878878

879-
# there are currently some bugs that prevent multi-init/multi-fetch
880-
# setups from working well without this.
881-
$Git::SVN::_minimize_url = 1;
882-
883879
$_prefix = '' unless defined $_prefix;
884880
if (defined $url) {
885881
$url = canonicalize_url($url);
@@ -1180,7 +1176,7 @@ sub complete_url_ls_init {
11801176
"wanted to set to: $gs->{url}\n";
11811177
}
11821178
command_oneline('config', $k, $gs->{url}) unless $orig_url;
1183-
my $remote_path = "$ra->{svn_path}/$repo_path";
1179+
my $remote_path = "$gs->{path}/$repo_path";
11841180
$remote_path =~ s#/+#/#g;
11851181
$remote_path =~ s#^/##g;
11861182
$remote_path .= "/*" if $remote_path !~ /\*/;
@@ -2177,16 +2173,6 @@ sub ra {
21772173
$ra;
21782174
}
21792175

2180-
sub rel_path {
2181-
my ($self) = @_;
2182-
my $repos_root = $self->ra->{repos_root};
2183-
return $self->{path} if ($self->{url} eq $repos_root);
2184-
my $url = $self->{url} .
2185-
(length $self->{path} ? "/$self->{path}" : $self->{path});
2186-
$url =~ s!^\Q$repos_root\E(?:/+|$)!!g;
2187-
$url;
2188-
}
2189-
21902176
# prop_walk(PATH, REV, SUB)
21912177
# -------------------------
21922178
# Recursively traverse PATH at revision REV and invoke SUB for each
@@ -2512,10 +2498,7 @@ sub match_paths {
25122498
if (my $path = $paths->{"/$self->{path}"}) {
25132499
return ($path->{action} eq 'D') ? 0 : 1;
25142500
}
2515-
my $repos_root = $self->ra->{repos_root};
2516-
my $extended_path = $self->{url} . '/' . $self->{path};
2517-
$extended_path =~ s#^\Q$repos_root\E(/|$)##;
2518-
$self->{path_regex} ||= qr/^\/\Q$extended_path\E\//;
2501+
$self->{path_regex} ||= qr/^\/\Q$self->{path}\E\//;
25192502
if (grep /$self->{path_regex}/, keys %$paths) {
25202503
return 1;
25212504
}
@@ -2545,7 +2528,7 @@ sub find_parent_branch {
25452528
return undef unless defined $paths;
25462529

25472530
# look for a parent from another branch:
2548-
my @b_path_components = split m#/#, $self->rel_path;
2531+
my @b_path_components = split m#/#, $self->{path};
25492532
my @a_path_components;
25502533
my $i;
25512534
while (@b_path_components) {
@@ -2563,11 +2546,11 @@ sub find_parent_branch {
25632546
my $r = $i->{copyfrom_rev};
25642547
my $repos_root = $self->ra->{repos_root};
25652548
my $url = $self->ra->{url};
2566-
my $new_url = $repos_root . $branch_from;
2549+
my $new_url = $url . $branch_from;
25672550
print STDERR "Found possible branch point: ",
25682551
"$new_url => ", $self->full_url, ", $r\n";
25692552
$branch_from =~ s#^/##;
2570-
my $gs = $self->other_gs($new_url, $url, $repos_root,
2553+
my $gs = $self->other_gs($new_url, $url,
25712554
$branch_from, $r, $self->{ref_id});
25722555
my ($r0, $parent) = $gs->find_rev_before($r, 1);
25732556
{
@@ -2752,9 +2735,9 @@ sub parse_svn_date {
27522735
}
27532736

27542737
sub other_gs {
2755-
my ($self, $new_url, $url, $repos_root,
2738+
my ($self, $new_url, $url,
27562739
$branch_from, $r, $old_ref_id) = @_;
2757-
my $gs = Git::SVN->find_by_url($new_url, $repos_root, $branch_from);
2740+
my $gs = Git::SVN->find_by_url($new_url, $url, $branch_from);
27582741
unless ($gs) {
27592742
my $ref_id = $old_ref_id;
27602743
$ref_id =~ s/\@\d+$//;
@@ -4436,14 +4419,22 @@ sub get_log {
44364419
# externally passed pool (instead of our temporary and quickly cleared
44374420
# pool in Git::SVN::Ra) does not help matters at all...
44384421
my $receiver = pop @args;
4422+
my $prefix = "/".$self->{svn_path};
4423+
$prefix =~ s#/+($)##;
4424+
my $prefix_regex = qr#^\Q$prefix\E#;
44394425
push(@args, sub {
44404426
my ($paths) = $_[0];
44414427
return &$receiver(@_) unless $paths;
44424428
$_[0] = ();
44434429
foreach my $p (keys %$paths) {
44444430
my $i = $paths->{$p};
4445-
my %s = map { $_ => $i->$_ }
4446-
qw/copyfrom_path copyfrom_rev action/;
4431+
# Make path relative to our url, not repos_root
4432+
$p =~ s/$prefix_regex//;
4433+
my %s = map { $_ => $i->$_; }
4434+
qw/copyfrom_path copyfrom_rev action/;
4435+
if ($s{'copyfrom_path'}) {
4436+
$s{'copyfrom_path'} =~ s/$prefix_regex//;
4437+
}
44474438
$_[0]{$p} = \%s;
44484439
}
44494440
&$receiver(@_);

t/t9138-git-svn-multiple-branches.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,22 @@ test_expect_success 'Multiple branch or tag paths require -d' '
9999

100100
test_expect_success 'create new branches and tags' '
101101
( cd git_project &&
102-
git svn branch -m "New branch 1" -d project/b_one New1 ) &&
102+
git svn branch -m "New branch 1" -d b_one New1 ) &&
103103
( cd svn_project &&
104104
svn_cmd up && test -e b_one/New1/a.file ) &&
105105
106106
( cd git_project &&
107-
git svn branch -m "New branch 2" -d project/b_two New2 ) &&
107+
git svn branch -m "New branch 2" -d b_two New2 ) &&
108108
( cd svn_project &&
109109
svn_cmd up && test -e b_two/New2/a.file ) &&
110110
111111
( cd git_project &&
112-
git svn branch -t -m "New tag 1" -d project/tags_A Tag1 ) &&
112+
git svn branch -t -m "New tag 1" -d tags_A Tag1 ) &&
113113
( cd svn_project &&
114114
svn_cmd up && test -e tags_A/Tag1/a.file ) &&
115115
116116
( cd git_project &&
117-
git svn tag -m "New tag 2" -d project/tags_B Tag2 ) &&
117+
git svn tag -m "New tag 2" -d tags_B Tag2 ) &&
118118
( cd svn_project &&
119119
svn_cmd up && test -e tags_B/Tag2/a.file )
120120
'

0 commit comments

Comments
 (0)