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>
This commit is contained in:
parent
3e18ce1ac3
commit
075762085c
@ -838,6 +838,22 @@ independent path component (surrounded by '/' or EOL). This
|
|||||||
type of configuration is not automatically created by 'init' and
|
type of configuration is not automatically created by 'init' and
|
||||||
should be manually entered with a text-editor or using 'git config'.
|
should be manually entered with a text-editor or using 'git config'.
|
||||||
|
|
||||||
|
It is also possible to fetch a subset of branches or tags by using a
|
||||||
|
comma-separated list of names within braces. For example:
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
[svn-remote "huge-project"]
|
||||||
|
url = http://server.org/svn
|
||||||
|
fetch = trunk/src:refs/remotes/trunk
|
||||||
|
branches = branches/{red,green}/src:refs/remotes/branches/*
|
||||||
|
tags = tags/{1.0,2.0}/src:refs/remotes/tags/*
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Note that git-svn keeps track of the highest revision in which a branch
|
||||||
|
or tag has appeared. If the subset of branches or tags is changed after
|
||||||
|
fetching, then .git/svn/.metadata must be manually edited to remove (or
|
||||||
|
reset) branches-maxRev and/or tags-maxRev as appropriate.
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
linkgit:git-rebase[1]
|
linkgit:git-rebase[1]
|
||||||
|
60
git-svn.perl
60
git-svn.perl
@ -1825,8 +1825,8 @@ sub read_all_remotes {
|
|||||||
my $rs = {
|
my $rs = {
|
||||||
t => $t,
|
t => $t,
|
||||||
remote => $remote,
|
remote => $remote,
|
||||||
path => Git::SVN::GlobSpec->new($local_ref),
|
path => Git::SVN::GlobSpec->new($local_ref, 1),
|
||||||
ref => Git::SVN::GlobSpec->new($remote_ref) };
|
ref => Git::SVN::GlobSpec->new($remote_ref, 0) };
|
||||||
if (length($rs->{ref}->{right}) != 0) {
|
if (length($rs->{ref}->{right}) != 0) {
|
||||||
die "The '*' glob character must be the last ",
|
die "The '*' glob character must be the last ",
|
||||||
"character of '$remote_ref'\n";
|
"character of '$remote_ref'\n";
|
||||||
@ -5233,6 +5233,7 @@ sub match_globs {
|
|||||||
next if (length $g->{path}->{right} &&
|
next if (length $g->{path}->{right} &&
|
||||||
($self->check_path($p, $r) !=
|
($self->check_path($p, $r) !=
|
||||||
$SVN::Node::dir));
|
$SVN::Node::dir));
|
||||||
|
next unless $p =~ /$g->{path}->{regex}/;
|
||||||
$exists->{$p} = Git::SVN->init($self->{url}, $p, undef,
|
$exists->{$p} = Git::SVN->init($self->{url}, $p, undef,
|
||||||
$g->{ref}->full_path($de), 1);
|
$g->{ref}->full_path($de), 1);
|
||||||
}
|
}
|
||||||
@ -6006,29 +6007,48 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
my ($class, $glob) = @_;
|
my ($class, $glob, $pattern_ok) = @_;
|
||||||
my $re = $glob;
|
my $re = $glob;
|
||||||
$re =~ s!/+$!!g; # no need for trailing slashes
|
$re =~ s!/+$!!g; # no need for trailing slashes
|
||||||
$re =~ m!^([^*]*)(\*(?:/\*)*)(.*)$!;
|
my (@left, @right, @patterns);
|
||||||
my $temp = $re;
|
my $state = "left";
|
||||||
my ($left, $right) = ($1, $3);
|
my $die_msg = "Only one set of wildcard directories " .
|
||||||
$re = $2;
|
"(e.g. '*' or '*/*/*') is supported: '$glob'\n";
|
||||||
my $depth = $re =~ tr/*/*/;
|
for my $part (split(m|/|, $glob)) {
|
||||||
if ($depth != $temp =~ tr/*/*/) {
|
if ($part =~ /\*/ && $part ne "*") {
|
||||||
die "Only one set of wildcard directories " .
|
die "Invalid pattern in '$glob': $part\n";
|
||||||
"(e.g. '*' or '*/*/*') is supported: '$glob'\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) {
|
if ($depth == 0) {
|
||||||
die "One '*' is needed for glob: '$glob'\n";
|
die "One '*' is needed in 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";
|
|
||||||
}
|
}
|
||||||
|
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(\/|$)/;
|
my $left_re = qr/^\/\Q$left\E(\/|$)/;
|
||||||
bless { left => $left, right => $right, left_regex => $left_re,
|
bless { left => $left, right => $right, left_regex => $left_re,
|
||||||
regex => qr/$re/, glob => $glob, depth => $depth }, $class;
|
regex => qr/$re/, glob => $glob, depth => $depth }, $class;
|
||||||
|
42
t/t9154-git-svn-fancy-glob.sh
Executable file
42
t/t9154-git-svn-fancy-glob.sh
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (c) 2010 Jay Soffian
|
||||||
|
#
|
||||||
|
|
||||||
|
test_description='git svn fancy glob test'
|
||||||
|
|
||||||
|
. ./lib-git-svn.sh
|
||||||
|
|
||||||
|
test_expect_success 'load svn repo' "
|
||||||
|
svnadmin load -q '$rawsvnrepo' < '$TEST_DIRECTORY/t9154/svn.dump' &&
|
||||||
|
git svn init --minimize-url -T trunk '$svnrepo' &&
|
||||||
|
git svn fetch
|
||||||
|
"
|
||||||
|
|
||||||
|
test_expect_success 'add red branch' "
|
||||||
|
git config svn-remote.svn.branches 'branches/{red}:refs/remotes/*' &&
|
||||||
|
git svn fetch &&
|
||||||
|
git rev-parse refs/remotes/red &&
|
||||||
|
test_must_fail git rev-parse refs/remotes/green &&
|
||||||
|
test_must_fail git rev-parse refs/remotes/blue
|
||||||
|
"
|
||||||
|
|
||||||
|
test_expect_success 'add green branch' "
|
||||||
|
GIT_CONFIG=.git/svn/.metadata git config --unset svn-remote.svn.branches-maxRev &&
|
||||||
|
git config svn-remote.svn.branches 'branches/{red,green}:refs/remotes/*' &&
|
||||||
|
git svn fetch &&
|
||||||
|
git rev-parse refs/remotes/red &&
|
||||||
|
git rev-parse refs/remotes/green &&
|
||||||
|
test_must_fail git rev-parse refs/remotes/blue
|
||||||
|
"
|
||||||
|
|
||||||
|
test_expect_success 'add all branches' "
|
||||||
|
GIT_CONFIG=.git/svn/.metadata git config --unset svn-remote.svn.branches-maxRev &&
|
||||||
|
git config svn-remote.svn.branches 'branches/*:refs/remotes/*' &&
|
||||||
|
git svn fetch &&
|
||||||
|
git rev-parse refs/remotes/red &&
|
||||||
|
git rev-parse refs/remotes/green &&
|
||||||
|
git rev-parse refs/remotes/blue
|
||||||
|
"
|
||||||
|
|
||||||
|
test_done
|
222
t/t9154/svn.dump
Normal file
222
t/t9154/svn.dump
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
SVN-fs-dump-format-version: 2
|
||||||
|
|
||||||
|
UUID: a18093a0-5f0b-44e0-8d88-8911ac7078db
|
||||||
|
|
||||||
|
Revision-number: 0
|
||||||
|
Prop-content-length: 56
|
||||||
|
Content-length: 56
|
||||||
|
|
||||||
|
K 8
|
||||||
|
svn:date
|
||||||
|
V 27
|
||||||
|
2010-01-23T07:40:25.660053Z
|
||||||
|
PROPS-END
|
||||||
|
|
||||||
|
Revision-number: 1
|
||||||
|
Prop-content-length: 104
|
||||||
|
Content-length: 104
|
||||||
|
|
||||||
|
K 7
|
||||||
|
svn:log
|
||||||
|
V 7
|
||||||
|
initial
|
||||||
|
K 10
|
||||||
|
svn:author
|
||||||
|
V 3
|
||||||
|
jay
|
||||||
|
K 8
|
||||||
|
svn:date
|
||||||
|
V 27
|
||||||
|
2010-01-23T07:41:33.636365Z
|
||||||
|
PROPS-END
|
||||||
|
|
||||||
|
Node-path: trunk
|
||||||
|
Node-kind: dir
|
||||||
|
Node-action: add
|
||||||
|
Prop-content-length: 10
|
||||||
|
Content-length: 10
|
||||||
|
|
||||||
|
PROPS-END
|
||||||
|
|
||||||
|
|
||||||
|
Node-path: trunk/foo
|
||||||
|
Node-kind: file
|
||||||
|
Node-action: add
|
||||||
|
Prop-content-length: 10
|
||||||
|
Text-content-length: 4
|
||||||
|
Text-content-md5: d3b07384d113edec49eaa6238ad5ff00
|
||||||
|
Text-content-sha1: f1d2d2f924e986ac86fdf7b36c94bcdf32beec15
|
||||||
|
Content-length: 14
|
||||||
|
|
||||||
|
PROPS-END
|
||||||
|
foo
|
||||||
|
|
||||||
|
|
||||||
|
Revision-number: 2
|
||||||
|
Prop-content-length: 110
|
||||||
|
Content-length: 110
|
||||||
|
|
||||||
|
K 7
|
||||||
|
svn:log
|
||||||
|
V 12
|
||||||
|
add branches
|
||||||
|
K 10
|
||||||
|
svn:author
|
||||||
|
V 3
|
||||||
|
jay
|
||||||
|
K 8
|
||||||
|
svn:date
|
||||||
|
V 27
|
||||||
|
2010-01-23T07:42:37.290694Z
|
||||||
|
PROPS-END
|
||||||
|
|
||||||
|
Node-path: branches
|
||||||
|
Node-kind: dir
|
||||||
|
Node-action: add
|
||||||
|
Prop-content-length: 10
|
||||||
|
Content-length: 10
|
||||||
|
|
||||||
|
PROPS-END
|
||||||
|
|
||||||
|
|
||||||
|
Node-path: branches/blue
|
||||||
|
Node-kind: dir
|
||||||
|
Node-action: add
|
||||||
|
Node-copyfrom-rev: 1
|
||||||
|
Node-copyfrom-path: trunk
|
||||||
|
|
||||||
|
|
||||||
|
Node-path: branches/green
|
||||||
|
Node-kind: dir
|
||||||
|
Node-action: add
|
||||||
|
Node-copyfrom-rev: 1
|
||||||
|
Node-copyfrom-path: trunk
|
||||||
|
|
||||||
|
|
||||||
|
Node-path: branches/red
|
||||||
|
Node-kind: dir
|
||||||
|
Node-action: add
|
||||||
|
Node-copyfrom-rev: 1
|
||||||
|
Node-copyfrom-path: trunk
|
||||||
|
|
||||||
|
|
||||||
|
Revision-number: 3
|
||||||
|
Prop-content-length: 108
|
||||||
|
Content-length: 108
|
||||||
|
|
||||||
|
K 7
|
||||||
|
svn:log
|
||||||
|
V 10
|
||||||
|
red change
|
||||||
|
K 10
|
||||||
|
svn:author
|
||||||
|
V 3
|
||||||
|
jay
|
||||||
|
K 8
|
||||||
|
svn:date
|
||||||
|
V 27
|
||||||
|
2010-01-23T07:43:02.208918Z
|
||||||
|
PROPS-END
|
||||||
|
|
||||||
|
Node-path: branches/red/foo
|
||||||
|
Node-kind: file
|
||||||
|
Node-action: change
|
||||||
|
Text-content-length: 8
|
||||||
|
Text-content-md5: 64c3c8cf7d0233ab7627623a68888bd1
|
||||||
|
Text-content-sha1: 95a0492027876adfd3891ec71ee37b79ee44d640
|
||||||
|
Content-length: 8
|
||||||
|
|
||||||
|
foo
|
||||||
|
red
|
||||||
|
|
||||||
|
|
||||||
|
Revision-number: 4
|
||||||
|
Prop-content-length: 110
|
||||||
|
Content-length: 110
|
||||||
|
|
||||||
|
K 7
|
||||||
|
svn:log
|
||||||
|
V 12
|
||||||
|
green change
|
||||||
|
K 10
|
||||||
|
svn:author
|
||||||
|
V 3
|
||||||
|
jay
|
||||||
|
K 8
|
||||||
|
svn:date
|
||||||
|
V 27
|
||||||
|
2010-01-23T07:43:15.746586Z
|
||||||
|
PROPS-END
|
||||||
|
|
||||||
|
Node-path: branches/green/foo
|
||||||
|
Node-kind: file
|
||||||
|
Node-action: change
|
||||||
|
Text-content-length: 10
|
||||||
|
Text-content-md5: 0209b6450891abc033d5eaaa9d3a8023
|
||||||
|
Text-content-sha1: 87fc3bef9faeec48c0cd61dfc9851db377fdccf7
|
||||||
|
Content-length: 10
|
||||||
|
|
||||||
|
foo
|
||||||
|
green
|
||||||
|
|
||||||
|
|
||||||
|
Revision-number: 5
|
||||||
|
Prop-content-length: 109
|
||||||
|
Content-length: 109
|
||||||
|
|
||||||
|
K 7
|
||||||
|
svn:log
|
||||||
|
V 11
|
||||||
|
blue change
|
||||||
|
K 10
|
||||||
|
svn:author
|
||||||
|
V 3
|
||||||
|
jay
|
||||||
|
K 8
|
||||||
|
svn:date
|
||||||
|
V 27
|
||||||
|
2010-01-23T07:43:29.364811Z
|
||||||
|
PROPS-END
|
||||||
|
|
||||||
|
Node-path: branches/blue/foo
|
||||||
|
Node-kind: file
|
||||||
|
Node-action: change
|
||||||
|
Text-content-length: 9
|
||||||
|
Text-content-md5: 9fbe4c13d0bae86386ae5209b2e6b275
|
||||||
|
Text-content-sha1: cc4575083459a16f9aaef796c4a2456d64691ba0
|
||||||
|
Content-length: 9
|
||||||
|
|
||||||
|
foo
|
||||||
|
blue
|
||||||
|
|
||||||
|
|
||||||
|
Revision-number: 6
|
||||||
|
Prop-content-length: 110
|
||||||
|
Content-length: 110
|
||||||
|
|
||||||
|
K 7
|
||||||
|
svn:log
|
||||||
|
V 12
|
||||||
|
trunk change
|
||||||
|
K 10
|
||||||
|
svn:author
|
||||||
|
V 3
|
||||||
|
jay
|
||||||
|
K 8
|
||||||
|
svn:date
|
||||||
|
V 27
|
||||||
|
2010-01-23T07:44:01.313130Z
|
||||||
|
PROPS-END
|
||||||
|
|
||||||
|
Node-path: trunk/foo
|
||||||
|
Node-kind: file
|
||||||
|
Node-action: change
|
||||||
|
Text-content-length: 10
|
||||||
|
Text-content-md5: 1c4db977d7a57c3bae582aab87948516
|
||||||
|
Text-content-sha1: 469c08df449e702cf2a1fe746244a9ef3f837fad
|
||||||
|
Content-length: 10
|
||||||
|
|
||||||
|
foo
|
||||||
|
trunk
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user