From 38318318502e77df284db6113b741c1d7ba5b43e Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 13 Jun 2007 01:45:22 +0100 Subject: [PATCH] Interpret :/ as a regular expression Earlier, Git interpreted the pattern as a strict prefix, which made the operator unsuited in many cases. Now, the pattern is interpreted as a regular expression, on the whole message, so that you can say git diff :/.*^Signed-off-by:.Zack.Brown to see the diff against the most recent reachable commit which was signed off by Zack, whose Kernel Cousin I miss very much. If you want to match just the oneline, but with a regular expression, say something like git diff ':/[^ ]*intelligent' Signed-off-by: Johannes Schindelin --- Documentation/git-rev-parse.txt | 6 +++--- sha1_name.c | 12 +++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index fc731525da..16239d63ac 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@ -275,9 +275,9 @@ when you run 'git merge'. found. * A colon, followed by a slash, followed by a text: this names - a commit whose commit message starts with the specified text. - This name returns the youngest matching commit which is - reachable from any ref. If the commit message starts with a + a commit whose commit message starts with the specified regular + expression. This name returns the youngest matching commit which + is reachable from any ref. If the commit message starts with a '!', you have to repeat that; the special sequence ':/!', followed by something else than '!' is reserved for now. diff --git a/sha1_name.c b/sha1_name.c index 77299257bf..3e075f6dce 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -680,8 +680,8 @@ static int handle_one_ref(const char *path, /* * This interprets names like ':/Initial revision of "git"' by searching - * through history and returning the first commit whose message starts - * with the given string. + * through history and returning the first commit whose message matches + * the given regular expression. * * For future extension, ':/!' is reserved. If you want to match a message * beginning with a '!', you have to repeat the exclamation mark. @@ -692,6 +692,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1) { struct commit_list *list = NULL, *backup = NULL, *l; int retval = -1; + regex_t regexp; + regmatch_t regmatch[1]; char *temp_commit_buffer = NULL; if (prefix[0] == '!') { @@ -702,6 +704,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1) for_each_ref(handle_one_ref, &list); for (l = list; l; l = l->next) commit_list_insert(l->item, &backup); + if (regcomp(®exp, prefix, 0)) + return error("invalid regexp: %s", prefix); while (list) { char *p; struct commit *commit; @@ -722,7 +726,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1) } if (!(p = strstr(p, "\n\n"))) continue; - if (!prefixcmp(p + 2, prefix)) { + if (!regexec(®exp, p + 2, 1, regmatch, 0) && + regmatch[0].rm_so == 0) { hashcpy(sha1, commit->object.sha1); retval = 0; break; @@ -732,6 +737,7 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1) free_commit_list(list); for (l = backup; l; l = l->next) clear_commit_marks(l->item, ONELINE_SEEN); + regfree(®exp); return retval; } -- 2.11.4.GIT