{"thread":{"id":"41082","subject":"[PATCH/RFC 0/2] add a perl compatible regex match flag to git describe","startedAt":"2015-12-27T22:59:50Z","lastAt":"2015-12-27T23:39:51Z","messageCount":4,"participants":["Mostyn Bramley-Moore","brian m. carlson"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"275026","messageId":"1451257192-5755-1-git-send-email-mostynb@opera.com","threadId":"41082","inReplyTo":null,"subject":"[PATCH/RFC 0/2] add a perl compatible regex match flag to git describe","fromName":"Mostyn Bramley-Moore","fromEmail":"mostynb@opera.com","sentAt":"2015-12-27T22:59:50Z","receivedAt":"2015-12-27T22:59:50Z","isPatch":true,"sender":{"key":"mostynb@opera.com","avatar":null},"body":"git describe currently only supports glob matching with the --matches flag.\nIt would be useful to support regular expressions.\n\nPCRE is already an optional dependency from git grep, I wonder if posix or\nextended regexes would be preferable?\n\nSome old discussion of this as a candidate feature is here, though nobody put\ntogether a patch as far as I can see:\nhttp://comments.gmane.org/gmane.comp.version-control.git/173873\n\nMostyn Bramley-Moore (2):\n  describe: mention glob in the --matches help text\n  describe: add --pcre-match option\n\n Documentation/git-describe.txt |  5 +++\n builtin/describe.c             | 73 ++++++++++++++++++++++++++++++++++++++++--\n t/README                       |  3 +-\n t/t6120-describe.sh            | 29 ++++++++++++++---\n 4 files changed, 103 insertions(+), 7 deletions(-)\n\n-- \n2.5.0\n"},{"id":"275027","messageId":"1451257192-5755-2-git-send-email-mostynb@opera.com","threadId":"41082","inReplyTo":"1451257192-5755-1-git-send-email-mostynb@opera.com","subject":"[PATCH/RFC 1/2] describe: mention glob in the --matches help text","fromName":"Mostyn Bramley-Moore","fromEmail":"mostynb@opera.com","sentAt":"2015-12-27T22:59:51Z","receivedAt":"2015-12-27T22:59:51Z","isPatch":true,"sender":{"key":"mostynb@opera.com","avatar":null},"body":"This saves the user from needing to consult to manpage to learn the\nformat of the --matches argument.\n\nSigned-off-by: Mostyn Bramley-Moore <mostynb@opera.com>\n---\n builtin/describe.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/describe.c b/builtin/describe.c\nindex 8a25abe..2386c64 100644\n--- a/builtin/describe.c\n+++ b/builtin/describe.c\n@@ -404,8 +404,8 @@ int cmd_describe(int argc, const char **argv, const char *prefix)\n \t\t\t    N_(\"only output exact matches\"), 0),\n \t\tOPT_INTEGER(0, \"candidates\", &max_candidates,\n \t\t\t    N_(\"consider <n> most recent tags (default: 10)\")),\n-\t\tOPT_STRING(0, \"match\",       &pattern, N_(\"pattern\"),\n-\t\t\t   N_(\"only consider tags matching <pattern>\")),\n+\t\tOPT_STRING(0, \"match\",       &pattern, N_(\"glob\"),\n+\t\t\t   N_(\"only consider tags matching <glob>\")),\n \t\tOPT_BOOL(0, \"always\",        &always,\n \t\t\tN_(\"show abbreviated commit object as fallback\")),\n \t\t{OPTION_STRING, 0, \"dirty\",  &dirty, N_(\"mark\"),\n-- \n2.5.0\n"},{"id":"275028","messageId":"1451257192-5755-3-git-send-email-mostynb@opera.com","threadId":"41082","inReplyTo":"1451257192-5755-1-git-send-email-mostynb@opera.com","subject":"[PATCH/RFC 2/2] describe: add --pcre-match option","fromName":"Mostyn Bramley-Moore","fromEmail":"mostynb@opera.com","sentAt":"2015-12-27T22:59:52Z","receivedAt":"2015-12-27T22:59:52Z","isPatch":true,"sender":{"key":"mostynb@opera.com","avatar":null},"body":"Add a perl-compatible regular expression version of the --match option,\nwhich allows more flexible pattern matching.\n\nSigned-off-by: Mostyn Bramley-Moore <mostynb@opera.com>\n---\n Documentation/git-describe.txt |  5 +++\n builtin/describe.c             | 69 ++++++++++++++++++++++++++++++++++++++++++\n t/README                       |  3 +-\n t/t6120-describe.sh            | 29 +++++++++++++++---\n 4 files changed, 101 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt\nindex c8f28c8..f646560 100644\n--- a/Documentation/git-describe.txt\n+++ b/Documentation/git-describe.txt\n@@ -85,6 +85,11 @@ OPTIONS\n \texcluding the \"refs/tags/\" prefix.  This can be used to avoid\n \tleaking private tags from the repository.\n \n+--pcre-match <pattern>::\n+\tOnly consider tags matching the given `PCRE` pattern,\n+\texcluding the \"refs/tags/\" prefix.  This can be used to avoid\n+\tleaking private tags from the repository.\n+\n --always::\n \tShow uniquely abbreviated commit object as fallback.\n \ndiff --git a/builtin/describe.c b/builtin/describe.c\nindex 2386c64..7ceecd7 100644\n--- a/builtin/describe.c\n+++ b/builtin/describe.c\n@@ -10,6 +10,10 @@\n #include \"hashmap.h\"\n #include \"argv-array.h\"\n \n+#ifdef USE_LIBPCRE\n+#include <pcre.h>\n+#endif\n+\n #define SEEN\t\t(1u << 0)\n #define MAX_TAGS\t(FLAG_BITS - 1)\n \n@@ -32,6 +36,12 @@ static const char *pattern;\n static int always;\n static const char *dirty;\n \n+#ifdef USE_LIBPCRE\n+static pcre *regex = NULL;\n+static pcre_extra *extra = NULL;\n+static const char *pcre_pattern = NULL;\n+#endif\n+\n /* diff-index command arguments to check if working tree is dirty. */\n static const char *diff_index_args[] = {\n \t\"diff-index\", \"--quiet\", \"HEAD\", \"--\", NULL\n@@ -119,6 +129,47 @@ static void add_to_known_names(const char *path,\n \t}\n }\n \n+#ifdef USE_LIBPCRE\n+static void pcre_init()\n+{\n+\tconst char *error = NULL;\n+\tint erroffset = -1;\n+\tint opts = PCRE_MULTILINE;\n+\n+\tregex = pcre_compile(pcre_pattern, opts, &error, &erroffset, NULL);\n+\tif (!regex)\n+\t\tdie(\"invalid PCRE at position %d of \\'%s\\': %s\",\n+\t\t\terroffset, pcre_pattern, error);\n+\n+\textra = pcre_study(regex, 0, &error);\n+\tif (!extra && error)\n+\t\tdie(\"%s\", error);\n+}\n+\n+static void pcre_cleanup()\n+{\n+\tpcre_free(regex);\n+\tregex = NULL;\n+\tpcre_free(extra);\n+\textra = NULL;\n+}\n+\n+/* return 1 on match, 0 on no match. */\n+static int pcre_match(const char *pattern, const char *text)\n+{\n+\tint ovector[30], flags = 0; // FIXME: ovector size ... ?\n+\tint ret = pcre_exec(regex, extra,\n+\t                    text, strlen(text), 0,\n+\t                    flags, ovector, ARRAY_SIZE(ovector));\n+\tif (ret < 0 && ret != PCRE_ERROR_NOMATCH)\n+\t\tdie(\"pcre_exec failed with error code %d\", ret);\n+\tif (ret > 0)\n+\t\treturn 0; /* no match */\n+\n+\treturn 1; /* match */\n+}\n+#endif\n+\n static int get_name(const char *path, const struct object_id *oid, int flag, void *cb_data)\n {\n \tint is_tag = starts_with(path, \"refs/tags/\");\n@@ -132,6 +183,10 @@ static int get_name(const char *path, const struct object_id *oid, int flag, voi\n \t/* Accept only tags that match the pattern, if given */\n \tif (pattern && (!is_tag || wildmatch(pattern, path + 10, 0, NULL)))\n \t\treturn 0;\n+#ifdef USE_LIBPCRE\n+\tif (pcre_pattern && (!is_tag || pcre_match(pcre_pattern, path + 10)))\n+\t\treturn 0;\n+#endif\n \n \t/* Is it annotated? */\n \tif (!peel_ref(path, peeled.hash)) {\n@@ -406,6 +461,10 @@ int cmd_describe(int argc, const char **argv, const char *prefix)\n \t\t\t    N_(\"consider <n> most recent tags (default: 10)\")),\n \t\tOPT_STRING(0, \"match\",       &pattern, N_(\"glob\"),\n \t\t\t   N_(\"only consider tags matching <glob>\")),\n+#ifdef USE_LIBPCRE\n+\t\tOPT_STRING(0, \"pcre-match\",  &pcre_pattern, N_(\"regex\"),\n+\t\t\t   N_(\"only consider tags matching PCRE <regex>\")),\n+#endif\n \t\tOPT_BOOL(0, \"always\",        &always,\n \t\t\tN_(\"show abbreviated commit object as fallback\")),\n \t\t{OPTION_STRING, 0, \"dirty\",  &dirty, N_(\"mark\"),\n@@ -429,6 +488,11 @@ int cmd_describe(int argc, const char **argv, const char *prefix)\n \tif (longformat && abbrev == 0)\n \t\tdie(_(\"--long is incompatible with --abbrev=0\"));\n \n+#ifdef USE_LIBPCRE\n+\tif (pcre_pattern)\n+\t\tpcre_init();\n+#endif\n+\n \tif (contains) {\n \t\tstruct argv_array args;\n \n@@ -455,6 +519,11 @@ int cmd_describe(int argc, const char **argv, const char *prefix)\n \tif (!names.size && !always)\n \t\tdie(_(\"No names found, cannot describe anything.\"));\n \n+#ifdef USE_LIBPCRE\n+\tif (pcre_pattern)\n+\t\tpcre_cleanup();\n+#endif\n+\n \tif (argc == 0) {\n \t\tif (dirty) {\n \t\t\tstatic struct lock_file index_lock;\ndiff --git a/t/README b/t/README\nindex 1dc908e..1495f59 100644\n--- a/t/README\n+++ b/t/README\n@@ -798,7 +798,8 @@ use these, and \"test_set_prereq\" for how to define your own.\n  - LIBPCRE\n \n    Git was compiled with USE_LIBPCRE=YesPlease. Wrap any tests\n-   that use git-grep --perl-regexp or git-grep -P in these.\n+   that use git-grep --perl-regexp, git-grep -P or\n+   git describe --pcre-matches in these.\n \n  - CASE_INSENSITIVE_FS\n \ndiff --git a/t/t6120-describe.sh b/t/t6120-describe.sh\nindex 85f2694..8290dea 100755\n--- a/t/t6120-describe.sh\n+++ b/t/t6120-describe.sh\n@@ -12,13 +12,14 @@ test_description='test describe\n '\n . ./test-lib.sh\n \n-check_describe () {\n-\texpect=\"$1\"\n-\tshift\n+_check_describe () {\n+\tpcre=\"$1\"\n+\texpect=\"$2\"\n+\tshift 2\n \tR=$(git describe \"$@\" 2>err.actual)\n \tS=$?\n \tcat err.actual >&3\n-\ttest_expect_success \"describe $*\" '\n+\ttest_expect_success $pcre \"describe $*\" '\n \ttest $S = 0 &&\n \tcase \"$R\" in\n \t$expect)\techo happy ;;\n@@ -28,6 +29,14 @@ check_describe () {\n \t'\n }\n \n+check_describe() {\n+\t_check_describe \"\" $*\n+}\n+\n+check_describe_pcre() {\n+\t_check_describe LIBPCRE $*\n+}\n+\n test_expect_success setup '\n \n \ttest_tick &&\n@@ -175,12 +184,24 @@ test_expect_success 'set-up matching pattern tests' '\n '\n \n check_describe \"test-annotated-*\" --match=\"test-*\"\n+check_describe_pcre \"test-annotated-*\" --pcre-match=\"^test-\"\n+check_describe_pcre \"test-annotated-*\" --match=\"test-*\" --pcre-match=\"^test-\"\n \n check_describe \"test1-lightweight-*\" --tags --match=\"test1-*\"\n+check_describe_pcre \"test1-lightweight-*\" --tags --pcre-match=\"^test1-\"\n+check_describe_pcre \"test1-lightweight-*\" --tags --match=\"test1-*\" \\\n+\t--pcre-match=\"^test1-\"\n \n check_describe \"test2-lightweight-*\" --tags --match=\"test2-*\"\n+check_describe_pcre \"test2-lightweight-*\" --tags --pcre-match=\"^test2-\"\n+check_describe_pcre \"test2-lightweight-*\" --tags --match=\"test2-*\" \\\n+\t--pcre-match=\"^test2-\"\n \n check_describe \"test2-lightweight-*\" --long --tags --match=\"test2-*\" HEAD^\n+check_describe_pcre \"test2-lightweight-*\" --long --tags \\\n+\t--pcre-match=\"^test2-\" HEAD^\n+check_describe_pcre \"test2-lightweight-*\" --long --tags --match=\"test2-*\" \\\n+\t--pcre-match=\"^test2-\" HEAD^\n \n test_expect_success 'name-rev with exact tags' '\n \techo A >expect &&\n-- \n2.5.0\n"},{"id":"275029","messageId":"20151227233951.GA52863@vauxhall.crustytoothpaste.net","threadId":"41082","inReplyTo":"1451257192-5755-1-git-send-email-mostynb@opera.com","subject":"Re: [PATCH/RFC 0/2] add a perl compatible regex match flag to git describe","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2015-12-27T23:39:51Z","receivedAt":"2015-12-27T23:39:51Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Sun, Dec 27, 2015 at 11:59:50PM +0100, Mostyn Bramley-Moore wrote:\n> git describe currently only supports glob matching with the --matches flag.\n> It would be useful to support regular expressions.\n> \n> PCRE is already an optional dependency from git grep, I wonder if posix or\n> extended regexes would be preferable?\n> \n> Some old discussion of this as a candidate feature is here, though nobody put\n> together a patch as far as I can see:\n> http://comments.gmane.org/gmane.comp.version-control.git/173873\n> \n> Mostyn Bramley-Moore (2):\n>   describe: mention glob in the --matches help text\n>   describe: add --pcre-match option\n\nIf you're going to implement this, I'd recommend an option that adjusts\n--matches to accept a PCRE regexp instead of adding a new option\naccepting its own pattern.  I'd also recommend calling it --perl-regexp\nfor compatibility with git grep.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | https://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"}]}