* [PATCH 1/3] Fix multi-glob assertion in git-svn
2008-08-08 8:40 ` [PATCH v2 0/2] git-svn multi-glob fix and extension Eric Wong
@ 2008-08-08 8:41 ` Eric Wong
2008-08-08 9:41 ` Junio C Hamano
2008-08-08 8:41 ` [PATCH 2/3] git-svn: Allow deep branch names by supporting multi-globs Eric Wong
` (3 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Eric Wong @ 2008-08-08 8:41 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Marcus Griep
From: Marcus Griep <marcus@griep.us>
Fixes bad regex match check for multiple globs (would always return
one glob regardless of actual number).
[ew: fixed a bashism in the test and some minor line-wrapping]
Signed-off-by: Marcus Griep <marcus@griep.us>
Acked-by: Eric Wong <normalperson@yhbt.net>
---
git-svn.perl | 5 +++--
t/t9108-git-svn-glob.sh | 21 +++++++++++++++++++++
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/git-svn.perl b/git-svn.perl
index 06a82c8..503a7c9 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -4915,14 +4915,15 @@ sub new {
my ($class, $glob) = @_;
my $re = $glob;
$re =~ s!/+$!!g; # no need for trailing slashes
- my $nr = ($re =~ s!^(.*)\*(.*)$!\(\[^/\]+\)!g);
- my ($left, $right) = ($1, $2);
+ my $nr = $re =~ tr/*/*/;
if ($nr > 1) {
die "Only one '*' wildcard expansion ",
"is supported (got $nr): '$glob'\n";
} elsif ($nr == 0) {
die "One '*' is needed for glob: '$glob'\n";
}
+ $re =~ s!^(.*)\*(.*)$!\(\[^/\]+\)!g;
+ my ($left, $right) = ($1, $2);
$re = quotemeta($left) . $re . quotemeta($right);
if (length $left && !($left =~ s!/+$!!g)) {
die "Missing trailing '/' on left side of: '$glob' ($left)\n";
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index f6f71d0..a6f88bd 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -83,4 +83,25 @@ test_expect_success 'test left-hand-side only globbing' '
cmp expect.two output.two
'
+echo "Only one '*' wildcard expansion is supported (got 2): 'branches/*/*'" \
+ > expect.three
+echo "" >> expect.three
+
+test_expect_success 'test disallow multi-globs' '
+ git config --add svn-remote.three.url "$svnrepo" &&
+ git config --add svn-remote.three.fetch \
+ trunk:refs/remotes/three/trunk &&
+ git config --add svn-remote.three.branches \
+ "branches/*/*:refs/remotes/three/branches/*" &&
+ git config --add svn-remote.three.tags \
+ "tags/*/*:refs/remotes/three/tags/*" &&
+ cd tmp &&
+ echo "try try" >> tags/end/src/b/readme &&
+ poke tags/end/src/b/readme &&
+ svn commit -m "try to try"
+ cd .. &&
+ test_must_fail git-svn fetch three 2> stderr.three &&
+ cmp expect.three stderr.three
+ '
+
test_done
--
1.6.0.rc2.4.g0643f
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Fix multi-glob assertion in git-svn
2008-08-08 8:41 ` [PATCH 1/3] Fix multi-glob assertion in git-svn Eric Wong
@ 2008-08-08 9:41 ` Junio C Hamano
2008-08-09 7:28 ` Eric Wong
0 siblings, 1 reply; 14+ messages in thread
From: Junio C Hamano @ 2008-08-08 9:41 UTC (permalink / raw)
To: Eric Wong; +Cc: git, Marcus Griep
Eric Wong <normalperson@yhbt.net> writes:
> From: Marcus Griep <marcus@griep.us>
>
> Fixes bad regex match check for multiple globs (would always return
> one glob regardless of actual number).
>
> [ew: fixed a bashism in the test and some minor line-wrapping]
Thanks both.
> +test_expect_success 'test disallow multi-globs' '
> ...
> + cd tmp &&
> + echo "try try" >> tags/end/src/b/readme &&
> + poke tags/end/src/b/readme &&
> + svn commit -m "try to try"
> + cd .. &&
Do you want to ignore exit code from 'svn commit -m' here?
In any case, I'd want to see "temporarily work in subdirectory" done in a
subshell when applicable, so that we won't have to worry about where we
are when we later add more tests, like this:
(
cd tmp &&
echo "try try" >>tags/end/src/b/readme &&
poke tags/end/src/b/readme &&
svn commit -m "try to try" &&
) &&
> + test_must_fail git-svn fetch three 2> stderr.three &&
> + cmp expect.three stderr.three
s/cmp/test_cmp/;
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Fix multi-glob assertion in git-svn
2008-08-08 9:41 ` Junio C Hamano
@ 2008-08-09 7:28 ` Eric Wong
2008-08-09 7:48 ` Junio C Hamano
0 siblings, 1 reply; 14+ messages in thread
From: Eric Wong @ 2008-08-09 7:28 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Marcus Griep
Junio C Hamano <gitster@pobox.com> wrote:
> Eric Wong <normalperson@yhbt.net> writes:
>
> > From: Marcus Griep <marcus@griep.us>
> >
> > Fixes bad regex match check for multiple globs (would always return
> > one glob regardless of actual number).
> >
> > [ew: fixed a bashism in the test and some minor line-wrapping]
>
> Thanks both.
>
> > +test_expect_success 'test disallow multi-globs' '
> > ...
> > + cd tmp &&
> > + echo "try try" >> tags/end/src/b/readme &&
> > + poke tags/end/src/b/readme &&
> > + svn commit -m "try to try"
> > + cd .. &&
>
> Do you want to ignore exit code from 'svn commit -m' here?
Oops, no missed that.
> In any case, I'd want to see "temporarily work in subdirectory" done in a
> subshell when applicable, so that we won't have to worry about where we
> are when we later add more tests, like this:
>
> (
> cd tmp &&
> echo "try try" >>tags/end/src/b/readme &&
> poke tags/end/src/b/readme &&
> svn commit -m "try to try" &&
> ) &&
Yes, that's a good idea
> > + test_must_fail git-svn fetch three 2> stderr.three &&
> > + cmp expect.three stderr.three
>
> s/cmp/test_cmp/;
Noted.
Shall I make those changes and resubmit or are they simple enough
for you to do?
--
Eric Wong
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/3] git-svn: Allow deep branch names by supporting multi-globs
2008-08-08 8:40 ` [PATCH v2 0/2] git-svn multi-glob fix and extension Eric Wong
2008-08-08 8:41 ` [PATCH 1/3] Fix multi-glob assertion in git-svn Eric Wong
@ 2008-08-08 8:41 ` Eric Wong
2008-08-08 8:41 ` [PATCH 3/3] git-svn: wrap long lines in a few places Eric Wong
` (2 subsequent siblings)
4 siblings, 0 replies; 14+ messages in thread
From: Eric Wong @ 2008-08-08 8:41 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Marcus Griep
From: Marcus Griep <marcus@griep.us>
Some repositories use a deep branching strategy, such as:
branches/1.0/1.0.rc1
branches/1.0/1.0.rc2
branches/1.0/1.0.rtm
branches/1.0/1.0.gold
Only allowing a single glob stiffles this.
This change allows for a single glob 'set' to accept this deep
branching strategy.
The ref glob depth must match the branch glob depth. When using
the -b or -t options for init or clone, this is automatically
done.
For example, using the above branches:
svn-remote.svn.branches = branches/*/*:refs/remote/*/*
gives the following branch names:
1.0/1.0.rc1
1.0/1.0.rc2
1.0/1.0.rtm
1.0/1.0.gold
[ew:
* removed unrelated line-wrapping changes
* fixed line-wrapping in a few more places
* removed trailing whitespace
* fixed bashism in test
* removed unnecessary httpd startup in test
* changed copyright on tests to 2008 Marcus Griep
* added executable permissions to new tests
]
Signed-off-by: Marcus Griep <marcus@griep.us>
Acked-by: Eric Wong <normalperson@yhbt.net>
---
git-svn.perl | 61 ++++++++---
t/t9108-git-svn-glob.sh | 9 +-
t/t9108-git-svn-multi-glob.sh | 157 ++++++++++++++++++++++++++++
t/t9125-git-svn-multi-glob-branch-names.sh | 37 +++++++
4 files changed, 244 insertions(+), 20 deletions(-)
create mode 100755 t/t9108-git-svn-multi-glob.sh
create mode 100755 t/t9125-git-svn-multi-glob-branch-names.sh
diff --git a/git-svn.perl b/git-svn.perl
index 503a7c9..47ad378 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -987,8 +987,10 @@ sub complete_url_ls_init {
if (length $pfx && $pfx !~ m#/$#) {
die "--prefix='$pfx' must have a trailing slash '/'\n";
}
- command_noisy('config', "svn-remote.$gs->{repo_id}.$n",
- "$remote_path:refs/remotes/$pfx*");
+ command_noisy('config',
+ "svn-remote.$gs->{repo_id}.$n",
+ "$remote_path:refs/remotes/$pfx*" .
+ ('/*' x (($remote_path =~ tr/*/*/) - 1)) );
}
sub verify_ref {
@@ -4124,16 +4126,38 @@ sub gs_fetch_loop_common {
Git::SVN::gc();
}
+sub get_dir_globbed {
+ my ($self, $left, $depth, $r) = @_;
+
+ my @x = eval { $self->get_dir($left, $r) };
+ return unless scalar @x == 3;
+ my $dirents = $x[0];
+ my @finalents;
+ foreach my $de (keys %$dirents) {
+ next if $dirents->{$de}->{kind} != $SVN::Node::dir;
+ if ($depth > 1) {
+ my @args = ("$left/$de", $depth - 1, $r);
+ foreach my $dir ($self->get_dir_globbed(@args)) {
+ push @finalents, "$de/$dir";
+ }
+ } else {
+ push @finalents, $de;
+ }
+ }
+ @finalents;
+}
+
sub match_globs {
my ($self, $exists, $paths, $globs, $r) = @_;
sub get_dir_check {
my ($self, $exists, $g, $r) = @_;
- my @x = eval { $self->get_dir($g->{path}->{left}, $r) };
- return unless scalar @x == 3;
- my $dirents = $x[0];
- foreach my $de (keys %$dirents) {
- next if $dirents->{$de}->{kind} != $SVN::Node::dir;
+
+ my @dirs = $self->get_dir_globbed($g->{path}->{left},
+ $g->{path}->{depth},
+ $r);
+
+ foreach my $de (@dirs) {
my $p = $g->{path}->full_path($de);
next if $exists->{$p};
next if (length $g->{path}->{right} &&
@@ -4915,16 +4939,21 @@ sub new {
my ($class, $glob) = @_;
my $re = $glob;
$re =~ s!/+$!!g; # no need for trailing slashes
- my $nr = $re =~ tr/*/*/;
- if ($nr > 1) {
- die "Only one '*' wildcard expansion ",
- "is supported (got $nr): '$glob'\n";
- } elsif ($nr == 0) {
+ $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";
+ }
+ if ($depth == 0) {
die "One '*' is needed for glob: '$glob'\n";
}
- $re =~ s!^(.*)\*(.*)$!\(\[^/\]+\)!g;
- my ($left, $right) = ($1, $2);
- $re = quotemeta($left) . $re . quotemeta($right);
+ $re =~ s!\*!\[^/\]*!g;
+# $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";
}
@@ -4933,7 +4962,7 @@ sub new {
}
my $left_re = qr/^\/\Q$left\E(\/|$)/;
bless { left => $left, right => $right, left_regex => $left_re,
- regex => qr/$re/, glob => $glob }, $class;
+ regex => qr/$re/, glob => $glob, depth => $depth }, $class;
}
sub full_path {
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index a6f88bd..bb9df56 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -52,7 +52,8 @@ test_expect_success 'test refspec globbing' '
test "`git rev-parse refs/remotes/tags/end~1`" = \
"`git rev-parse refs/remotes/branches/start`" &&
test "`git rev-parse refs/remotes/branches/start~2`" = \
- "`git rev-parse refs/remotes/trunk`"
+ "`git rev-parse refs/remotes/trunk`" &&
+ test_must_fail git rev-parse refs/remotes/tags/end@3
'
echo try to try > expect.two
@@ -83,8 +84,8 @@ test_expect_success 'test left-hand-side only globbing' '
cmp expect.two output.two
'
-echo "Only one '*' wildcard expansion is supported (got 2): 'branches/*/*'" \
- > expect.three
+echo "Only one set of wildcard directories" \
+ "(e.g. '*' or '*/*/*') is supported: 'branches/*/t/*'" > expect.three
echo "" >> expect.three
test_expect_success 'test disallow multi-globs' '
@@ -92,7 +93,7 @@ test_expect_success 'test disallow multi-globs' '
git config --add svn-remote.three.fetch \
trunk:refs/remotes/three/trunk &&
git config --add svn-remote.three.branches \
- "branches/*/*:refs/remotes/three/branches/*" &&
+ "branches/*/t/*:refs/remotes/three/branches/*" &&
git config --add svn-remote.three.tags \
"tags/*/*:refs/remotes/three/tags/*" &&
cd tmp &&
diff --git a/t/t9108-git-svn-multi-glob.sh b/t/t9108-git-svn-multi-glob.sh
new file mode 100755
index 0000000..9fb51d6
--- /dev/null
+++ b/t/t9108-git-svn-multi-glob.sh
@@ -0,0 +1,157 @@
+#!/bin/sh
+# Copyright (c) 2007 Eric Wong
+test_description='git-svn globbing refspecs'
+. ./lib-git-svn.sh
+
+cat > expect.end <<EOF
+the end
+hi
+start a new branch
+initial
+EOF
+
+test_expect_success 'test refspec globbing' '
+ mkdir -p trunk/src/a trunk/src/b trunk/doc &&
+ echo "hello world" > trunk/src/a/readme &&
+ echo "goodbye world" > trunk/src/b/readme &&
+ svn import -m "initial" trunk "$svnrepo"/trunk &&
+ svn co "$svnrepo" tmp &&
+ cd tmp &&
+ mkdir branches branches/v1 tags &&
+ svn add branches tags &&
+ svn cp trunk branches/v1/start &&
+ svn commit -m "start a new branch" &&
+ svn up &&
+ echo "hi" >> branches/v1/start/src/b/readme &&
+ poke branches/v1/start/src/b/readme &&
+ echo "hey" >> branches/v1/start/src/a/readme &&
+ poke branches/v1/start/src/a/readme &&
+ svn commit -m "hi" &&
+ svn up &&
+ svn cp branches/v1/start tags/end &&
+ echo "bye" >> tags/end/src/b/readme &&
+ poke tags/end/src/b/readme &&
+ echo "aye" >> tags/end/src/a/readme &&
+ poke tags/end/src/a/readme &&
+ svn commit -m "the end" &&
+ echo "byebye" >> tags/end/src/b/readme &&
+ poke tags/end/src/b/readme &&
+ svn commit -m "nothing to see here"
+ cd .. &&
+ git config --add svn-remote.svn.url "$svnrepo" &&
+ git config --add svn-remote.svn.fetch \
+ "trunk/src/a:refs/remotes/trunk" &&
+ git config --add svn-remote.svn.branches \
+ "branches/*/*/src/a:refs/remotes/branches/*/*" &&
+ git config --add svn-remote.svn.tags\
+ "tags/*/src/a:refs/remotes/tags/*" &&
+ git-svn multi-fetch &&
+ git log --pretty=oneline refs/remotes/tags/end | \
+ sed -e "s/^.\{41\}//" > output.end &&
+ cmp expect.end output.end &&
+ test "`git rev-parse refs/remotes/tags/end~1`" = \
+ "`git rev-parse refs/remotes/branches/v1/start`" &&
+ test "`git rev-parse refs/remotes/branches/v1/start~2`" = \
+ "`git rev-parse refs/remotes/trunk`" &&
+ test_must_fail git rev-parse refs/remotes/tags/end@3
+ '
+
+echo try to try > expect.two
+echo nothing to see here >> expect.two
+cat expect.end >> expect.two
+
+test_expect_success 'test left-hand-side only globbing' '
+ git config --add svn-remote.two.url "$svnrepo" &&
+ git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk &&
+ git config --add svn-remote.two.branches \
+ "branches/*/*:refs/remotes/two/branches/*/*" &&
+ git config --add svn-remote.two.tags \
+ "tags/*:refs/remotes/two/tags/*" &&
+ cd tmp &&
+ echo "try try" >> tags/end/src/b/readme &&
+ poke tags/end/src/b/readme &&
+ svn commit -m "try to try"
+ cd .. &&
+ git-svn fetch two &&
+ test `git rev-list refs/remotes/two/tags/end | wc -l` -eq 6 &&
+ test `git rev-list refs/remotes/two/branches/v1/start | wc -l` -eq 3 &&
+ test `git rev-parse refs/remotes/two/branches/v1/start~2` = \
+ `git rev-parse refs/remotes/two/trunk` &&
+ test `git rev-parse refs/remotes/two/tags/end~3` = \
+ `git rev-parse refs/remotes/two/branches/v1/start` &&
+ git log --pretty=oneline refs/remotes/two/tags/end | \
+ sed -e "s/^.\{41\}//" > output.two &&
+ cmp expect.two output.two
+ '
+cat > expect.four <<EOF
+adios
+adding more
+Changed 2 in v2/start
+Another versioned branch
+initial
+EOF
+
+test_expect_success 'test another branch' '
+ (
+ cd tmp &&
+ mkdir branches/v2 &&
+ svn add branches/v2 &&
+ svn cp trunk branches/v2/start &&
+ svn commit -m "Another versioned branch" &&
+ svn up &&
+ echo "hello" >> branches/v2/start/src/b/readme &&
+ poke branches/v2/start/src/b/readme &&
+ echo "howdy" >> branches/v2/start/src/a/readme &&
+ poke branches/v2/start/src/a/readme &&
+ svn commit -m "Changed 2 in v2/start" &&
+ svn up &&
+ svn cp branches/v2/start tags/next &&
+ echo "bye" >> tags/next/src/b/readme &&
+ poke tags/next/src/b/readme &&
+ echo "aye" >> tags/next/src/a/readme &&
+ poke tags/next/src/a/readme &&
+ svn commit -m "adding more" &&
+ echo "byebye" >> tags/next/src/b/readme &&
+ poke tags/next/src/b/readme &&
+ svn commit -m "adios"
+ ) &&
+ git config --add svn-remote.four.url "$svnrepo" &&
+ git config --add svn-remote.four.fetch trunk:refs/remotes/four/trunk &&
+ git config --add svn-remote.four.branches \
+ "branches/*/*:refs/remotes/four/branches/*/*" &&
+ git config --add svn-remote.four.tags \
+ "tags/*:refs/remotes/four/tags/*" &&
+ git-svn fetch four &&
+ test `git rev-list refs/remotes/four/tags/next | wc -l` -eq 5 &&
+ test `git rev-list refs/remotes/four/branches/v2/start | wc -l` -eq 3 &&
+ test `git rev-parse refs/remotes/four/branches/v2/start~2` = \
+ `git rev-parse refs/remotes/four/trunk` &&
+ test `git rev-parse refs/remotes/four/tags/next~2` = \
+ `git rev-parse refs/remotes/four/branches/v2/start` &&
+ git log --pretty=oneline refs/remotes/four/tags/next | \
+ sed -e "s/^.\{41\}//" > output.four &&
+ cmp expect.four output.four
+ '
+
+echo "Only one set of wildcard directories" \
+ "(e.g. '*' or '*/*/*') is supported: 'branches/*/t/*'" > expect.three
+echo "" >> expect.three
+
+test_expect_success 'test disallow multiple globs' '
+ git config --add svn-remote.three.url "$svnrepo" &&
+ git config --add svn-remote.three.fetch \
+ trunk:refs/remotes/three/trunk &&
+ git config --add svn-remote.three.branches \
+ "branches/*/t/*:refs/remotes/three/branches/*/*" &&
+ git config --add svn-remote.three.tags \
+ "tags/*:refs/remotes/three/tags/*" &&
+ cd tmp &&
+ echo "try try" >> tags/end/src/b/readme &&
+ poke tags/end/src/b/readme &&
+ svn commit -m "try to try"
+ cd .. &&
+ test_must_fail git-svn fetch three 2> stderr.three &&
+ cmp expect.three stderr.three
+ '
+
+test_done
diff --git a/t/t9125-git-svn-multi-glob-branch-names.sh b/t/t9125-git-svn-multi-glob-branch-names.sh
new file mode 100755
index 0000000..6b62b52
--- /dev/null
+++ b/t/t9125-git-svn-multi-glob-branch-names.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+# Copyright (c) 2008 Marcus Griep
+
+test_description='git-svn multi-glob branch names'
+. ./lib-git-svn.sh
+
+test_expect_success 'setup svnrepo' '
+ mkdir project project/trunk project/branches \
+ project/branches/v14.1 project/tags &&
+ echo foo > project/trunk/foo &&
+ svn import -m "$test_description" project "$svnrepo/project" &&
+ rm -rf project &&
+ svn cp -m "fun" "$svnrepo/project/trunk" \
+ "$svnrepo/project/branches/v14.1/beta" &&
+ svn cp -m "more fun!" "$svnrepo/project/branches/v14.1/beta" \
+ "$svnrepo/project/branches/v14.1/gold"
+ '
+
+test_expect_success 'test clone with multi-glob in branch names' '
+ git svn clone -T trunk -b branches/*/* -t tags \
+ "$svnrepo/project" project &&
+ cd project &&
+ git rev-parse "refs/remotes/v14.1/beta" &&
+ git rev-parse "refs/remotes/v14.1/gold" &&
+ cd ..
+ '
+
+test_expect_success 'test dcommit to multi-globbed branch' "
+ cd project &&
+ git reset --hard 'refs/remotes/v14.1/gold' &&
+ echo hello >> foo &&
+ git commit -m 'hello' -- foo &&
+ git svn dcommit &&
+ cd ..
+ "
+
+test_done
--
1.6.0.rc2.4.g0643f
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/3] git-svn: wrap long lines in a few places
2008-08-08 8:40 ` [PATCH v2 0/2] git-svn multi-glob fix and extension Eric Wong
2008-08-08 8:41 ` [PATCH 1/3] Fix multi-glob assertion in git-svn Eric Wong
2008-08-08 8:41 ` [PATCH 2/3] git-svn: Allow deep branch names by supporting multi-globs Eric Wong
@ 2008-08-08 8:41 ` Eric Wong
2008-08-08 8:56 ` [PATCH 1/3] Fix multi-glob assertion in git-svn Eric Wong
2008-08-08 8:57 ` [PATCH 2/3] git-svn: Allow deep branch names by supporting multi-globs Eric Wong
4 siblings, 0 replies; 14+ messages in thread
From: Eric Wong @ 2008-08-08 8:41 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Marcus Griep, Eric Wong
Oops, I let a few patches slip by with long lines in them.
Extracted from an unrelated patch by: Marcus Griep <marcus@griep.us>
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
git-svn.perl | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/git-svn.perl b/git-svn.perl
index 47ad378..d7a884d 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -171,7 +171,8 @@ my %cmd = (
'color' => \$Git::SVN::Log::color,
'pager=s' => \$Git::SVN::Log::pager
} ],
- 'find-rev' => [ \&cmd_find_rev, "Translate between SVN revision numbers and tree-ish",
+ 'find-rev' => [ \&cmd_find_rev,
+ "Translate between SVN revision numbers and tree-ish",
{} ],
'rebase' => [ \&cmd_rebase, "Fetch and rebase your working directory",
{ 'merge|m|M' => \$_merge,
@@ -231,7 +232,9 @@ unless ($cmd && $cmd =~ /(?:clone|init|multi-init)$/) {
my %opts = %{$cmd{$cmd}->[2]} if (defined $cmd);
read_repo_config(\%opts);
-Getopt::Long::Configure('pass_through') if ($cmd && ($cmd eq 'log' || $cmd eq 'blame'));
+if ($cmd && ($cmd eq 'log' || $cmd eq 'blame')) {
+ Getopt::Long::Configure('pass_through');
+}
my $rv = GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version,
'minimize-connections' => \$Git::SVN::Migration::_minimize,
'id|i=s' => \$Git::SVN::default_ref_id,
--
1.6.0.rc2.4.g0643f
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 1/3] Fix multi-glob assertion in git-svn
2008-08-08 8:40 ` [PATCH v2 0/2] git-svn multi-glob fix and extension Eric Wong
` (2 preceding siblings ...)
2008-08-08 8:41 ` [PATCH 3/3] git-svn: wrap long lines in a few places Eric Wong
@ 2008-08-08 8:56 ` Eric Wong
2008-08-08 8:57 ` [PATCH 2/3] git-svn: Allow deep branch names by supporting multi-globs Eric Wong
4 siblings, 0 replies; 14+ messages in thread
From: Eric Wong @ 2008-08-08 8:56 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List, Marcus Griep
From: Marcus Griep <marcus@griep.us>
Date: Thu, 7 Aug 2008 11:34:01 -0400
Subject: [PATCH 1/3] Fix multi-glob assertion in git-svn
Fixes bad regex match check for multiple globs (would always return
one glob regardless of actual number).
[ew: fixed a bashism in the test and some minor line-wrapping]
Signed-off-by: Marcus Griep <marcus@griep.us>
Acked-by: Eric Wong <normalperson@yhbt.net>
---
Oops, resent as I forgot to change the From: header
git-svn.perl | 5 +++--
t/t9108-git-svn-glob.sh | 21 +++++++++++++++++++++
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/git-svn.perl b/git-svn.perl
index 06a82c8..503a7c9 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -4915,14 +4915,15 @@ sub new {
my ($class, $glob) = @_;
my $re = $glob;
$re =~ s!/+$!!g; # no need for trailing slashes
- my $nr = ($re =~ s!^(.*)\*(.*)$!\(\[^/\]+\)!g);
- my ($left, $right) = ($1, $2);
+ my $nr = $re =~ tr/*/*/;
if ($nr > 1) {
die "Only one '*' wildcard expansion ",
"is supported (got $nr): '$glob'\n";
} elsif ($nr == 0) {
die "One '*' is needed for glob: '$glob'\n";
}
+ $re =~ s!^(.*)\*(.*)$!\(\[^/\]+\)!g;
+ my ($left, $right) = ($1, $2);
$re = quotemeta($left) . $re . quotemeta($right);
if (length $left && !($left =~ s!/+$!!g)) {
die "Missing trailing '/' on left side of: '$glob' ($left)\n";
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index f6f71d0..a6f88bd 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -83,4 +83,25 @@ test_expect_success 'test left-hand-side only globbing' '
cmp expect.two output.two
'
+echo "Only one '*' wildcard expansion is supported (got 2): 'branches/*/*'" \
+ > expect.three
+echo "" >> expect.three
+
+test_expect_success 'test disallow multi-globs' '
+ git config --add svn-remote.three.url "$svnrepo" &&
+ git config --add svn-remote.three.fetch \
+ trunk:refs/remotes/three/trunk &&
+ git config --add svn-remote.three.branches \
+ "branches/*/*:refs/remotes/three/branches/*" &&
+ git config --add svn-remote.three.tags \
+ "tags/*/*:refs/remotes/three/tags/*" &&
+ cd tmp &&
+ echo "try try" >> tags/end/src/b/readme &&
+ poke tags/end/src/b/readme &&
+ svn commit -m "try to try"
+ cd .. &&
+ test_must_fail git-svn fetch three 2> stderr.three &&
+ cmp expect.three stderr.three
+ '
+
test_done
--
1.6.0.rc2.4.g0643f
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/3] git-svn: Allow deep branch names by supporting multi-globs
2008-08-08 8:40 ` [PATCH v2 0/2] git-svn multi-glob fix and extension Eric Wong
` (3 preceding siblings ...)
2008-08-08 8:56 ` [PATCH 1/3] Fix multi-glob assertion in git-svn Eric Wong
@ 2008-08-08 8:57 ` Eric Wong
4 siblings, 0 replies; 14+ messages in thread
From: Eric Wong @ 2008-08-08 8:57 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List, Marcus Griep
From: Marcus Griep <marcus@griep.us>
Date: Thu, 7 Aug 2008 11:34:02 -0400
Subject: [PATCH 2/3] git-svn: Allow deep branch names by supporting multi-globs
Some repositories use a deep branching strategy, such as:
branches/1.0/1.0.rc1
branches/1.0/1.0.rc2
branches/1.0/1.0.rtm
branches/1.0/1.0.gold
Only allowing a single glob stiffles this.
This change allows for a single glob 'set' to accept this deep
branching strategy.
The ref glob depth must match the branch glob depth. When using
the -b or -t options for init or clone, this is automatically
done.
For example, using the above branches:
svn-remote.svn.branches = branches/*/*:refs/remote/*/*
gives the following branch names:
1.0/1.0.rc1
1.0/1.0.rc2
1.0/1.0.rtm
1.0/1.0.gold
[ew:
* removed unrelated line-wrapping changes
* fixed line-wrapping in a few more places
* removed trailing whitespace
* fixed bashism in test
* removed unnecessary httpd startup in test
* changed copyright on tests to 2008 Marcus Griep
* added executable permissions to new tests
]
Signed-off-by: Marcus Griep <marcus@griep.us>
Acked-by: Eric Wong <normalperson@yhbt.net>
---
Oops, resent as I forgot to change the From: header
git-svn.perl | 61 ++++++++---
t/t9108-git-svn-glob.sh | 9 +-
t/t9108-git-svn-multi-glob.sh | 157 ++++++++++++++++++++++++++++
t/t9125-git-svn-multi-glob-branch-names.sh | 37 +++++++
4 files changed, 244 insertions(+), 20 deletions(-)
create mode 100755 t/t9108-git-svn-multi-glob.sh
create mode 100755 t/t9125-git-svn-multi-glob-branch-names.sh
diff --git a/git-svn.perl b/git-svn.perl
index 503a7c9..47ad378 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -987,8 +987,10 @@ sub complete_url_ls_init {
if (length $pfx && $pfx !~ m#/$#) {
die "--prefix='$pfx' must have a trailing slash '/'\n";
}
- command_noisy('config', "svn-remote.$gs->{repo_id}.$n",
- "$remote_path:refs/remotes/$pfx*");
+ command_noisy('config',
+ "svn-remote.$gs->{repo_id}.$n",
+ "$remote_path:refs/remotes/$pfx*" .
+ ('/*' x (($remote_path =~ tr/*/*/) - 1)) );
}
sub verify_ref {
@@ -4124,16 +4126,38 @@ sub gs_fetch_loop_common {
Git::SVN::gc();
}
+sub get_dir_globbed {
+ my ($self, $left, $depth, $r) = @_;
+
+ my @x = eval { $self->get_dir($left, $r) };
+ return unless scalar @x == 3;
+ my $dirents = $x[0];
+ my @finalents;
+ foreach my $de (keys %$dirents) {
+ next if $dirents->{$de}->{kind} != $SVN::Node::dir;
+ if ($depth > 1) {
+ my @args = ("$left/$de", $depth - 1, $r);
+ foreach my $dir ($self->get_dir_globbed(@args)) {
+ push @finalents, "$de/$dir";
+ }
+ } else {
+ push @finalents, $de;
+ }
+ }
+ @finalents;
+}
+
sub match_globs {
my ($self, $exists, $paths, $globs, $r) = @_;
sub get_dir_check {
my ($self, $exists, $g, $r) = @_;
- my @x = eval { $self->get_dir($g->{path}->{left}, $r) };
- return unless scalar @x == 3;
- my $dirents = $x[0];
- foreach my $de (keys %$dirents) {
- next if $dirents->{$de}->{kind} != $SVN::Node::dir;
+
+ my @dirs = $self->get_dir_globbed($g->{path}->{left},
+ $g->{path}->{depth},
+ $r);
+
+ foreach my $de (@dirs) {
my $p = $g->{path}->full_path($de);
next if $exists->{$p};
next if (length $g->{path}->{right} &&
@@ -4915,16 +4939,21 @@ sub new {
my ($class, $glob) = @_;
my $re = $glob;
$re =~ s!/+$!!g; # no need for trailing slashes
- my $nr = $re =~ tr/*/*/;
- if ($nr > 1) {
- die "Only one '*' wildcard expansion ",
- "is supported (got $nr): '$glob'\n";
- } elsif ($nr == 0) {
+ $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";
+ }
+ if ($depth == 0) {
die "One '*' is needed for glob: '$glob'\n";
}
- $re =~ s!^(.*)\*(.*)$!\(\[^/\]+\)!g;
- my ($left, $right) = ($1, $2);
- $re = quotemeta($left) . $re . quotemeta($right);
+ $re =~ s!\*!\[^/\]*!g;
+# $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";
}
@@ -4933,7 +4962,7 @@ sub new {
}
my $left_re = qr/^\/\Q$left\E(\/|$)/;
bless { left => $left, right => $right, left_regex => $left_re,
- regex => qr/$re/, glob => $glob }, $class;
+ regex => qr/$re/, glob => $glob, depth => $depth }, $class;
}
sub full_path {
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index a6f88bd..bb9df56 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -52,7 +52,8 @@ test_expect_success 'test refspec globbing' '
test "`git rev-parse refs/remotes/tags/end~1`" = \
"`git rev-parse refs/remotes/branches/start`" &&
test "`git rev-parse refs/remotes/branches/start~2`" = \
- "`git rev-parse refs/remotes/trunk`"
+ "`git rev-parse refs/remotes/trunk`" &&
+ test_must_fail git rev-parse refs/remotes/tags/end@3
'
echo try to try > expect.two
@@ -83,8 +84,8 @@ test_expect_success 'test left-hand-side only globbing' '
cmp expect.two output.two
'
-echo "Only one '*' wildcard expansion is supported (got 2): 'branches/*/*'" \
- > expect.three
+echo "Only one set of wildcard directories" \
+ "(e.g. '*' or '*/*/*') is supported: 'branches/*/t/*'" > expect.three
echo "" >> expect.three
test_expect_success 'test disallow multi-globs' '
@@ -92,7 +93,7 @@ test_expect_success 'test disallow multi-globs' '
git config --add svn-remote.three.fetch \
trunk:refs/remotes/three/trunk &&
git config --add svn-remote.three.branches \
- "branches/*/*:refs/remotes/three/branches/*" &&
+ "branches/*/t/*:refs/remotes/three/branches/*" &&
git config --add svn-remote.three.tags \
"tags/*/*:refs/remotes/three/tags/*" &&
cd tmp &&
diff --git a/t/t9108-git-svn-multi-glob.sh b/t/t9108-git-svn-multi-glob.sh
new file mode 100755
index 0000000..9fb51d6
--- /dev/null
+++ b/t/t9108-git-svn-multi-glob.sh
@@ -0,0 +1,157 @@
+#!/bin/sh
+# Copyright (c) 2007 Eric Wong
+test_description='git-svn globbing refspecs'
+. ./lib-git-svn.sh
+
+cat > expect.end <<EOF
+the end
+hi
+start a new branch
+initial
+EOF
+
+test_expect_success 'test refspec globbing' '
+ mkdir -p trunk/src/a trunk/src/b trunk/doc &&
+ echo "hello world" > trunk/src/a/readme &&
+ echo "goodbye world" > trunk/src/b/readme &&
+ svn import -m "initial" trunk "$svnrepo"/trunk &&
+ svn co "$svnrepo" tmp &&
+ cd tmp &&
+ mkdir branches branches/v1 tags &&
+ svn add branches tags &&
+ svn cp trunk branches/v1/start &&
+ svn commit -m "start a new branch" &&
+ svn up &&
+ echo "hi" >> branches/v1/start/src/b/readme &&
+ poke branches/v1/start/src/b/readme &&
+ echo "hey" >> branches/v1/start/src/a/readme &&
+ poke branches/v1/start/src/a/readme &&
+ svn commit -m "hi" &&
+ svn up &&
+ svn cp branches/v1/start tags/end &&
+ echo "bye" >> tags/end/src/b/readme &&
+ poke tags/end/src/b/readme &&
+ echo "aye" >> tags/end/src/a/readme &&
+ poke tags/end/src/a/readme &&
+ svn commit -m "the end" &&
+ echo "byebye" >> tags/end/src/b/readme &&
+ poke tags/end/src/b/readme &&
+ svn commit -m "nothing to see here"
+ cd .. &&
+ git config --add svn-remote.svn.url "$svnrepo" &&
+ git config --add svn-remote.svn.fetch \
+ "trunk/src/a:refs/remotes/trunk" &&
+ git config --add svn-remote.svn.branches \
+ "branches/*/*/src/a:refs/remotes/branches/*/*" &&
+ git config --add svn-remote.svn.tags\
+ "tags/*/src/a:refs/remotes/tags/*" &&
+ git-svn multi-fetch &&
+ git log --pretty=oneline refs/remotes/tags/end | \
+ sed -e "s/^.\{41\}//" > output.end &&
+ cmp expect.end output.end &&
+ test "`git rev-parse refs/remotes/tags/end~1`" = \
+ "`git rev-parse refs/remotes/branches/v1/start`" &&
+ test "`git rev-parse refs/remotes/branches/v1/start~2`" = \
+ "`git rev-parse refs/remotes/trunk`" &&
+ test_must_fail git rev-parse refs/remotes/tags/end@3
+ '
+
+echo try to try > expect.two
+echo nothing to see here >> expect.two
+cat expect.end >> expect.two
+
+test_expect_success 'test left-hand-side only globbing' '
+ git config --add svn-remote.two.url "$svnrepo" &&
+ git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk &&
+ git config --add svn-remote.two.branches \
+ "branches/*/*:refs/remotes/two/branches/*/*" &&
+ git config --add svn-remote.two.tags \
+ "tags/*:refs/remotes/two/tags/*" &&
+ cd tmp &&
+ echo "try try" >> tags/end/src/b/readme &&
+ poke tags/end/src/b/readme &&
+ svn commit -m "try to try"
+ cd .. &&
+ git-svn fetch two &&
+ test `git rev-list refs/remotes/two/tags/end | wc -l` -eq 6 &&
+ test `git rev-list refs/remotes/two/branches/v1/start | wc -l` -eq 3 &&
+ test `git rev-parse refs/remotes/two/branches/v1/start~2` = \
+ `git rev-parse refs/remotes/two/trunk` &&
+ test `git rev-parse refs/remotes/two/tags/end~3` = \
+ `git rev-parse refs/remotes/two/branches/v1/start` &&
+ git log --pretty=oneline refs/remotes/two/tags/end | \
+ sed -e "s/^.\{41\}//" > output.two &&
+ cmp expect.two output.two
+ '
+cat > expect.four <<EOF
+adios
+adding more
+Changed 2 in v2/start
+Another versioned branch
+initial
+EOF
+
+test_expect_success 'test another branch' '
+ (
+ cd tmp &&
+ mkdir branches/v2 &&
+ svn add branches/v2 &&
+ svn cp trunk branches/v2/start &&
+ svn commit -m "Another versioned branch" &&
+ svn up &&
+ echo "hello" >> branches/v2/start/src/b/readme &&
+ poke branches/v2/start/src/b/readme &&
+ echo "howdy" >> branches/v2/start/src/a/readme &&
+ poke branches/v2/start/src/a/readme &&
+ svn commit -m "Changed 2 in v2/start" &&
+ svn up &&
+ svn cp branches/v2/start tags/next &&
+ echo "bye" >> tags/next/src/b/readme &&
+ poke tags/next/src/b/readme &&
+ echo "aye" >> tags/next/src/a/readme &&
+ poke tags/next/src/a/readme &&
+ svn commit -m "adding more" &&
+ echo "byebye" >> tags/next/src/b/readme &&
+ poke tags/next/src/b/readme &&
+ svn commit -m "adios"
+ ) &&
+ git config --add svn-remote.four.url "$svnrepo" &&
+ git config --add svn-remote.four.fetch trunk:refs/remotes/four/trunk &&
+ git config --add svn-remote.four.branches \
+ "branches/*/*:refs/remotes/four/branches/*/*" &&
+ git config --add svn-remote.four.tags \
+ "tags/*:refs/remotes/four/tags/*" &&
+ git-svn fetch four &&
+ test `git rev-list refs/remotes/four/tags/next | wc -l` -eq 5 &&
+ test `git rev-list refs/remotes/four/branches/v2/start | wc -l` -eq 3 &&
+ test `git rev-parse refs/remotes/four/branches/v2/start~2` = \
+ `git rev-parse refs/remotes/four/trunk` &&
+ test `git rev-parse refs/remotes/four/tags/next~2` = \
+ `git rev-parse refs/remotes/four/branches/v2/start` &&
+ git log --pretty=oneline refs/remotes/four/tags/next | \
+ sed -e "s/^.\{41\}//" > output.four &&
+ cmp expect.four output.four
+ '
+
+echo "Only one set of wildcard directories" \
+ "(e.g. '*' or '*/*/*') is supported: 'branches/*/t/*'" > expect.three
+echo "" >> expect.three
+
+test_expect_success 'test disallow multiple globs' '
+ git config --add svn-remote.three.url "$svnrepo" &&
+ git config --add svn-remote.three.fetch \
+ trunk:refs/remotes/three/trunk &&
+ git config --add svn-remote.three.branches \
+ "branches/*/t/*:refs/remotes/three/branches/*/*" &&
+ git config --add svn-remote.three.tags \
+ "tags/*:refs/remotes/three/tags/*" &&
+ cd tmp &&
+ echo "try try" >> tags/end/src/b/readme &&
+ poke tags/end/src/b/readme &&
+ svn commit -m "try to try"
+ cd .. &&
+ test_must_fail git-svn fetch three 2> stderr.three &&
+ cmp expect.three stderr.three
+ '
+
+test_done
diff --git a/t/t9125-git-svn-multi-glob-branch-names.sh b/t/t9125-git-svn-multi-glob-branch-names.sh
new file mode 100755
index 0000000..6b62b52
--- /dev/null
+++ b/t/t9125-git-svn-multi-glob-branch-names.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+# Copyright (c) 2008 Marcus Griep
+
+test_description='git-svn multi-glob branch names'
+. ./lib-git-svn.sh
+
+test_expect_success 'setup svnrepo' '
+ mkdir project project/trunk project/branches \
+ project/branches/v14.1 project/tags &&
+ echo foo > project/trunk/foo &&
+ svn import -m "$test_description" project "$svnrepo/project" &&
+ rm -rf project &&
+ svn cp -m "fun" "$svnrepo/project/trunk" \
+ "$svnrepo/project/branches/v14.1/beta" &&
+ svn cp -m "more fun!" "$svnrepo/project/branches/v14.1/beta" \
+ "$svnrepo/project/branches/v14.1/gold"
+ '
+
+test_expect_success 'test clone with multi-glob in branch names' '
+ git svn clone -T trunk -b branches/*/* -t tags \
+ "$svnrepo/project" project &&
+ cd project &&
+ git rev-parse "refs/remotes/v14.1/beta" &&
+ git rev-parse "refs/remotes/v14.1/gold" &&
+ cd ..
+ '
+
+test_expect_success 'test dcommit to multi-globbed branch' "
+ cd project &&
+ git reset --hard 'refs/remotes/v14.1/gold' &&
+ echo hello >> foo &&
+ git commit -m 'hello' -- foo &&
+ git svn dcommit &&
+ cd ..
+ "
+
+test_done
--
1.6.0.rc2.4.g0643f
^ permalink raw reply related [flat|nested] 14+ messages in thread