diff options
-rwxr-xr-x | git-svn.perl | 96 | ||||
-rwxr-xr-x | t/t9100-git-svn-basic.sh | 14 |
2 files changed, 89 insertions, 21 deletions
diff --git a/git-svn.perl b/git-svn.perl index de026b4e4..d290a0d8e 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -748,35 +748,78 @@ sub sanitize_remote_name { $name; } -sub init { - my ($class, $url, $path, $repo_id, $ref_id) = @_; - my $self = _new($class, $repo_id, $ref_id, $path); - if (defined $url) { - $url =~ s!/+$!!; # strip trailing slash +sub find_existing_remote { + my ($url, $remotes) = @_; + my $existing; + foreach my $repo_id (keys %$remotes) { + my $u = $remotes->{$repo_id}->{url} or next; + next if $u ne $url; + $existing = $repo_id; + last; + } + $existing; +} +sub init_remote_config { + my ($self, $url) = @_; + $url =~ s!/+$!!; # strip trailing slash + my $r = read_all_remotes(); + my $existing = find_existing_remote($url, $r); + if ($existing) { + print STDERR "Using existing ", + "[svn-remote \"$existing\"]\n"; + $self->{repo_id} = $existing; + } else { + my $min_url = Git::SVN::Ra->new($url)->minimize_url; + $existing = find_existing_remote($min_url, $r); + if ($existing) { + print STDERR "Using existing ", + "[svn-remote \"$existing\"]\n"; + $self->{repo_id} = $existing; + } + if ($min_url ne $url) { + print STDERR "Using higher level of URL: ", + "$url => $min_url\n"; + my $old_path = $self->{path}; + $self->{path} = $url; + $self->{path} =~ s!^\Q$min_url\E/*!!; + if (length $old_path) { + $self->{path} .= "/$old_path"; + } + $url = $min_url; + } + } + my $orig_url; + if (!$existing) { # verify that we aren't overwriting anything: - my $orig_url = eval { + $orig_url = eval { command_oneline('config', '--get', - "svn-remote.$repo_id.url") + "svn-remote.$self->{repo_id}.url") }; if ($orig_url && ($orig_url ne $url)) { - die "svn-remote.$repo_id.url already set: ", + die "svn-remote.$self->{repo_id}.url already set: ", "$orig_url\nwanted to set to: $url\n"; } - my ($xrepo_id, $xpath) = find_ref($self->refname); - if (defined $xpath) { - die "svn-remote.$xrepo_id.fetch already set to track ", - "$xpath:refs/remotes/", $self->refname, "\n"; - } - if (!$orig_url) { - command_noisy('config', - "svn-remote.$repo_id.url", $url); - } - command_noisy('config', '--add', - "svn-remote.$repo_id.fetch", - "$path:".$self->refname); } + my ($xrepo_id, $xpath) = find_ref($self->refname); + if (defined $xpath) { + die "svn-remote.$xrepo_id.fetch already set to track ", + "$xpath:refs/remotes/", $self->refname, "\n"; + } + command_noisy('config', + "svn-remote.$self->{repo_id}.url", $url); + command_noisy('config', '--add', + "svn-remote.$self->{repo_id}.fetch", + "$self->{path}:".$self->refname); $self->{url} = $url; +} + +sub init { + my ($class, $url, $path, $repo_id, $ref_id) = @_; + my $self = _new($class, $repo_id, $ref_id, $path); + if (defined $url) { + $self->init_remote_config($url); + } $self; } @@ -2208,6 +2251,19 @@ sub gs_do_switch { $editor->{git_commit_ok}; } +sub minimize_url { + my ($self) = @_; + return $self->{url} if ($self->{url} eq $self->{repos_root}); + my $url = $self->{repos_root}; + my @components = split(m!/!, $self->{svn_path}); + my $c = ''; + do { + $url .= "/$c" if length $c; + eval { (ref $self)->new($url)->get_latest_revnum }; + } while ($@ && ($c = shift @components)); + $url; +} + sub can_do_switch { my $self = shift; unless (defined $can_do_switch) { diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index af617486d..97798c4d0 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -220,10 +220,22 @@ test_expect_failure 'exit if remote refs are ambigious' " bar:refs/remotes/git-svn && git-svn migrate " + test_expect_failure 'exit if init-ing a would clobber a URL' " + svnadmin create ${PWD}/svnrepo2 && + svn mkdir -m 'mkdir bar' ${svnrepo}2/bar && git-repo-config --unset svn-remote.git-svn.fetch \ '^bar:refs/remotes/git-svn$' && - git-svn init $svnrepo/bar + git-svn init ${svnrepo}2/bar + " + +test_expect_success \ + 'init allows us to connect to another directory in the same repo' " + git-svn init -i bar $svnrepo/bar && + git repo-config --get svn-remote.git-svn.fetch \ + '^bar:refs/remotes/bar$' && + git repo-config --get svn-remote.git-svn.fetch \ + '^:refs/remotes/git-svn$' " test_done |