{"thread":{"id":"41095","subject":"[PATCH v4] git-svn: add support for prefixed globs in config","startedAt":"2015-12-30T10:09:09Z","lastAt":"2016-01-10T11:00:46Z","messageCount":4,"participants":["Victor Leschuk","Junio C Hamano","Eric Wong"],"isPatch":true,"patchVersion":4,"patchTotal":null},"messages":[{"id":"275173","messageId":"1451470149-14735-1-git-send-email-vleschuk@accesssoftek.com","threadId":"41095","inReplyTo":null,"subject":"[PATCH v4] git-svn: add support for prefixed globs in config","fromName":"Victor Leschuk","fromEmail":"vleschuk@gmail.com","sentAt":"2015-12-30T10:09:09Z","receivedAt":"2015-12-30T10:09:09Z","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 v3:\n\t* Wrapped all test preparations in separate test-cases\n\n Documentation/git-svn.txt        |   5 ++\n perl/Git/SVN/GlobSpec.pm         |   9 ++-\n t/t9168-git-svn-prefixed-glob.sh | 142 +++++++++++++++++++++++++++++++++++++++\n 3 files changed, 151 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..1b08e45\n--- /dev/null\n+++ b/t/t9168-git-svn-prefixed-glob.sh\n@@ -0,0 +1,142 @@\n+#!/bin/sh\n+test_description='git svn globbing refspecs with prefixed globs'\n+. ./lib-git-svn.sh\n+\n+test_expect_success 'prepare test refspec prefixed globbing' '\n+\tcat >expect.end <<EOF\n+the end\n+hi\n+start a new branch\n+initial\n+EOF\n+\t'\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+test_expect_success 'prepare test left-hand-side only prefixed globbing' '\n+\techo try to try >expect.two &&\n+\techo nothing to see here >>expect.two &&\n+\tcat expect.end >>expect.two\n+\t'\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+test_expect_success 'prepare test dissallow prefixed multi-globs' \"\n+\techo \\\"Only one set of wildcard directories\\\" \\\n+\t     \\\"(e.g. '*' or '*/*/*') is supported: 'branches/b_*/t/*'\\\" >expect.four &&\n+\techo \\\"\\\" >>expect.four\n+\t\"\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"},{"id":"275203","messageId":"xmqq60zfehyb.fsf@gitster.mtv.corp.google.com","threadId":"41095","inReplyTo":"1451470149-14735-1-git-send-email-vleschuk@accesssoftek.com","subject":"Re: [PATCH v4] git-svn: add support for prefixed globs in config","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-12-30T21:37:32Z","receivedAt":"2015-12-30T21:37:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Victor Leschuk <vleschuk@gmail.com> writes:\n\n> Introduce prefixed globs for branches and tags in git-svn.\n> Globs like 'release_*' allow users to avoid long lines in config like:\n>\n> branches = branches/{release_20,release_21,release_22,...}\n>\n> Signed-off-by: Victor Leschuk <vleschuk@accesssoftek.com>\n> ---\n> Changes from v3:\n> \t* Wrapped all test preparations in separate test-cases\n>\n>  Documentation/git-svn.txt        |   5 ++\n>  perl/Git/SVN/GlobSpec.pm         |   9 ++-\n>  t/t9168-git-svn-prefixed-glob.sh | 142 +++++++++++++++++++++++++++++++++++++++\n>  3 files changed, 151 insertions(+), 5 deletions(-)\n>  create mode 100755 t/t9168-git-svn-prefixed-glob.sh\n>\n> diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt\n> index 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\nHmph, if you are going this route, I wonder if there is a reason to\nlimit yourself only to \"prefix\".  Would allowing something like this:\n\n\tbranches = branches/pre*post:refs/remotes/project-a/branches/*\n\ni.e., loosening the rule to allow at most one asterisk anywhere on\nthe left hand side of the colon, and require the same number of\nasterisks as the left hand side has on the right hand side of the\ncolon, be too lax and hurt the users?\n"},{"id":"275365","messageId":"20160105081513.GA32695@dcvr.yhbt.net","threadId":"41095","inReplyTo":"xmqq60zfehyb.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v4] git-svn: add support for prefixed globs in config","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2016-01-05T08:15:13Z","receivedAt":"2016-01-05T08:15:13Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Junio C Hamano <gitster@pobox.com> wrote:\n> Victor Leschuk <vleschuk@gmail.com> writes:\n> > +\tbranches = branches/release_*:refs/remotes/project-a/branches/release_*\n> \n> Hmph, if you are going this route, I wonder if there is a reason to\n> limit yourself only to \"prefix\".  Would allowing something like this:\n> \n> \tbranches = branches/pre*post:refs/remotes/project-a/branches/*\n> \n> i.e., loosening the rule to allow at most one asterisk anywhere on\n> the left hand side of the colon, and require the same number of\n> asterisks as the left hand side has on the right hand side of the\n> colon, be too lax and hurt the users?\n\nSeems doable.  Not sure about the consequences, yet...\n\nI also think the $1 truthiness check was unnecessary and even\nproblematic if we need to encounter a \"0\" as a path component.\nAnd using the path component will need to be quoted as we do below\nwith the brace case (showing with diff -U6)\n\nPerhaps this? (untested)\n\ndiff --git a/perl/Git/SVN/GlobSpec.pm b/perl/Git/SVN/GlobSpec.pm\nindex a136090..7961a78 100644\n--- a/perl/Git/SVN/GlobSpec.pm\n+++ b/perl/Git/SVN/GlobSpec.pm\n@@ -12,16 +12,17 @@ sub new {\n \t\t\t\t\"(e.g. '*' or '*/*/*') is supported: '$glob'\\n\";\n \tfor my $part (split(m|/|, $glob)) {\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 =~ /(\\w*)\\*/) {\n+\t\tif ($part =~ /(\\w*)\\*(\\w*)/) {\n+\t\t\tmy ($l, $r) = ($1, $2);\n \t\t\tdie $die_msg if $state eq \"right\";\n \t\t\t$state = \"pattern\";\n-\t\t\tmy $pat = $1 ? \"${1}[^/]+\" : \"[^/]*\";\n+\t\t\tmy $pat = quotemeta($l) . '[^/]*'. quotemeta($r);\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\";\n \t\t\tmy $p = quotemeta($1);\n \t\t\t$p =~ s/\\\\,/|/g;\n-- \nEW\n"},{"id":"275608","messageId":"6AE1604EE3EC5F4296C096518C6B77EE5FF2055FF4@mail.accesssoftek.com","threadId":"41095","inReplyTo":"20160105081513.GA32695@dcvr.yhbt.net","subject":"RE: [PATCH v4] git-svn: add support for prefixed globs in config","fromName":"Victor Leschuk","fromEmail":"vleschuk@accesssoftek.com","sentAt":"2016-01-10T11:00:46Z","receivedAt":"2016-01-10T11:00:46Z","isPatch":true,"sender":{"key":"vleschuk@accesssoftek.com","avatar":null},"body":"Hello Eric and Junio,\n\nThanks a lot for the comments and sorry for the delay with the response.\n\nI think that's reasonable to widen the applicability of globs, will do it and prepare next patch.\n\n\n-                       my $pat = $1 ? \"${1}[^/]+\" : \"[^/]*\";\n+                       my $pat = quotemeta($l) . '[^/]*'. quotemeta($r);\n\nHm, that differs from the behavior I suggested at first time: in this case the 'test*' pattern will match all of the: \"test\", \"test0\", \"test1\". In my case it wouldn't match \"test\"...\n\nHowever I think that's ok.\n"}]}