{"thread":{"id":"41032","subject":"[PATCH v2] git-svn: add support for prefixed globs in config","startedAt":"2015-12-17T14:34:42Z","lastAt":"2015-12-17T14:34:42Z","messageCount":1,"participants":["Victor Leschuk"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"274670","messageId":"1450362882-716-1-git-send-email-vleschuk@accesssoftek.com","threadId":"41032","inReplyTo":null,"subject":"[PATCH v2] git-svn: add support for prefixed globs in config","fromName":"Victor Leschuk","fromEmail":"vleschuk@gmail.com","sentAt":"2015-12-17T14:34:42Z","receivedAt":"2015-12-17T14:34:42Z","isPatch":true,"sender":{"key":"vleschuk@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1045374?v=4"},"body":"Introduce prefixed globs for branches and tags in git-svn.\nGlobs like 'release_*' allow users to avoid long lines in config like:\n\nbranches = branches/{release_20,release_21,release_22,...}\n\nSigned-off-by: Victor Leschuk <vleschuk@accesssoftek.com>\n---\nChanges from v1:\n\t* Joined implementation and test in one patch\n\t* Fixed test code style according to current coding style guide\n\n Documentation/git-svn.txt        |   5 ++\n perl/Git/SVN/GlobSpec.pm         |   9 ++-\n t/t9168-git-svn-prefixed-glob.sh | 136 +++++++++++++++++++++++++++++++++++++++\n 3 files changed, 145 insertions(+), 5 deletions(-)\n create mode 100755 t/t9168-git-svn-prefixed-glob.sh\n\ndiff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt\nindex 0c0f60b..529cffe 100644\n--- a/Documentation/git-svn.txt\n+++ b/Documentation/git-svn.txt\n@@ -1034,6 +1034,7 @@ listed below are allowed:\n \turl = http://server.org/svn\n \tfetch = trunk/project-a:refs/remotes/project-a/trunk\n \tbranches = branches/*/project-a:refs/remotes/project-a/branches/*\n+\tbranches = branches/release_*:refs/remotes/project-a/branches/release_*\n \ttags = tags/*/project-a:refs/remotes/project-a/tags/*\n ------------------------------------------------------------------------\n \n@@ -1044,6 +1045,10 @@ independent path component (surrounded by '/' or EOL).   This\n type of configuration is not automatically created by 'init' and\n should be manually entered with a text-editor or using 'git config'.\n \n+Also note that prefixed globs (e.g. 'release_*') match everything after prefix\n+but do not match exact prefix. For example:\n+'release_*' will match 'release_1' or 'release_v1' but will not match 'release_'.\n+\n It is also possible to fetch a subset of branches or tags by using a\n comma-separated list of names within braces. For example:\n \ndiff --git a/perl/Git/SVN/GlobSpec.pm b/perl/Git/SVN/GlobSpec.pm\nindex c95f5d7..a136090 100644\n--- a/perl/Git/SVN/GlobSpec.pm\n+++ b/perl/Git/SVN/GlobSpec.pm\n@@ -11,16 +11,15 @@ sub new {\n \tmy $die_msg = \"Only one set of wildcard directories \" .\n \t\t\t\t\"(e.g. '*' or '*/*/*') is supported: '$glob'\\n\";\n \tfor my $part (split(m|/|, $glob)) {\n-\t\tif ($part =~ /\\*/ && $part ne \"*\") {\n-\t\t\tdie \"Invalid pattern in '$glob': $part\\n\";\n-\t\t} elsif ($pattern_ok && $part =~ /[{}]/ &&\n+\t\tif ($pattern_ok && $part =~ /[{}]/ &&\n \t\t\t $part !~ /^\\{[^{}]+\\}/) {\n \t\t\tdie \"Invalid pattern in '$glob': $part\\n\";\n \t\t}\n-\t\tif ($part eq \"*\") {\n+\t\tif ($part =~ /(\\w*)\\*/) {\n \t\t\tdie $die_msg if $state eq \"right\";\n \t\t\t$state = \"pattern\";\n-\t\t\tpush(@patterns, \"[^/]*\");\n+\t\t\tmy $pat = $1 ? \"${1}[^/]+\" : \"[^/]*\";\n+\t\t\tpush(@patterns, $pat);\n \t\t} elsif ($pattern_ok && $part =~ /^\\{(.*)\\}$/) {\n \t\t\tdie $die_msg if $state eq \"right\";\n \t\t\t$state = \"pattern\";\ndiff --git a/t/t9168-git-svn-prefixed-glob.sh b/t/t9168-git-svn-prefixed-glob.sh\nnew file mode 100755\nindex 0000000..b8a059b\n--- /dev/null\n+++ b/t/t9168-git-svn-prefixed-glob.sh\n@@ -0,0 +1,136 @@\n+#!/bin/sh\n+test_description='git svn globbing refspecs with prefixed globs'\n+. ./lib-git-svn.sh\n+\n+cat >expect.end <<EOF\n+the end\n+hi\n+start a new branch\n+initial\n+EOF\n+\n+test_expect_success 'test refspec prefixed globbing' '\n+\tmkdir -p trunk/src/a trunk/src/b trunk/doc &&\n+\techo \"hello world\" >trunk/src/a/readme &&\n+\techo \"goodbye world\" >trunk/src/b/readme &&\n+\tsvn_cmd import -m \"initial\" trunk \"$svnrepo\"/trunk &&\n+\tsvn_cmd co \"$svnrepo\" tmp &&\n+\t(\n+\t\tcd tmp &&\n+\t\tmkdir branches tags &&\n+\t\tsvn_cmd add branches tags &&\n+\t\tsvn_cmd cp trunk branches/b_start &&\n+\t\tsvn_cmd commit -m \"start a new branch\" &&\n+\t\tsvn_cmd up &&\n+\t\techo \"hi\" >>branches/b_start/src/b/readme &&\n+\t\tpoke branches/b_start/src/b/readme &&\n+\t\techo \"hey\" >>branches/b_start/src/a/readme &&\n+\t\tpoke branches/b_start/src/a/readme &&\n+\t\tsvn_cmd commit -m \"hi\" &&\n+\t\tsvn_cmd up &&\n+\t\tsvn_cmd cp branches/b_start tags/t_end &&\n+\t\techo \"bye\" >>tags/t_end/src/b/readme &&\n+\t\tpoke tags/t_end/src/b/readme &&\n+\t\techo \"aye\" >>tags/t_end/src/a/readme &&\n+\t\tpoke tags/t_end/src/a/readme &&\n+\t\tsvn_cmd commit -m \"the end\" &&\n+\t\techo \"byebye\" >>tags/t_end/src/b/readme &&\n+\t\tpoke tags/t_end/src/b/readme &&\n+\t\tsvn_cmd commit -m \"nothing to see here\"\n+\t) &&\n+\tgit config --add svn-remote.svn.url \"$svnrepo\" &&\n+\tgit config --add svn-remote.svn.fetch \\\n+\t                 \"trunk/src/a:refs/remotes/trunk\" &&\n+\tgit config --add svn-remote.svn.branches \\\n+\t                 \"branches/b_*/src/a:refs/remotes/branches/b_*\" &&\n+\tgit config --add svn-remote.svn.tags\\\n+\t                 \"tags/t_*/src/a:refs/remotes/tags/t_*\" &&\n+\tgit svn multi-fetch &&\n+\tgit log --pretty=oneline refs/remotes/tags/t_end | \\\n+\t    sed -e \"s/^.\\{41\\}//\" >output.end &&\n+\ttest_cmp expect.end output.end &&\n+\ttest \"`git rev-parse refs/remotes/tags/t_end~1`\" = \\\n+\t\t\"`git rev-parse refs/remotes/branches/b_start`\" &&\n+\ttest \"`git rev-parse refs/remotes/branches/b_start~2`\" = \\\n+\t\t\"`git rev-parse refs/remotes/trunk`\" &&\n+\ttest_must_fail git rev-parse refs/remotes/tags/t_end@3\n+\t'\n+\n+echo try to try >expect.two &&\n+echo nothing to see here >>expect.two &&\n+cat expect.end >>expect.two\n+\n+test_expect_success 'test left-hand-side only prefixed globbing' '\n+\tgit config --add svn-remote.two.url \"$svnrepo\" &&\n+\tgit config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk &&\n+\tgit config --add svn-remote.two.branches \\\n+\t                 \"branches/b_*:refs/remotes/two/branches/*\" &&\n+\tgit config --add svn-remote.two.tags \\\n+\t                 \"tags/t_*:refs/remotes/two/tags/*\" &&\n+\t(\n+\t\tcd tmp &&\n+\t\techo \"try try\" >>tags/t_end/src/b/readme &&\n+\t\tpoke tags/t_end/src/b/readme &&\n+\t\tsvn_cmd commit -m \"try to try\"\n+\t) &&\n+\tgit svn fetch two &&\n+\ttest `git rev-list refs/remotes/two/tags/t_end | wc -l` -eq 6 &&\n+\ttest `git rev-list refs/remotes/two/branches/b_start | wc -l` -eq 3 &&\n+\ttest `git rev-parse refs/remotes/two/branches/b_start~2` = \\\n+\t     `git rev-parse refs/remotes/two/trunk` &&\n+\ttest `git rev-parse refs/remotes/two/tags/t_end~3` = \\\n+\t     `git rev-parse refs/remotes/two/branches/b_start` &&\n+\tgit log --pretty=oneline refs/remotes/two/tags/t_end | \\\n+\t    sed -e \"s/^.\\{41\\}//\" >output.two &&\n+\ttest_cmp expect.two output.two\n+\t'\n+\n+test_expect_success 'test prefixed globs do not match just prefix' '\n+\tgit config --add svn-remote.three.url \"$svnrepo\" &&\n+\tgit config --add svn-remote.three.fetch \\\n+\t                 trunk:refs/remotes/three/trunk &&\n+\tgit config --add svn-remote.three.branches \\\n+\t                 \"branches/b_*:refs/remotes/three/branches/*\" &&\n+\tgit config --add svn-remote.three.tags \\\n+\t                 \"tags/t_*:refs/remotes/three/tags/*\" &&\n+\t(\n+\t\tcd tmp &&\n+\t\tsvn_cmd cp trunk branches/b_ &&\n+\t\techo \"You should never see me\" >>branches/b_/src/a/readme &&\n+\t\tpoke branches/b_/src/a/readme &&\n+\t\tsvn_cmd commit -m \"Never seen branch commit\" &&\n+\t\tsvn_cmd up &&\n+\t\tsvn_cmd cp branches/b_ tags/t_ &&\n+\t\techo \"You should never see mee too\" >>tags/t_/src/a/readme &&\n+\t\tpoke tags/t_/src/a/readme &&\n+\t\tsvn_cmd commit -m \"Never seen tag commit\" &&\n+\t\tsvn_cmd up\n+\t) &&\n+\tgit svn fetch three &&\n+\ttest_path_is_missing refs/remotes/three/branches/b_ &&\n+\ttest_path_is_missing refs/remotes/three/tags/t_\n+\t'\n+\n+echo \"Only one set of wildcard directories\" \\\n+     \"(e.g. '*' or '*/*/*') is supported: 'branches/b_*/t/*'\" >expect.four &&\n+echo \"\" >>expect.four\n+\n+test_expect_success 'test disallow prefixed multi-globs' '\n+\tgit config --add svn-remote.four.url \"$svnrepo\" &&\n+\tgit config --add svn-remote.four.fetch \\\n+\t                 trunk:refs/remotes/four/trunk &&\n+\tgit config --add svn-remote.four.branches \\\n+\t                 \"branches/b_*/t/*:refs/remotes/four/branches/*\" &&\n+\tgit config --add svn-remote.four.tags \\\n+\t                 \"tags/t_*/*:refs/remotes/four/tags/*\" &&\n+\t(\n+\t\tcd tmp &&\n+\t\techo \"try try\" >>tags/t_end/src/b/readme &&\n+\t\tpoke tags/t_end/src/b/readme &&\n+\t\tsvn_cmd commit -m \"try to try\"\n+\t) &&\n+\ttest_must_fail git svn fetch four 2>stderr.four &&\n+\ttest_cmp expect.four stderr.four\n+\t'\n+\n+test_done\n-- \n2.7.0.rc0.21.gb793f61\n"}]}