diff options
| author | Jay Soffian <jaysoffian@gmail.com> | 2010-01-23 03:30:01 -0500 | 
|---|---|---|
| committer | Eric Wong <normalperson@yhbt.net> | 2010-01-23 03:23:04 -0800 | 
| commit | 075762085c6668f11c4ea165ecec17f69245ef09 (patch) | |
| tree | c96d230f80c8d4322b43e899482e83e2fd784eca /git-svn.perl | |
| parent | 3e18ce1ac3034b1562ec748523aa7636e1b58b52 (diff) | |
| download | git-075762085c6668f11c4ea165ecec17f69245ef09.tar.gz | |
git-svn: allow subset of branches/tags to be specified in glob spec
For very large projects it is useful to be able to clone a subset of the
upstream SVN repo's branches. Allow for this by letting the left-side of
the branches and tags glob specs contain a brace-delineated comma-separated
list of names. e.g.:
	branches = branches/{red,green}/src:refs/remotes/branches/*
Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
Acked-by: Eric Wong <normalperson@yhbt.net>
Diffstat (limited to 'git-svn.perl')
| -rwxr-xr-x | git-svn.perl | 60 | 
1 files changed, 40 insertions, 20 deletions
| diff --git a/git-svn.perl b/git-svn.perl index f7226714fa..b321c968af 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -1825,8 +1825,8 @@ sub read_all_remotes {  			my $rs = {  			    t => $t,  			    remote => $remote, -			    path => Git::SVN::GlobSpec->new($local_ref), -			    ref => Git::SVN::GlobSpec->new($remote_ref) }; +			    path => Git::SVN::GlobSpec->new($local_ref, 1), +			    ref => Git::SVN::GlobSpec->new($remote_ref, 0) };  			if (length($rs->{ref}->{right}) != 0) {  				die "The '*' glob character must be the last ",  				    "character of '$remote_ref'\n"; @@ -5233,6 +5233,7 @@ sub match_globs {  			next if (length $g->{path}->{right} &&  				 ($self->check_path($p, $r) !=  				  $SVN::Node::dir)); +			next unless $p =~ /$g->{path}->{regex}/;  			$exists->{$p} = Git::SVN->init($self->{url}, $p, undef,  					 $g->{ref}->full_path($de), 1);  		} @@ -6006,29 +6007,48 @@ use strict;  use warnings;  sub new { -	my ($class, $glob) = @_; +	my ($class, $glob, $pattern_ok) = @_;  	my $re = $glob;  	$re =~ s!/+$!!g; # no need for trailing slashes -	$re =~ m!^([^*]*)(\*(?:/\*)*)(.*)$!; -	my $temp = $re; -	my ($left, $right) = ($1, $3); -	$re = $2; -	my $depth = $re =~ tr/*/*/; -	if ($depth != $temp =~ tr/*/*/) { -		die "Only one set of wildcard directories " . -			"(e.g. '*' or '*/*/*') is supported: '$glob'\n"; +	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 for glob: '$glob'\n"; -	} -	$re =~ s!\*!\[^/\]*!g; -	$re = quotemeta($left) . "($re)" . quotemeta($right); -	if (length $left && !($left =~ s!/+$!!g)) { -		die "Missing trailing '/' on left side of: '$glob' ($left)\n"; -	} -	if (length $right && !($right =~ s!^/+!!g)) { -		die "Missing leading '/' on right side of: '$glob' ($right)\n"; +		die "One '*' is needed in glob: '$glob'\n";  	} +	my $left = join('/', @left); +	my $right = join('/', @right); +	$re = join('/', @patterns); +	$re = join('\/', +		   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; | 
