{"thread":{"id":"22392","subject":"[PATCH] grep: expose \"status-only\" feature via -q","startedAt":"2010-01-25T23:37:23Z","lastAt":"2010-01-28T20:27:58Z","messageCount":3,"participants":["Junio C Hamano","Stephen Boyd"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"132646","messageId":"7vk4v53gek.fsf@alter.siamese.dyndns.org","threadId":"22392","inReplyTo":null,"subject":"[PATCH] grep: expose \"status-only\" feature via -q","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-25T23:37:23Z","receivedAt":"2010-01-25T23:37:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Teach \"git grep\" a new \"-q\" option to report the presense of a match via\nits exit status without showing any output, similar to how \"grep -q\"\nworks.  Internally \"grep\" engine already knew this \"status-only\" mode of\noperation because it needed to grep inside log message to filter commits\nwhen called from the \"git log\" machinery, and this patch only exposes it\nto the command line tool.\n\nA somewhat unfair benchmark in the Linux kernel directory shows a dramatic\nimprovement:\n\n    (with patch)\n    $ time ../git.git/git grep -q linux HEAD ; echo $?\n\n    real    0m0.030s\n    user    0m0.004s\n    sys     0m0.004s\n    0\n\n    (without patch)\n    $ time git grep linux HEAD >/dev/null; echo $?\n\n    real    0m4.432s\n    user    0m4.272s\n    sys     0m0.076s\n    0\n\nThis is \"somewhat unfair\" because I knew a file with such a string comes\nvery early in the tree traversal (namely, \".gitignore\").\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-grep.c |   16 ++++++++++++++--\n 1 files changed, 14 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin-grep.c b/builtin-grep.c\nindex da854fa..64cdfef 100644\n--- a/builtin-grep.c\n+++ b/builtin-grep.c\n@@ -236,6 +236,8 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached)\n \t\t\t\t !strcmp(ce->name, active_cache[nr]->name));\n \t\t\tnr--; /* compensate for loop control */\n \t\t}\n+\t\tif (hit && opt->status_only)\n+\t\t\tbreak;\n \t}\n \tfree_grep_patterns(opt);\n \treturn hit;\n@@ -293,6 +295,8 @@ static int grep_tree(struct grep_opt *opt, const char **paths,\n \t\t\thit |= grep_tree(opt, paths, &sub, tree_name, down);\n \t\t\tfree(data);\n \t\t}\n+\t\tif (hit && opt->status_only)\n+\t\t\tbreak;\n \t}\n \tstrbuf_release(&pathbuf);\n \treturn hit;\n@@ -329,8 +333,11 @@ static int grep_directory(struct grep_opt *opt, const char **paths)\n \tsetup_standard_excludes(&dir);\n \n \tfill_directory(&dir, paths);\n-\tfor (i = 0; i < dir.nr; i++)\n+\tfor (i = 0; i < dir.nr; i++) {\n \t\thit |= grep_file(opt, dir.entries[i]->name);\n+\t\tif (hit && opt->status_only)\n+\t\t\tbreak;\n+\t}\n \tfree_grep_patterns(opt);\n \treturn hit;\n }\n@@ -505,6 +512,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \t\t{ OPTION_CALLBACK, ')', NULL, &opt, NULL, \"\",\n \t\t  PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,\n \t\t  close_callback },\n+\t\tOPT_BOOLEAN('q', \"quick\", &opt.status_only,\n+\t\t\t    \"indicate hit with exit status without output\"),\n \t\tOPT_BOOLEAN(0, \"all-match\", &opt.all_match,\n \t\t\t\"show only matches from files that match all patterns\"),\n \t\tOPT_GROUP(\"\"),\n@@ -628,8 +637,11 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \tfor (i = 0; i < list.nr; i++) {\n \t\tstruct object *real_obj;\n \t\treal_obj = deref_tag(list.objects[i].item, NULL, 0);\n-\t\tif (grep_object(&opt, paths, real_obj, list.objects[i].name))\n+\t\tif (grep_object(&opt, paths, real_obj, list.objects[i].name)) {\n \t\t\thit = 1;\n+\t\t\tif (opt.status_only)\n+\t\t\t\tbreak;\n+\t\t}\n \t}\n \tfree_grep_patterns(&opt);\n \treturn !hit;\n"},{"id":"132896","messageId":"4B61BC02.3070408@gmail.com","threadId":"22392","inReplyTo":"7vk4v53gek.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] grep: expose \"status-only\" feature via -q","fromName":"Stephen Boyd","fromEmail":"bebarino@gmail.com","sentAt":"2010-01-28T16:32:02Z","receivedAt":"2010-01-28T16:32:02Z","isPatch":true,"sender":{"key":"bebarino@gmail.com","avatar":"https://avatars.githubusercontent.com/u/38832?v=4"},"body":"On 01/25/2010 03:37 PM, Junio C Hamano wrote:\n> @@ -505,6 +512,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n>   \t\t{ OPTION_CALLBACK, ')', NULL,&opt, NULL, \"\",\n>   \t\t  PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,\n>   \t\t  close_callback },\n> +\t\tOPT_BOOLEAN('q', \"quick\",&opt.status_only,\n> +\t\t\t    \"indicate hit with exit status without output\"),\n>\n\nWhy isn't this --quiet just like grep? I think this might be mistaken \nfor enabling threads or some fancy algorithm to go faster.\n"},{"id":"132907","messageId":"7viqamkm9d.fsf@alter.siamese.dyndns.org","threadId":"22392","inReplyTo":"4B61BC02.3070408@gmail.com","subject":"Re: [PATCH] grep: expose \"status-only\" feature via -q","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-28T20:27:58Z","receivedAt":"2010-01-28T20:27:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stephen Boyd <bebarino@gmail.com> writes:\n\n> On 01/25/2010 03:37 PM, Junio C Hamano wrote:\n>> @@ -505,6 +512,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n>>   \t\t{ OPTION_CALLBACK, ')', NULL,&opt, NULL, \"\",\n>>   \t\t  PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,\n>>   \t\t  close_callback },\n>> +\t\tOPT_BOOLEAN('q', \"quick\",&opt.status_only,\n>> +\t\t\t    \"indicate hit with exit status without output\"),\n>>\n>\n> Why isn't this --quiet just like grep?\n\nBecause I wasn't careful enough.  Thanks; will fix.\n"}]}