Signed-off-by: Mostyn Bramley-Moore <mostynb@xxxxxxxxx> --- Documentation/git-describe.txt | 6 ++++++ builtin/describe.c | 41 +++++++++++++++++++++++++++++++++++++++++ t/t6120-describe.sh | 14 ++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt index b8279ec..0c237c3 100644 --- a/Documentation/git-describe.txt +++ b/Documentation/git-describe.txt @@ -89,6 +89,12 @@ OPTIONS --glob:: Use `glob(7)` patterns with --match, this is the default. +-E:: +--extended-regexp:: +-G:: +--basic-regexp:: + Use POSIX extended/basic regexp for patterns with --match. + -P:: --perl-regexp:: Use Perl-compatible regexp for patterns with --match. Requires diff --git a/builtin/describe.c b/builtin/describe.c index d9ab5bd..3bff610 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -9,6 +9,7 @@ #include "diff.h" #include "hashmap.h" #include "argv-array.h" +#include <regex.h> #ifdef USE_LIBPCRE #include <pcre.h> @@ -25,6 +26,8 @@ static const char * const describe_usage[] = { enum match_type { MATCH_GLOB = 0, + MATCH_BRE, + MATCH_ERE, MATCH_PCRE }; @@ -41,6 +44,7 @@ static const char *pattern; static int always; static const char *dirty; static enum match_type pattern_type_arg = MATCH_GLOB; +static regex_t posix_regex; #ifdef USE_LIBPCRE static pcre *pcre_regex = NULL; @@ -134,6 +138,27 @@ static void add_to_known_names(const char *path, } } +static void re_init(enum match_type type) +{ + int cflags = REG_NOSUB; + if (type == MATCH_ERE) + cflags |= REG_EXTENDED; + + if (regcomp(&posix_regex, pattern, cflags)) + die("Invalid regular expression: %s", pattern); +} + +static void re_cleanup() +{ + regfree(&posix_regex); +} + +/* return 1 on match, 0 on no match. */ +static int posix_re_match(const char *text) +{ + return regexec(&posix_regex, text, 0, NULL, 0) != 0; +} + #ifdef USE_LIBPCRE static void pcre_init() { @@ -180,6 +205,8 @@ static int match(const char *pattern, const char *text, enum match_type t) { if (t == MATCH_GLOB) { return wildmatch(pattern, text, 0, NULL); + } else if (t == MATCH_ERE || t == MATCH_BRE) { + return posix_re_match(text); #ifdef USE_LIBPCRE } else if (t == MATCH_PCRE) { return pcre_match(text); @@ -479,6 +506,12 @@ int cmd_describe(int argc, const char **argv, const char *prefix) OPT_SET_INT(0, "glob", &pattern_type_arg, N_("use glob patterns with --match (default)"), MATCH_GLOB), + OPT_SET_INT('E', "extended-regexp", &pattern_type_arg, + N_("use extended POSIX regular expressions with --match"), + MATCH_ERE), + OPT_SET_INT('G', "basic-regexp", &pattern_type_arg, + N_("use basic POSIX regular expressions with --match"), + MATCH_BRE), #ifdef USE_LIBPCRE OPT_SET_INT('P', "perl-regexp", &pattern_type_arg, N_("use Perl-compatible regular expressions with --match"), @@ -507,6 +540,10 @@ int cmd_describe(int argc, const char **argv, const char *prefix) if (longformat && abbrev == 0) die(_("--long is incompatible with --abbrev=0")); + if (pattern && (pattern_type_arg == MATCH_ERE || + pattern_type_arg == MATCH_BRE)) + re_init(pattern_type_arg); + #ifdef USE_LIBPCRE if (pattern && pattern_type_arg == MATCH_PCRE) pcre_init(); @@ -538,6 +575,10 @@ int cmd_describe(int argc, const char **argv, const char *prefix) if (!names.size && !always) die(_("No names found, cannot describe anything.")); + if (pattern && (pattern_type_arg == MATCH_ERE || + pattern_type_arg == MATCH_BRE)) + re_cleanup(); + #ifdef USE_LIBPCRE if (pattern && pattern_type_arg == MATCH_PCRE) pcre_cleanup(); diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh index 47427c4..e3d8663 100755 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@ -184,17 +184,31 @@ test_expect_success 'set-up matching pattern tests' ' ' check_describe "test-annotated-*" --match="test-*" +check_describe "test-annotated-*" --match="^test-" --basic-regexp +check_describe "test-annotated-*" --match="^test-" --extended-regexp check_describe_pcre "test-annotated-*" --match="^test-" --perl-regexp check_describe "test1-lightweight-*" --tags --match="test1-*" +check_describe "test1-lightweight-*" --tags --match="^test1-" \ + --extended-regexp +check_describe "test1-lightweight-*" --tags --match="^test1-" \ + --basic-regexp check_describe_pcre "test1-lightweight-*" --tags --match="^test1-" \ --perl-regexp check_describe "test2-lightweight-*" --tags --match="test2-*" +check_describe "test2-lightweight-*" --tags --match="^test2-" \ + --extended-regexp +check_describe "test2-lightweight-*" --tags --match="^test2-" \ + --basic-regexp check_describe_pcre "test2-lightweight-*" --tags --match="^test2-" \ --perl-regexp check_describe "test2-lightweight-*" --long --tags --match="test2-*" HEAD^ +check_describe "test2-lightweight-*" --long --tags --match="test2-*" \ + --extended-regexp HEAD^ +check_describe "test2-lightweight-*" --long --tags --match="test2-*" \ + --basic-regexp HEAD^ check_describe_pcre "test2-lightweight-*" --long --tags --match="^test2-" \ --perl-regexp HEAD^ -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html