git-svn: prepare multi-init for wildcard support
Update the tests since we no longer write so many things to the config. Signed-off-by: Eric Wong <normalperson@yhbt.net>
This commit is contained in:
parent
9fa00b655c
commit
4bb9ed0466
124
git-svn.perl
124
git-svn.perl
@ -367,9 +367,10 @@ sub cmd_multi_init {
|
||||
sub cmd_multi_fetch {
|
||||
my $remotes = Git::SVN::read_all_remotes();
|
||||
foreach my $repo_id (sort keys %$remotes) {
|
||||
my $url = $remotes->{$repo_id}->{url} or next;
|
||||
my $fetch = $remotes->{$repo_id}->{fetch} or next;
|
||||
Git::SVN::fetch_all($repo_id, $url, $fetch);
|
||||
if ($remotes->{$repo_id}->{url} &&
|
||||
$remotes->{$repo_id}->{fetch}) {
|
||||
Git::SVN::fetch_all($repo_id, $remotes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -479,9 +480,12 @@ sub complete_url_ls_init {
|
||||
# don't try to init already existing refs
|
||||
unless ($gs) {
|
||||
print "init $url/$path => $ref\n";
|
||||
$gs = Git::SVN->init($url, $path, undef, $ref);
|
||||
$gs = Git::SVN->init($url, $path, undef, $ref, 1);
|
||||
}
|
||||
if ($gs) {
|
||||
$remote_id = $gs->{repo_id};
|
||||
last;
|
||||
}
|
||||
$remote_id ||= $gs->{repo_id} if $gs;
|
||||
}
|
||||
if (defined $remote_id) {
|
||||
$remote_path = "$ra->{svn_path}/$repo_path/*";
|
||||
@ -489,7 +493,7 @@ sub complete_url_ls_init {
|
||||
$remote_path =~ s#^/##g;
|
||||
my ($n) = ($switch =~ /^--(\w+)/);
|
||||
command_noisy('config', "svn-remote.$remote_id.$n",
|
||||
$remote_path);
|
||||
"$remote_path:refs/remotes/$pfx*");
|
||||
}
|
||||
}
|
||||
|
||||
@ -660,9 +664,48 @@ BEGIN {
|
||||
my %LOCKFILES;
|
||||
END { unlink keys %LOCKFILES if %LOCKFILES }
|
||||
|
||||
sub resolve_local_globs {
|
||||
my ($url, $fetch, $glob_spec) = @_;
|
||||
return unless defined $glob_spec;
|
||||
my $ref = $glob_spec->{ref};
|
||||
my $path = $glob_spec->{path};
|
||||
foreach (command(qw#for-each-ref --format=%(refname) refs/remotes#)) {
|
||||
next unless m#^refs/remotes/$ref->{regex}$#;
|
||||
my $p = $1;
|
||||
my $pathname = $path->full_path($p);
|
||||
my $refname = $ref->full_path($p);
|
||||
if (my $existing = $fetch->{$pathname}) {
|
||||
if ($existing ne $refname) {
|
||||
die "Refspec conflict:\n",
|
||||
"existing: refs/remotes/$existing\n",
|
||||
" globbed: refs/remotes/$refname\n";
|
||||
}
|
||||
my $u = (::cmt_metadata("refs/remotes/$refname"))[0];
|
||||
$u =~ s!^\Q$url\E/?!! or die
|
||||
"refs/remotes/$refname: '$url' not found in '$u'\n";
|
||||
if ($pathname ne $u) {
|
||||
warn "W: Refspec glob conflict ",
|
||||
"(ref: refs/remotes/$refname):\n",
|
||||
"expected path: $pathname\n",
|
||||
" real path: $u\n",
|
||||
"Continuing ahead with $u\n";
|
||||
next;
|
||||
}
|
||||
} else {
|
||||
warn "Globbed ($path->{glob}:$ref->{glob}): ",
|
||||
"$pathname == $refname\n";
|
||||
$fetch->{$pathname} = $refname;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub fetch_all {
|
||||
my ($repo_id, $url, $fetch) = @_;
|
||||
my ($repo_id, $remotes) = @_;
|
||||
my $fetch = $remotes->{$repo_id}->{fetch};
|
||||
my $url = $remotes->{$repo_id}->{url};
|
||||
my @gs;
|
||||
resolve_local_globs($url, $fetch, $remotes->{$repo_id}->{branches});
|
||||
resolve_local_globs($url, $fetch, $remotes->{$repo_id}->{tags});
|
||||
my $ra = Git::SVN::Ra->new($url);
|
||||
my $head = $ra->get_latest_revnum;
|
||||
my $base = $head;
|
||||
@ -685,6 +728,16 @@ sub read_all_remotes {
|
||||
$r->{$1}->{fetch}->{$2} = $3;
|
||||
} elsif (m!^(.+)\.url=\s*(.*)\s*$!) {
|
||||
$r->{$1}->{url} = $2;
|
||||
} elsif (m!^(.+)\.(branches|tags)=
|
||||
(.*):refs/remotes/(.+)\s*$/!x) {
|
||||
my ($p, $g) = ($3, $4);
|
||||
my $rs = $r->{$1}->{$2} = {
|
||||
path => Git::SVN::GlobSpec->new($p),
|
||||
ref => Git::SVN::GlobSpec->new($g) };
|
||||
if (length($rs->{ref}->{right}) != 0) {
|
||||
die "The '*' glob character must be the last ",
|
||||
"character of '$g'\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
$r;
|
||||
@ -3072,10 +3125,67 @@ sub DESTROY {
|
||||
command_close_pipe($self->{gui}, $self->{ctx});
|
||||
}
|
||||
|
||||
package Git::SVN::GlobSpec;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
sub new {
|
||||
my ($class, $glob) = @_;
|
||||
warn "glob: $glob\n";
|
||||
my $re = $glob;
|
||||
$re =~ s!/+$!!g; # no need for trailing slashes
|
||||
my $nr = ($re =~ s!^(.*/?)\*(/?.*)$!\(\[^/\]+\)!g);
|
||||
my ($left, $right) = ($1, $2);
|
||||
if ($nr > 1) {
|
||||
warn "Only one '*' wildcard expansion ",
|
||||
"is supported (got $nr): '$glob'\n";
|
||||
} elsif ($nr == 0) {
|
||||
warn "One '*' is needed for glob: '$glob'\n";
|
||||
}
|
||||
$re = quotemeta($left) . $re . quotemeta($right);
|
||||
$left =~ s!/+$!!g;
|
||||
$right =~ s!^/+!!g;
|
||||
bless { left => $left, right => $right,
|
||||
regex => qr/$re/, glob => $glob }, $class;
|
||||
}
|
||||
|
||||
sub full_path {
|
||||
my ($self, $path) = @_;
|
||||
return (length $self->{left} ? "$self->{left}/" : '') .
|
||||
$path . (length $self->{right} ? "/$self->{right}" : '');
|
||||
}
|
||||
|
||||
__END__
|
||||
|
||||
Data structures:
|
||||
|
||||
|
||||
$remotes = { # returned by read_all_remotes()
|
||||
'svn' => {
|
||||
# svn-remote.svn.url=https://svn.musicpd.org
|
||||
url => 'https://svn.musicpd.org',
|
||||
# svn-remote.svn.fetch=mpd/trunk:trunk
|
||||
fetch => {
|
||||
'mpd/trunk' => 'trunk',
|
||||
},
|
||||
# svn-remote.svn.tags=mpd/tags/*:tags/*
|
||||
tags => {
|
||||
path => {
|
||||
left => 'mpd/tags',
|
||||
right => '',
|
||||
regex => qr!mpd/tags/([^/]+)$!,
|
||||
glob => 'tags/*',
|
||||
},
|
||||
ref => {
|
||||
left => 'tags',
|
||||
right => '',
|
||||
regex => qr!tags/([^/]+)$!,
|
||||
glob => 'tags/*',
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$log_entry hashref as returned by libsvn_log_entry()
|
||||
{
|
||||
log => 'whitespace-formatted log entry
|
||||
|
@ -6,7 +6,7 @@ test_description='git-svn metadata migrations from previous versions'
|
||||
test_expect_success 'setup old-looking metadata' "
|
||||
cp $GIT_DIR/config $GIT_DIR/config-old-git-svn &&
|
||||
mkdir import &&
|
||||
cd import
|
||||
cd import &&
|
||||
for i in trunk branches/a branches/b \
|
||||
tags/0.1 tags/0.2 tags/0.3; do
|
||||
mkdir -p \$i && \
|
||||
@ -43,11 +43,19 @@ test_expect_success 'initialize a multi-repository repo' "
|
||||
git-svn multi-init $svnrepo -T trunk -t tags -b branches &&
|
||||
git-repo-config --get-all svn-remote.svn.fetch > fetch.out &&
|
||||
grep '^trunk:refs/remotes/trunk$' fetch.out &&
|
||||
grep '^branches/a:refs/remotes/a$' fetch.out &&
|
||||
grep '^branches/b:refs/remotes/b$' fetch.out &&
|
||||
grep '^tags/0\.1:refs/remotes/tags/0\.1$' fetch.out &&
|
||||
grep '^tags/0\.2:refs/remotes/tags/0\.2$' fetch.out &&
|
||||
grep '^tags/0\.3:refs/remotes/tags/0\.3$' fetch.out
|
||||
test -n \"\`git-config --get svn-remote.svn.branches \
|
||||
'^branches/\*:refs/remotes/\*$'\`\" &&
|
||||
test -n \"\`git-config --get svn-remote.svn.tags \
|
||||
'^tags/\*:refs/remotes/tags/\*$'\`\" &&
|
||||
git config --unset svn-remote.svn.branches \
|
||||
'^branches/\*:refs/remotes/\*$' &&
|
||||
git config --unset svn-remote.svn.tags \
|
||||
'^tags/\*:refs/remotes/tags/\*$' &&
|
||||
git-config --add svn-remote.svn.fetch 'branches/a:refs/remotes/a' &&
|
||||
git-config --add svn-remote.svn.fetch 'branches/b:refs/remotes/b' &&
|
||||
for i in tags/0.1 tags/0.2 tags/0.3; do
|
||||
git-config --add svn-remote.svn.fetch \
|
||||
\$i:refs/remotes/\$i || exit 1; done
|
||||
"
|
||||
|
||||
# refs should all be different, but the trees should all be the same:
|
||||
|
Loading…
Reference in New Issue
Block a user