{"thread":{"id":"8578","subject":"[PATCH] Interpret :/<pattern> as a regular expression","startedAt":"2007-06-13T00:50:22Z","lastAt":"2007-06-14T09:07:40Z","messageCount":14,"participants":["Johannes Schindelin","Junio C Hamano","Jeff King","Sam Vilain"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"44882","messageId":"Pine.LNX.4.64.0706130148080.4059@racer.site","threadId":"8578","inReplyTo":null,"subject":"[PATCH] Interpret :/<pattern> as a regular expression","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-13T00:50:22Z","receivedAt":"2007-06-13T00:50:22Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nEarlier, Git interpreted the pattern as a strict prefix, which made\nthe operator unsuited in many cases.\n\nNow, the pattern is interpreted as a regular expression (which does not \nchange the behaviour too much, since few onelines contain special regex \ncharacters), so that you can say\n\n\tgit diff :/.*^Signed-off-by:.Zack.Brown\n\nto see the diff against the most recent reachable commit which was\nsigned off by Zack, whose Kernel Cousin I miss very much.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tFor fun, you can see which committer signed himself off:\n\n\t\tgit show :/.*^Signed-off:\n\n\t*grin*\n\n sha1_name.c |    9 ++++++++-\n 1 files changed, 8 insertions(+), 1 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex d9188ed..f1ba194 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -611,6 +611,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)\n {\n \tstruct commit_list *list = NULL, *backup = NULL, *l;\n \tint retval = -1;\n+\tregex_t regexp;\n+\tregmatch_t regmatch[1];\n \n \tif (prefix[0] == '!') {\n \t\tif (prefix[1] != '!')\n@@ -622,6 +624,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)\n \tfor_each_ref(handle_one_ref, &list);\n \tfor (l = list; l; l = l->next)\n \t\tcommit_list_insert(l->item, &backup);\n+\tif (regcomp(&regexp, prefix, REG_EXTENDED))\n+\t\treturn error(\"invalid regexp: %s\", prefix);\n \twhile (list) {\n \t\tchar *p;\n \t\tstruct commit *commit;\n@@ -630,7 +634,9 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)\n \t\tparse_object(commit->object.sha1);\n \t\tif (!commit->buffer || !(p = strstr(commit->buffer, \"\\n\\n\")))\n \t\t\tcontinue;\n-\t\tif (!prefixcmp(p + 2, prefix)) {\n+\t\tif (!regexec(&regexp, p + 2, 1, regmatch, 0) &&\n+\t\t\t\tprintf(\"match: %d\\n\", regmatch[0].rm_so) &&\n+\t\t\t\tregmatch[0].rm_so == 0) {\n \t\t\thashcpy(sha1, commit->object.sha1);\n \t\t\tretval = 0;\n \t\t\tbreak;\n@@ -639,6 +645,7 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)\n \tfree_commit_list(list);\n \tfor (l = backup; l; l = l->next)\n \t\tclear_commit_marks(l->item, ONELINE_SEEN);\n+\tregfree(&regexp);\n \treturn retval;\n }\n \n-- \n1.5.2.1.2827.gba84a8-dirty\n"},{"id":"44883","messageId":"7v1wggir80.fsf@assigned-by-dhcp.pobox.com","threadId":"8578","inReplyTo":"Pine.LNX.4.64.0706130148080.4059@racer.site","subject":"Re: [PATCH] Interpret :/<pattern> as a regular expression","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-06-13T01:21:51Z","receivedAt":"2007-06-13T01:21:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Earlier, Git interpreted the pattern as a strict prefix, which made\n> the operator unsuited in many cases.\n>\n> Now, the pattern is interpreted as a regular expression (which does not \n> change the behaviour too much, since few onelines contain special regex \n> characters), so that you can say\n>\n> \tgit diff :/.*^Signed-off-by:.Zack.Brown\n>\n> to see the diff against the most recent reachable commit which was\n> signed off by Zack, whose Kernel Cousin I miss very much.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nWhile this perhaps is an improvement and people who are not\ninterested in paying the price have a choice of not using this\nsilly syntax, I am moderately annoyed that the syntax does not\ndefine \"the most recent reachable\" very well.  It is more like\n\"the first one we happened to pick by diffing from reachable\nrefs\".  It would be more useful if it took \"$commit:/$pattern\"\nform to limit the search among reachable ones from named commit.\n"},{"id":"44884","messageId":"7vr6ogh2w7.fsf@assigned-by-dhcp.pobox.com","threadId":"8578","inReplyTo":"Pine.LNX.4.64.0706130148080.4059@racer.site","subject":"Re: [PATCH] Interpret :/<pattern> as a regular expression","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-06-13T04:52:40Z","receivedAt":"2007-06-13T04:52:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> diff --git a/sha1_name.c b/sha1_name.c\n> index d9188ed..f1ba194 100644\n> --- a/sha1_name.c\n> +++ b/sha1_name.c\n> @@ -611,6 +611,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)\n>  {\n>  \tstruct commit_list *list = NULL, *backup = NULL, *l;\n>  \tint retval = -1;\n> +\tregex_t regexp;\n> +\tregmatch_t regmatch[1];\n>  \n>  \tif (prefix[0] == '!') {\n>  \t\tif (prefix[1] != '!')\n\nBecause you are not extracting any match substring, I do not\nthink you would need regmatch[] there.\n\n> @@ -622,6 +624,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)\n>  \tfor_each_ref(handle_one_ref, &list);\n>  \tfor (l = list; l; l = l->next)\n>  \t\tcommit_list_insert(l->item, &backup);\n> +\tif (regcomp(&regexp, prefix, REG_EXTENDED))\n> +\t\treturn error(\"invalid regexp: %s\", prefix);\n>  \twhile (list) {\n>  \t\tchar *p;\n>  \t\tstruct commit *commit;\n\nWhy EXTENDED?\n\nI think our code prefer traditional regexp by default, but in\nplaces where extended behaviour is truly useful (e.g. grepping\nfor bulk of text) have command line option to enable extended.\nOf course, extended SHA-1 notation has no chance to do \"command\nline option\", but it somehow feels inconsistent.\n\nAlso you probably want REG_NEWLINE.\n\n> @@ -630,7 +634,9 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)\n>  \t\tparse_object(commit->object.sha1);\n>  \t\tif (!commit->buffer || !(p = strstr(commit->buffer, \"\\n\\n\")))\n>  \t\t\tcontinue;\n> -\t\tif (!prefixcmp(p + 2, prefix)) {\n> +\t\tif (!regexec(&regexp, p + 2, 1, regmatch, 0) &&\n> +\t\t\t\tprintf(\"match: %d\\n\", regmatch[0].rm_so) &&\n> +\t\t\t\tregmatch[0].rm_so == 0) {\n>  \t\t\thashcpy(sha1, commit->object.sha1);\n>  \t\t\tretval = 0;\n>  \t\t\tbreak;\n\nDo we want to detect return value other than REG_NOMATCH from\nregexec() when it does not return zero?\n\nPlease lose the debugging printf() before submitting.\n\n> @@ -639,6 +645,7 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)\n>  \tfree_commit_list(list);\n>  \tfor (l = backup; l; l = l->next)\n>  \t\tclear_commit_marks(l->item, ONELINE_SEEN);\n> +\tregfree(&regexp);\n>  \treturn retval;\n>  }\n>  \n\nAlso I think you would want to fix get_sha1_oneline() so that it\nnot to refuse to work without save_commit_buffer.  These are to\nparse user supplied strings (it would be crazy for scripts to\nthrow hundreds of ':/random string' to drive git -- it must come\nfrom the end user), and the user has every right to use this\nsyntax, if he wants to, to specify the starting point for a\ncommand that deliberately turns off save_commit_buffer to save\nmemory, because the command knows ithat t will traverse tons of\ncommits without needing the contents of the commit buffer.\n\nAfter parse_object(), if commit->buffer is NULL, read the buffer\nwith read_sha1_file() yourself to look for match (and if you did\nso you are also responsible for discarding it yourself).\n"},{"id":"44918","messageId":"Pine.LNX.4.64.0706131143590.4059@racer.site","threadId":"8578","inReplyTo":"7vr6ogh2w7.fsf@assigned-by-dhcp.pobox.com","subject":"Re: [PATCH] Interpret :/<pattern> as a regular expression","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-13T11:10:42Z","receivedAt":"2007-06-13T11:10:42Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 12 Jun 2007, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > diff --git a/sha1_name.c b/sha1_name.c\n> > index d9188ed..f1ba194 100644\n> > --- a/sha1_name.c\n> > +++ b/sha1_name.c\n> > @@ -611,6 +611,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)\n> >  {\n> >  \tstruct commit_list *list = NULL, *backup = NULL, *l;\n> >  \tint retval = -1;\n> > +\tregex_t regexp;\n> > +\tregmatch_t regmatch[1];\n> >  \n> >  \tif (prefix[0] == '!') {\n> >  \t\tif (prefix[1] != '!')\n> \n> Because you are not extracting any match substring, I do not\n> think you would need regmatch[] there.\n\nI explicitely want to anchor the match at the beginning of the message \n(otherwise, most of the interesting patterns would match a merge pulling \nthat commit in), and therefore I have to check where the match was. Alas, \nthat's only possible with regmatch.\n\n> > @@ -622,6 +624,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)\n> >  \tfor_each_ref(handle_one_ref, &list);\n> >  \tfor (l = list; l; l = l->next)\n> >  \t\tcommit_list_insert(l->item, &backup);\n> > +\tif (regcomp(&regexp, prefix, REG_EXTENDED))\n> > +\t\treturn error(\"invalid regexp: %s\", prefix);\n> >  \twhile (list) {\n> >  \t\tchar *p;\n> >  \t\tstruct commit *commit;\n> \n> Why EXTENDED?\n\nSorry. Old habit. Will fix.\n\n> Also you probably want REG_NEWLINE.\n\nNo. If I look for something in the body of the message (like I showed in \nthe two examples), I'd like to say ':/.*Blub'. Of course, you could always \nsay\n\n\tgit diff ':/[ -~\n]*Blub'\n\nwith REG_NEWLINE, to match newlines also. But frankly, it is much more \noften that I want to match something in the whole message than just in the \noneline. And if I _do_ want the match only in the oneline, I can still go \nand do\n\n\tgit diff ':/[^\n]*Blub'\n\nwhen REG_NEWLINE is disabled. If you can teach me a better way to do both \nthings, matching in the oneline _or_ matching the whole message, _with_ \nREG_NEWLINE, I'll gladly change it, and provide an example in the commit \nmessage as well as the documentation for equally clueless subjects as me.\n\n> > @@ -630,7 +634,9 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)\n> >  \t\tparse_object(commit->object.sha1);\n> >  \t\tif (!commit->buffer || !(p = strstr(commit->buffer, \"\\n\\n\")))\n> >  \t\t\tcontinue;\n> > -\t\tif (!prefixcmp(p + 2, prefix)) {\n> > +\t\tif (!regexec(&regexp, p + 2, 1, regmatch, 0) &&\n> > +\t\t\t\tprintf(\"match: %d\\n\", regmatch[0].rm_so) &&\n> > +\t\t\t\tregmatch[0].rm_so == 0) {\n> >  \t\t\thashcpy(sha1, commit->object.sha1);\n> >  \t\t\tretval = 0;\n> >  \t\t\tbreak;\n> \n> Do we want to detect return value other than REG_NOMATCH from\n> regexec() when it does not return zero?\n\nI am not well versed in the multitude of POSIX and other standards we have \non this planet, therefore I just read my man page. And it says, quote:\n\n\tregexec() returns zero for a successful match or REG_NOMATCH for \n\tfailure.\n\nTertium non datur. At least according to my man page here. Am I mistaken \nin my assumption (which seems to be somewhat supported from my limited \nreading of the man page) that all errors should be caught at regcomp() \ntime?\n\n> Please lose the debugging printf() before submitting.\n\nOuch. Sorry.\n\n> > @@ -639,6 +645,7 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)\n> >  \tfree_commit_list(list);\n> >  \tfor (l = backup; l; l = l->next)\n> >  \t\tclear_commit_marks(l->item, ONELINE_SEEN);\n> > +\tregfree(&regexp);\n> >  \treturn retval;\n> >  }\n> >  \n> \n> Also I think you would want to fix get_sha1_oneline() so that it\n> not to refuse to work without save_commit_buffer.\n\nYou're right, will fix.\n\nI'll resubmit shortly. However, feel free to enlighten me with insights \ninto working _with_ REG_NEWLINE, and I'll gladly submit another version of \nthe patch with REG_NEWLINE enabled, along with the additions to the \ndocumentation.\n\nThanks,\nDscho\n"},{"id":"44919","messageId":"Pine.LNX.4.64.0706131214010.4059@racer.site","threadId":"8578","inReplyTo":"7vr6ogh2w7.fsf@assigned-by-dhcp.pobox.com","subject":"(unknown)","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-13T11:17:34Z","receivedAt":"2007-06-13T11:17:34Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"[PATCH] Interpret :/<pattern> as a regular expression\n\nEarlier, Git interpreted the pattern as a strict prefix, which made\nthe operator unsuited in many cases.\n\nNow, the pattern is interpreted as a regular expression, on the whole\nmessage, so that you can say\n\n\tgit diff :/.*^Signed-off-by:.Zack.Brown\n\nto see the diff against the most recent reachable commit which was\nsigned off by Zack, whose Kernel Cousin I miss very much.\n\nIf you want to match just the oneline, but with a regular expression,\nsay something like\n\n\tgit diff ':/[^\n]*intelligent'\n\nSince it makes more sense to match the beginning of a message (otherwise,\na pattern like ':/git-gui: Improve' would match the _merge_ commit, \npulling in the commit you are likely to want), the implementation uses the \nregmatch parameter of regexec() to anchor the pattern there.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tAnyone who can teach me how to match / not-match a newline\n\tusing a more elegant syntax, please do so, by all means.\n\n Documentation/git-rev-parse.txt |    6 +++---\n sha1_name.c                     |   31 +++++++++++++++++++++++++------\n 2 files changed, 28 insertions(+), 9 deletions(-)\n\ndiff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt\nindex 6380676..56e1561 100644\n--- a/Documentation/git-rev-parse.txt\n+++ b/Documentation/git-rev-parse.txt\n@@ -194,9 +194,9 @@ blobs contained in a commit.\n   found.\n \n * A colon, followed by a slash, followed by a text: this names\n-  a commit whose commit message starts with the specified text.\n-  This name returns the youngest matching commit which is\n-  reachable from any ref.  If the commit message starts with a\n+  a commit whose commit message starts with the specified regular\n+  expression.  This name returns the youngest matching commit which\n+  is reachable from any ref.  If the commit message starts with a\n   '!', you have to repeat that;  the special sequence ':/!',\n   followed by something else than '!' is reserved for now.\n \ndiff --git a/sha1_name.c b/sha1_name.c\nindex d9188ed..988d599 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -599,8 +599,8 @@ static int handle_one_ref(const char *path,\n \n /*\n  * This interprets names like ':/Initial revision of \"git\"' by searching\n- * through history and returning the first commit whose message starts\n- * with the given string.\n+ * through history and returning the first commit whose message matches\n+ * the given regular expression.\n  *\n  * For future extension, ':/!' is reserved. If you want to match a message\n  * beginning with a '!', you have to repeat the exclamation mark.\n@@ -611,34 +611,53 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)\n {\n \tstruct commit_list *list = NULL, *backup = NULL, *l;\n \tint retval = -1;\n+\tregex_t regexp;\n+\tregmatch_t regmatch[1];\n+\tchar *temp_commit_buffer = NULL;\n \n \tif (prefix[0] == '!') {\n \t\tif (prefix[1] != '!')\n \t\t\tdie (\"Invalid search pattern: %s\", prefix);\n \t\tprefix++;\n \t}\n-\tif (!save_commit_buffer)\n-\t\treturn error(\"Could not expand oneline-name.\");\n \tfor_each_ref(handle_one_ref, &list);\n \tfor (l = list; l; l = l->next)\n \t\tcommit_list_insert(l->item, &backup);\n+\tif (regcomp(&regexp, prefix, 0))\n+\t\treturn error(\"invalid regexp: %s\", prefix);\n \twhile (list) {\n \t\tchar *p;\n \t\tstruct commit *commit;\n+\t\tenum object_type type;\n+\t\tunsigned long size;\n \n \t\tcommit = pop_most_recent_commit(&list, ONELINE_SEEN);\n \t\tparse_object(commit->object.sha1);\n-\t\tif (!commit->buffer || !(p = strstr(commit->buffer, \"\\n\\n\")))\n+\t\tif (temp_commit_buffer)\n+\t\t\tfree(temp_commit_buffer);\n+\t\tif (commit->buffer)\n+\t\t\tp = commit->buffer;\n+\t\telse {\n+\t\t\tp = read_sha1_file(commit->object.sha1, &type, &size);\n+\t\t\tif (!p)\n+\t\t\t\tcontinue;\n+\t\t\ttemp_commit_buffer = p;\n+\t\t}\n+\t\tif (!(p = strstr(p, \"\\n\\n\")))\n \t\t\tcontinue;\n-\t\tif (!prefixcmp(p + 2, prefix)) {\n+\t\tif (!regexec(&regexp, p + 2, 1, regmatch, 0) &&\n+\t\t\t\tregmatch[0].rm_so == 0) {\n \t\t\thashcpy(sha1, commit->object.sha1);\n \t\t\tretval = 0;\n \t\t\tbreak;\n \t\t}\n \t}\n+\tif (temp_commit_buffer)\n+\t\tfree(temp_commit_buffer);\n \tfree_commit_list(list);\n \tfor (l = backup; l; l = l->next)\n \t\tclear_commit_marks(l->item, ONELINE_SEEN);\n+\tregfree(&regexp);\n \treturn retval;\n }\n \n-- \n1.5.2.1.2827.gba84a8-dirty\n"},{"id":"44923","messageId":"Pine.LNX.4.64.0706131310290.4059@racer.site","threadId":"8578","inReplyTo":"Pine.LNX.4.64.0706131214010.4059@racer.site","subject":"[PATCH] Interpret :/<pattern> as a regular expression","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-13T12:11:18Z","receivedAt":"2007-06-13T12:11:18Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nI don't know what happened to my subject in the mail I'm replying to... \nSorry.\n\nCiao,\nDscho\n"},{"id":"44929","messageId":"Pine.LNX.4.64.0706131412320.4059@racer.site","threadId":"8578","inReplyTo":"7v1wggir80.fsf@assigned-by-dhcp.pobox.com","subject":"Re: [PATCH] Interpret :/<pattern> as a regular expression","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-13T13:13:45Z","receivedAt":"2007-06-13T13:13:45Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 12 Jun 2007, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > Earlier, Git interpreted the pattern as a strict prefix, which made\n> > the operator unsuited in many cases.\n> >\n> > Now, the pattern is interpreted as a regular expression (which does not \n> > change the behaviour too much, since few onelines contain special regex \n> > characters), so that you can say\n> >\n> > \tgit diff :/.*^Signed-off-by:.Zack.Brown\n> >\n> > to see the diff against the most recent reachable commit which was\n> > signed off by Zack, whose Kernel Cousin I miss very much.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> \n> While this perhaps is an improvement and people who are not\n> interested in paying the price have a choice of not using this\n> silly syntax, I am moderately annoyed that the syntax does not\n> define \"the most recent reachable\" very well.  It is more like\n> \"the first one we happened to pick by diffing from reachable\n> refs\".  It would be more useful if it took \"$commit:/$pattern\"\n> form to limit the search among reachable ones from named commit.\n\n\"Unfortunately\", $commit:/$pattern is not a good syntax, since it suggests \nthat you want to search _in_ $commit, not _from $commit.\n\nHow about ':/!commit=$commit:$pattern'?\n\nCiao,\nDscho\n"},{"id":"44986","messageId":"20070613184109.GG10941@coredump.intra.peff.net","threadId":"8578","inReplyTo":"Pine.LNX.4.64.0706130148080.4059@racer.site","subject":"Re: [PATCH] Interpret :/<pattern> as a regular expression","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-06-13T18:41:10Z","receivedAt":"2007-06-13T18:41:10Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jun 13, 2007 at 01:50:22AM +0100, Johannes Schindelin wrote:\n\n> Earlier, Git interpreted the pattern as a strict prefix, which made\n> the operator unsuited in many cases.\n\nThank you for working on this...I really like the :/ concept, but find\nmyself wishing for a regex all the time. I have been meaning to do it\nsince you introduced the original. :)\n\n-Peff\n"},{"id":"44989","messageId":"Pine.LNX.4.64.0706131953370.4059@racer.site","threadId":"8578","inReplyTo":"20070613184109.GG10941@coredump.intra.peff.net","subject":"Re: [PATCH] Interpret :/<pattern> as a regular expression","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-13T18:54:59Z","receivedAt":"2007-06-13T18:54:59Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 13 Jun 2007, Jeff King wrote:\n\n> On Wed, Jun 13, 2007 at 01:50:22AM +0100, Johannes Schindelin wrote:\n> \n> > Earlier, Git interpreted the pattern as a strict prefix, which made\n> > the operator unsuited in many cases.\n> \n> Thank you for working on this...I really like the :/ concept, but find\n> myself wishing for a regex all the time. I have been meaning to do it\n> since you introduced the original. :)\n\n:-) Since you seem comfortable with regular expressions, maybe you can \nhelp me: I am looking for a pattern which matches _any_ character, and one \nwhich matches only non-newlines, both with and without REG_NEWLINE. Hmm?\n\nTia,\nDscho\n"},{"id":"44995","messageId":"20070613200011.GA17360@coredump.intra.peff.net","threadId":"8578","inReplyTo":"Pine.LNX.4.64.0706131953370.4059@racer.site","subject":"Re: [PATCH] Interpret :/<pattern> as a regular expression","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2007-06-13T20:00:11Z","receivedAt":"2007-06-13T20:00:11Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jun 13, 2007 at 07:54:59PM +0100, Johannes Schindelin wrote:\n\n> :-) Since you seem comfortable with regular expressions, maybe you can \n> help me: I am looking for a pattern which matches _any_ character, and one \n> which matches only non-newlines, both with and without REG_NEWLINE. Hmm?\n\nWithout REG_NEWLINE, any character is just '.', but I think you are\nstuck with '[^\n]' for non-newlines, since POSIX makes no provisions for quoting the\nnewline (I just skimmed through POSIX chapter 9, and I didn't see\nanything useful).\n\nWith REG_NEWLINE, non-newlines is of course '.'. Matching both is tricky\nwithout using extended regular expressions (where you could just do '.|\n'). In fact, I have been playing with it for a few minutes and I can't\nseem to find a good way, since you really want to represent '.' _inside_\na bracketed alternation sequence. But I don't think there's a character\nclass for \"everything\".\n\nI think this would be much easier with pcre, but ISTR some opposition to\nthat a few months back.\n\nSo that's probably not very helpful to you, but at least you have\nconfirmation from one other person that the answer isn't totally\nobvious. :)\n\n-Peff\n"},{"id":"45009","messageId":"Pine.LNX.4.64.0706132317240.4059@racer.site","threadId":"8578","inReplyTo":"20070613200011.GA17360@coredump.intra.peff.net","subject":"Re: [PATCH] Interpret :/<pattern> as a regular expression","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-13T22:20:43Z","receivedAt":"2007-06-13T22:20:43Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Wed, 13 Jun 2007, Jeff King wrote:\n\n> On Wed, Jun 13, 2007 at 07:54:59PM +0100, Johannes Schindelin wrote:\n> \n> > :-) Since you seem comfortable with regular expressions, maybe you can \n> > help me: I am looking for a pattern which matches _any_ character, and one \n> > which matches only non-newlines, both with and without REG_NEWLINE. Hmm?\n> \n> Without REG_NEWLINE, any character is just '.', but I think you are\n> stuck with '[^\n> ]' for non-newlines, since POSIX makes no provisions for quoting the\n> newline (I just skimmed through POSIX chapter 9, and I didn't see\n> anything useful).\n> \n> With REG_NEWLINE, non-newlines is of course '.'. Matching both is tricky\n> without using extended regular expressions (where you could just do '.|\n> '). In fact, I have been playing with it for a few minutes and I can't\n> seem to find a good way, since you really want to represent '.' _inside_\n> a bracketed alternation sequence. But I don't think there's a character\n> class for \"everything\".\n> \n> I think this would be much easier with pcre, but ISTR some opposition to\n> that a few months back.\n\nActually, that's funny. Yesterday, I repeated my claim that pcre is \nslow on IRC, and Sam Villain on IRC accused me of trolling. But as you can \nsee from my postings on this list ($gmane/41682), you can see that _I_ had \nnumbers to back up my claim.\n\nSo no, I think pcre is just not worth it.\n\n> So that's probably not very helpful to you, but at least you have\n> confirmation from one other person that the answer isn't totally\n> obvious. :)\n\nThat confirmation is at least some consolation to me :-)\n\nCiao,\nDscho \"who is not here to teach, but to learn\"\n"},{"id":"45046","messageId":"4670F2BB.5060909@vilain.net","threadId":"8578","inReplyTo":"Pine.LNX.4.64.0706132317240.4059@racer.site","subject":"Re: [PATCH] Interpret :/<pattern> as a regular expression","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2007-06-14T07:48:11Z","receivedAt":"2007-06-14T07:48:11Z","isPatch":true,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"Johannes Schindelin wrote:\n> Actually, that's funny. Yesterday, I repeated my claim that pcre is \n> slow on IRC, and Sam Villain on IRC accused me of trolling. But as you can \n> see from my postings on this list ($gmane/41682), you can see that _I_ had \n> numbers to back up my claim.\n>\n> So no, I think pcre is just not worth it.\n>   \n\nA strange thing to conclude from your figures, which show pcre as the\nfastest out of several libraries that you tested.\n\nYour figures show exactly what I was saying on IRC - that a DFA\n(external grep) vs NFA engine (most regex libraries) is inherently\nfaster. The paper I linked to, specially selected as I had previously\nread a significant amount of the peer review the paper received,\nexplained this in detail. The one piece of feedback your numbers got\non-list also mentioned this.\n\nHowever there is a further flaw in your study. All but one of the\nperformance tests use an external program, which on a given system may\nor may not be faster because of pipeline performance characteristics.\nYou could improve the quality of the result by using the 'pcregrep'\nprogram as a data point. It might also be worth trying a few more\ncomplex patterns. I suggest reading the paper\n(http://swtch.com/~rsc/regexp/regexp1.html) for some background before\nrepeating the experiment.\n\nApologies for not reviewing your numbers at the time; it sure is hard to\nkeep on top of this list. But very interesting that they seem to suggest\npcre would be the best choice from a performance perspective, even\nthough the figures are very preliminary. Perhaps it is worth pursuing\nafter all.\n\nSam.\n"},{"id":"45051","messageId":"Pine.LNX.4.64.0706140909360.4059@racer.site","threadId":"8578","inReplyTo":"4670F2BB.5060909@vilain.net","subject":"Re: [PATCH] Interpret :/<pattern> as a regular expression","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-06-14T08:09:40Z","receivedAt":"2007-06-14T08:09:40Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 14 Jun 2007, Sam Vilain wrote:\n\n> Johannes Schindelin wrote:\n>\n> > So no, I think pcre is just not worth it.\n>\n> A strange thing to conclude from your figures, which show pcre as the \n> fastest out of several libraries that you tested.\n\nThe best of the worse. Yes. An external (!) program was 4x faster than \npcre. I don't know how to make it more obvious that pcre sucks.\n\nHth,\nDscho\n"},{"id":"45055","messageId":"4671055C.4050609@vilain.net","threadId":"8578","inReplyTo":"Pine.LNX.4.64.0706140909360.4059@racer.site","subject":"Re: [PATCH] Interpret :/<pattern> as a regular expression","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2007-06-14T09:07:40Z","receivedAt":"2007-06-14T09:07:40Z","isPatch":true,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"Johannes Schindelin wrote:\n>> A strange thing to conclude from your figures, which show pcre as the \n>> fastest out of several libraries that you tested.\n>>     \n>\n> The best of the worse. Yes. An external (!) program was 4x faster than \n> pcre. I don't know how to make it more obvious that pcre sucks.\n>   \n\nOh, your position is obvious enough, but it is correct and supportable\nby the available evidence? Why not read past the first paragraph of my\npost and reply to that.\n\nSam.\n"}]}