|
|
|
package Git::SVN::GlobSpec;
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
|
|
|
sub new {
|
|
|
|
my ($class, $glob, $pattern_ok) = @_;
|
|
|
|
my $re = $glob;
|
|
|
|
$re =~ s!/+$!!g; # no need for trailing slashes
|
|
|
|
my (@left, @right, @patterns);
|
|
|
|
my $state = "left";
|
|
|
|
my $die_msg = "Only one set of wildcard directories " .
|
|
|
|
"(e.g. '*' or '*/*/*') is supported: '$glob'\n";
|
|
|
|
for my $part (split(m|/|, $glob)) {
|
|
|
|
if ($part =~ /\*/ && $part ne "*") {
|
|
|
|
die "Invalid pattern in '$glob': $part\n";
|
|
|
|
} elsif ($pattern_ok && $part =~ /[{}]/ &&
|
|
|
|
$part !~ /^\{[^{}]+\}/) {
|
|
|
|
die "Invalid pattern in '$glob': $part\n";
|
|
|
|
}
|
|
|
|
if ($part eq "*") {
|
|
|
|
die $die_msg if $state eq "right";
|
|
|
|
$state = "pattern";
|
|
|
|
push(@patterns, "[^/]*");
|
|
|
|
} elsif ($pattern_ok && $part =~ /^\{(.*)\}$/) {
|
|
|
|
die $die_msg if $state eq "right";
|
|
|
|
$state = "pattern";
|
|
|
|
my $p = quotemeta($1);
|
|
|
|
$p =~ s/\\,/|/g;
|
|
|
|
push(@patterns, "(?:$p)");
|
|
|
|
} else {
|
|
|
|
if ($state eq "left") {
|
|
|
|
push(@left, $part);
|
|
|
|
} else {
|
|
|
|
push(@right, $part);
|
|
|
|
$state = "right";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
my $depth = @patterns;
|
|
|
|
if ($depth == 0) {
|
|
|
|
die "One '*' is needed in glob: '$glob'\n";
|
|
|
|
}
|
|
|
|
my $left = join('/', @left);
|
|
|
|
my $right = join('/', @right);
|
|
|
|
$re = join('/', @patterns);
|
|
|
|
$re = join('\/',
|
Make git-svn branch patterns match complete URL
When using the {word,[...]} style of configuration for tags and branches,
it appears the intent is to only match whole path parts, since the words
in the {} pattern are meta-character quoted.
When the pattern word appears in the beginning or middle of the url,
it's matched completely, since the left side, pattern, and (non-empty)
right side are joined together with path separators.
However, when the pattern word appears at the end of the URL, the
right side is an empty pattern, and the resulting regex matches
more than just the specified pattern.
For example, if you specify something along the lines of
branches = branches/project/{release_1,release_2}
and your repository also contains "branches/project/release_1_2", you
will also get the release_1_2 branch. By restricting the match regex
with anchors, this is avoided.
Signed-off-by: Ammon Riley <ammon.riley@gmail.com>
Signed-off-by: Eric Wong <normalperson@yhbt.net>
12 years ago
|
|
|
grep(length, quotemeta($left),
|
|
|
|
"($re)(?=/|\$)",
|
|
|
|
quotemeta($right)));
|
|
|
|
my $left_re = qr/^\/\Q$left\E(\/|$)/;
|
|
|
|
bless { left => $left, right => $right, left_regex => $left_re,
|
|
|
|
regex => qr/$re/, glob => $glob, depth => $depth }, $class;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub full_path {
|
|
|
|
my ($self, $path) = @_;
|
|
|
|
return (length $self->{left} ? "$self->{left}/" : '') .
|
|
|
|
$path . (length $self->{right} ? "/$self->{right}" : '');
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|