@matheusbsbs / matheus-bagliano / commits / 075762085c
Fork 0

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>

Jay Soffian committed Jan 23, 2010 at 03:30 UTC 075762085c6668f11c4ea165ecec17f69245ef09
4 files changed +320 -20
Documentation/git-svn.txt
+16
@@ -838,6 +838,22 @@ independent path component (surrounded by '/' or EOL). This
838 type of configuration is not automatically created by 'init' and
839 should be manually entered with a text-editor or using 'git config'.
840
841 +It is also possible to fetch a subset of branches or tags by using a
842 +comma-separated list of names within braces. For example:
843 +
844 +------------------------------------------------------------------------
845 +[svn-remote "huge-project"]
846 + url = http://server.org/svn
847 + fetch = trunk/src:refs/remotes/trunk
848 + branches = branches/{red,green}/src:refs/remotes/branches/*
849 + tags = tags/{1.0,2.0}/src:refs/remotes/tags/*
850 +------------------------------------------------------------------------
851 +
852 +Note that git-svn keeps track of the highest revision in which a branch
853 +or tag has appeared. If the subset of branches or tags is changed after
854 +fetching, then .git/svn/.metadata must be manually edited to remove (or
855 +reset) branches-maxRev and/or tags-maxRev as appropriate.
856 +
857 SEE ALSO
858 --------
859 linkgit:git-rebase[1]
git-svn.perl
+40 -20
@@ -1825,8 +1825,8 @@ sub read_all_remotes {
1825 my $rs = {
1826 t => $t,
1827 remote => $remote,
1828 - path => Git::SVN::GlobSpec->new($local_ref),
1829 - ref => Git::SVN::GlobSpec->new($remote_ref) };
1828 + path => Git::SVN::GlobSpec->new($local_ref, 1),
1829 + ref => Git::SVN::GlobSpec->new($remote_ref, 0) };
1830 if (length($rs->{ref}->{right}) != 0) {
1831 die "The '*' glob character must be the last ",
1832 "character of '$remote_ref'\n";
@@ -5233,6 +5233,7 @@ sub match_globs {
5233 next if (length $g->{path}->{right} &&
5234 ($self->check_path($p, $r) !=
5235 $SVN::Node::dir));
5236 + next unless $p =~ /$g->{path}->{regex}/;
5237 $exists->{$p} = Git::SVN->init($self->{url}, $p, undef,
5238 $g->{ref}->full_path($de), 1);
5239 }
@@ -6006,29 +6007,48 @@ use strict;
6007 use warnings;
6008
6009 sub new {
6009 - my ($class, $glob) = @_;
6010 + my ($class, $glob, $pattern_ok) = @_;
6011 my $re = $glob;
6012 $re =~ s!/+$!!g; # no need for trailing slashes
6012 - $re =~ m!^([^*]*)(\*(?:/\*)*)(.*)$!;
6013 - my $temp = $re;
6014 - my ($left, $right) = ($1, $3);
6015 - $re = $2;
6016 - my $depth = $re =~ tr/*/*/;
6017 - if ($depth != $temp =~ tr/*/*/) {
6018 - die "Only one set of wildcard directories " .
6019 - "(e.g. '*' or '*/*/*') is supported: '$glob'\n";
6013 + my (@left, @right, @patterns);
6014 + my $state = "left";
6015 + my $die_msg = "Only one set of wildcard directories " .
6016 + "(e.g. '*' or '*/*/*') is supported: '$glob'\n";
6017 + for my $part (split(m|/|, $glob)) {
6018 + if ($part =~ /\*/ && $part ne "*") {
6019 + die "Invalid pattern in '$glob': $part\n";
6020 + } elsif ($pattern_ok && $part =~ /[{}]/ &&
6021 + $part !~ /^\{[^{}]+\}/) {
6022 + die "Invalid pattern in '$glob': $part\n";
6023 + }
6024 + if ($part eq "*") {
6025 + die $die_msg if $state eq "right";
6026 + $state = "pattern";
6027 + push(@patterns, "[^/]*");
6028 + } elsif ($pattern_ok && $part =~ /^\{(.*)\}$/) {
6029 + die $die_msg if $state eq "right";
6030 + $state = "pattern";
6031 + my $p = quotemeta($1);
6032 + $p =~ s/\\,/|/g;
6033 + push(@patterns, "(?:$p)");
6034 + } else {
6035 + if ($state eq "left") {
6036 + push(@left, $part);
6037 + } else {
6038 + push(@right, $part);
6039 + $state = "right";
6040 + }
6041 + }
6042 }
6043 + my $depth = @patterns;
6044 if ($depth == 0) {
6022 - die "One '*' is needed for glob: '$glob'\n";
6023 - }
6024 - $re =~ s!\*!\[^/\]*!g;
6025 - $re = quotemeta($left) . "($re)" . quotemeta($right);
6026 - if (length $left && !($left =~ s!/+$!!g)) {
6027 - die "Missing trailing '/' on left side of: '$glob' ($left)\n";
6028 - }
6029 - if (length $right && !($right =~ s!^/+!!g)) {
6030 - die "Missing leading '/' on right side of: '$glob' ($right)\n";
6045 + die "One '*' is needed in glob: '$glob'\n";
6046 }
6047 + my $left = join('/', @left);
6048 + my $right = join('/', @right);
6049 + $re = join('/', @patterns);
6050 + $re = join('\/',
6051 + grep(length, quotemeta($left), "($re)", quotemeta($right)));
6052 my $left_re = qr/^\/\Q$left\E(\/|$)/;
6053 bless { left => $left, right => $right, left_regex => $left_re,
6054 regex => qr/$re/, glob => $glob, depth => $depth }, $class;
t/t9154-git-svn-fancy-glob.sh new
+42
@@ -0,0 +1,42 @@
1 +#!/bin/sh
2 +#
3 +# Copyright (c) 2010 Jay Soffian
4 +#
5 +
6 +test_description='git svn fancy glob test'
7 +
8 +. ./lib-git-svn.sh
9 +
10 +test_expect_success 'load svn repo' "
11 + svnadmin load -q '$rawsvnrepo' < '$TEST_DIRECTORY/t9154/svn.dump' &&
12 + git svn init --minimize-url -T trunk '$svnrepo' &&
13 + git svn fetch
14 + "
15 +
16 +test_expect_success 'add red branch' "
17 + git config svn-remote.svn.branches 'branches/{red}:refs/remotes/*' &&
18 + git svn fetch &&
19 + git rev-parse refs/remotes/red &&
20 + test_must_fail git rev-parse refs/remotes/green &&
21 + test_must_fail git rev-parse refs/remotes/blue
22 + "
23 +
24 +test_expect_success 'add green branch' "
25 + GIT_CONFIG=.git/svn/.metadata git config --unset svn-remote.svn.branches-maxRev &&
26 + git config svn-remote.svn.branches 'branches/{red,green}:refs/remotes/*' &&
27 + git svn fetch &&
28 + git rev-parse refs/remotes/red &&
29 + git rev-parse refs/remotes/green &&
30 + test_must_fail git rev-parse refs/remotes/blue
31 + "
32 +
33 +test_expect_success 'add all branches' "
34 + GIT_CONFIG=.git/svn/.metadata git config --unset svn-remote.svn.branches-maxRev &&
35 + git config svn-remote.svn.branches 'branches/*:refs/remotes/*' &&
36 + git svn fetch &&
37 + git rev-parse refs/remotes/red &&
38 + git rev-parse refs/remotes/green &&
39 + git rev-parse refs/remotes/blue
40 + "
41 +
42 +test_done
t/t9154/svn.dump new
+222
@@ -0,0 +1,222 @@
1 +SVN-fs-dump-format-version: 2
2 +
3 +UUID: a18093a0-5f0b-44e0-8d88-8911ac7078db
4 +
5 +Revision-number: 0
6 +Prop-content-length: 56
7 +Content-length: 56
8 +
9 +K 8
10 +svn:date
11 +V 27
12 +2010-01-23T07:40:25.660053Z
13 +PROPS-END
14 +
15 +Revision-number: 1
16 +Prop-content-length: 104
17 +Content-length: 104
18 +
19 +K 7
20 +svn:log
21 +V 7
22 +initial
23 +K 10
24 +svn:author
25 +V 3
26 +jay
27 +K 8
28 +svn:date
29 +V 27
30 +2010-01-23T07:41:33.636365Z
31 +PROPS-END
32 +
33 +Node-path: trunk
34 +Node-kind: dir
35 +Node-action: add
36 +Prop-content-length: 10
37 +Content-length: 10
38 +
39 +PROPS-END
40 +
41 +
42 +Node-path: trunk/foo
43 +Node-kind: file
44 +Node-action: add
45 +Prop-content-length: 10
46 +Text-content-length: 4
47 +Text-content-md5: d3b07384d113edec49eaa6238ad5ff00
48 +Text-content-sha1: f1d2d2f924e986ac86fdf7b36c94bcdf32beec15
49 +Content-length: 14
50 +
51 +PROPS-END
52 +foo
53 +
54 +
55 +Revision-number: 2
56 +Prop-content-length: 110
57 +Content-length: 110
58 +
59 +K 7
60 +svn:log
61 +V 12
62 +add branches
63 +K 10
64 +svn:author
65 +V 3
66 +jay
67 +K 8
68 +svn:date
69 +V 27
70 +2010-01-23T07:42:37.290694Z
71 +PROPS-END
72 +
73 +Node-path: branches
74 +Node-kind: dir
75 +Node-action: add
76 +Prop-content-length: 10
77 +Content-length: 10
78 +
79 +PROPS-END
80 +
81 +
82 +Node-path: branches/blue
83 +Node-kind: dir
84 +Node-action: add
85 +Node-copyfrom-rev: 1
86 +Node-copyfrom-path: trunk
87 +
88 +
89 +Node-path: branches/green
90 +Node-kind: dir
91 +Node-action: add
92 +Node-copyfrom-rev: 1
93 +Node-copyfrom-path: trunk
94 +
95 +
96 +Node-path: branches/red
97 +Node-kind: dir
98 +Node-action: add
99 +Node-copyfrom-rev: 1
100 +Node-copyfrom-path: trunk
101 +
102 +
103 +Revision-number: 3
104 +Prop-content-length: 108
105 +Content-length: 108
106 +
107 +K 7
108 +svn:log
109 +V 10
110 +red change
111 +K 10
112 +svn:author
113 +V 3
114 +jay
115 +K 8
116 +svn:date
117 +V 27
118 +2010-01-23T07:43:02.208918Z
119 +PROPS-END
120 +
121 +Node-path: branches/red/foo
122 +Node-kind: file
123 +Node-action: change
124 +Text-content-length: 8
125 +Text-content-md5: 64c3c8cf7d0233ab7627623a68888bd1
126 +Text-content-sha1: 95a0492027876adfd3891ec71ee37b79ee44d640
127 +Content-length: 8
128 +
129 +foo
130 +red
131 +
132 +
133 +Revision-number: 4
134 +Prop-content-length: 110
135 +Content-length: 110
136 +
137 +K 7
138 +svn:log
139 +V 12
140 +green change
141 +K 10
142 +svn:author
143 +V 3
144 +jay
145 +K 8
146 +svn:date
147 +V 27
148 +2010-01-23T07:43:15.746586Z
149 +PROPS-END
150 +
151 +Node-path: branches/green/foo
152 +Node-kind: file
153 +Node-action: change
154 +Text-content-length: 10
155 +Text-content-md5: 0209b6450891abc033d5eaaa9d3a8023
156 +Text-content-sha1: 87fc3bef9faeec48c0cd61dfc9851db377fdccf7
157 +Content-length: 10
158 +
159 +foo
160 +green
161 +
162 +
163 +Revision-number: 5
164 +Prop-content-length: 109
165 +Content-length: 109
166 +
167 +K 7
168 +svn:log
169 +V 11
170 +blue change
171 +K 10
172 +svn:author
173 +V 3
174 +jay
175 +K 8
176 +svn:date
177 +V 27
178 +2010-01-23T07:43:29.364811Z
179 +PROPS-END
180 +
181 +Node-path: branches/blue/foo
182 +Node-kind: file
183 +Node-action: change
184 +Text-content-length: 9
185 +Text-content-md5: 9fbe4c13d0bae86386ae5209b2e6b275
186 +Text-content-sha1: cc4575083459a16f9aaef796c4a2456d64691ba0
187 +Content-length: 9
188 +
189 +foo
190 +blue
191 +
192 +
193 +Revision-number: 6
194 +Prop-content-length: 110
195 +Content-length: 110
196 +
197 +K 7
198 +svn:log
199 +V 12
200 +trunk change
201 +K 10
202 +svn:author
203 +V 3
204 +jay
205 +K 8
206 +svn:date
207 +V 27
208 +2010-01-23T07:44:01.313130Z
209 +PROPS-END
210 +
211 +Node-path: trunk/foo
212 +Node-kind: file
213 +Node-action: change
214 +Text-content-length: 10
215 +Text-content-md5: 1c4db977d7a57c3bae582aab87948516
216 +Text-content-sha1: 469c08df449e702cf2a1fe746244a9ef3f837fad
217 +Content-length: 10
218 +
219 +foo
220 +trunk
221 +
222 +