{"thread":{"id":"13399","subject":"[PATCH] git-grep: Add ability to limit directory recursion","startedAt":"2008-05-06T17:18:24Z","lastAt":"2008-05-07T01:34:17Z","messageCount":4,"participants":["Aidan Van Dyk","Jakub Narebski"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"76214","messageId":"1210094304-2450-1-git-send-email-aidan@highrise.ca","threadId":"13399","inReplyTo":null,"subject":"[PATCH] git-grep: Add ability to limit directory recursion","fromName":"Aidan Van Dyk","fromEmail":"aidan@highrise.ca","sentAt":"2008-05-06T17:18:24Z","receivedAt":"2008-05-06T17:18:24Z","isPatch":true,"sender":{"key":"aidan@highrise.ca","avatar":"https://gravatar.com/avatar/853c50d90cce753dc1c390fdc6cbed558f5f969bd43fa4f5cb0118d8f71316f6?d=mp&s=160"},"body":"This add a -R <limit> option to git-grep which will limit the depth of the\ndirectories recursed when git is doing a grep.\n\nThis allows you to do something like:\n        git grep -R 1 <pattern>\nand see only the results of the grep on files in the current directory.\n\nIt defaults to a limit of \"0\" which disables the limiting.\n---\n Documentation/git-grep.txt |    6 +++++\n builtin-grep.c             |   52 +++++++++++++++++++++++++++++++++++++++++--\n grep.h                     |    1 +\n 3 files changed, 56 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt\nindex a97f055..2f73c90 100644\n--- a/Documentation/git-grep.txt\n+++ b/Documentation/git-grep.txt\n@@ -97,6 +97,12 @@ OPTIONS\n -f <file>::\n \tRead patterns from <file>, one per line.\n \n+-R <limit>::\n+\tLimit the recursion depth when grepping.  A limit of 1 stops\n+\tthe grep from accessing any subdirectories from the specified\n+\ttree, cache, or working files.  A higher limit will limit the\n+\tfiles to N directories deep.\n+\n -e::\n \tThe next parameter is the pattern. This option has to be\n \tused for patterns starting with - and should be used in\ndiff --git a/builtin-grep.c b/builtin-grep.c\nindex ef29910..2877584 100644\n--- a/builtin-grep.c\n+++ b/builtin-grep.c\n@@ -343,6 +343,15 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)\n \t\t\tcontinue;\n \t\tif (!pathspec_matches(paths, ce->name))\n \t\t\tcontinue;\n+\t\tif (opt->recurse_limit) {\n+\t\t\tint d = 0;\n+\t\t\tconst char* cp = ce->name + ce_namelen(ce);\n+\t\t\twhile (--cp > ce->name)\n+\t\t\t\tif (*cp == '/' && opt->recurse_limit < ++d)\n+\t\t\t\t\tbreak;\n+\t\t\tif (opt->recurse_limit <= d)\n+\t\t\t\tcontinue;\n+\t\t}\n \t\tname = ce->name;\n \t\tif (name[0] == '-') {\n \t\t\tint len = ce_namelen(ce);\n@@ -399,6 +408,16 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached)\n \t\t\tcontinue;\n \t\tif (!pathspec_matches(paths, ce->name))\n \t\t\tcontinue;\n+\t\tif (opt->recurse_limit) {\n+\t\t\tint d = 0;\n+\t\t\tconst char* cp = ce->name + ce_namelen(ce);\n+\t\t\twhile (--cp > ce->name)\n+\t\t\t\tif (*cp == '/' && opt->recurse_limit < ++d)\n+\t\t\t\t\tbreak;\n+\t\t\tif (opt->recurse_limit <= d)\n+\t\t\t\tcontinue;\n+\t\t}\n+\n \t\tif (cached) {\n \t\t\tif (ce_stage(ce))\n \t\t\t\tcontinue;\n@@ -420,7 +439,8 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached)\n \n static int grep_tree(struct grep_opt *opt, const char **paths,\n \t\t     struct tree_desc *tree,\n-\t\t     const char *tree_name, const char *base)\n+\t\t     const char *tree_name, const char *base,\n+\t\t     int recurse_depth)\n {\n \tint len;\n \tint hit = 0;\n@@ -460,12 +480,17 @@ static int grep_tree(struct grep_opt *opt, const char **paths,\n \t\t\tvoid *data;\n \t\t\tunsigned long size;\n \n+\t\t\tif (opt->recurse_limit &&\n+\t\t\t\t\topt->recurse_limit <= recurse_depth)\n+\t\t\t\tcontinue;\n+\n \t\t\tdata = read_sha1_file(entry.sha1, &type, &size);\n \t\t\tif (!data)\n \t\t\t\tdie(\"unable to read tree (%s)\",\n \t\t\t\t    sha1_to_hex(entry.sha1));\n \t\t\tinit_tree_desc(&sub, data, size);\n-\t\t\thit |= grep_tree(opt, paths, &sub, tree_name, down);\n+\t\t\thit |= grep_tree(opt, paths, &sub, tree_name, down,\n+\t\t\t\t\trecurse_depth+1);\n \t\t\tfree(data);\n \t\t}\n \t}\n@@ -487,7 +512,7 @@ static int grep_object(struct grep_opt *opt, const char **paths,\n \t\tif (!data)\n \t\t\tdie(\"unable to read tree (%s)\", sha1_to_hex(obj->sha1));\n \t\tinit_tree_desc(&tree, data, size);\n-\t\thit = grep_tree(opt, paths, &tree, name, \"\");\n+\t\thit = grep_tree(opt, paths, &tree, name, \"\", 1);\n \t\tfree(data);\n \t\treturn hit;\n \t}\n@@ -499,6 +524,8 @@ static const char builtin_grep_usage[] =\n \n static const char emsg_invalid_context_len[] =\n \"%s: invalid context length argument\";\n+static const char emsg_invalid_recurse_limit[] =\n+\"%s: invalid recursion limit argument\";\n static const char emsg_missing_context_len[] =\n \"missing context length argument\";\n static const char emsg_missing_argument[] =\n@@ -704,6 +731,25 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \t\t\t}\n \t\t\tdie(emsg_missing_argument, arg);\n \t\t}\n+\t\tif (!strcmp(\"-R\", arg)) {\n+\t\t\tunsigned num;\n+\t\t\tconst char *scan;\n+\t\t\tif (1 < argc) {\n+\t\t\t\tint i;\n+\t\t\t\tscan = *++argv;\n+\t\t\t\targc--;\n+\t\t\t\tif (strtoul_ui(scan, 10, &num))\n+\t\t\t\t\tdie(emsg_invalid_recurse_limit, scan);\n+\t\t\t\topt.recurse_limit = num;\n+\t\t\t\t/* increase by the depth of the prefix */\n+\t\t\t\tif (prefix && *prefix)\n+\t\t\t\t\tfor (i = 0; i < strlen(prefix); i++)\n+\t\t\t\t\t\tif (prefix[i] == '/')\n+\t\t\t\t\t\t\topt.recurse_limit++;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tdie(emsg_missing_argument, arg);\n+\t\t}\n \t\tif (!strcmp(\"--full-name\", arg)) {\n \t\t\topt.relative = 0;\n \t\t\tcontinue;\ndiff --git a/grep.h b/grep.h\nindex d252dd2..b71dbf2 100644\n--- a/grep.h\n+++ b/grep.h\n@@ -51,6 +51,7 @@ struct grep_opt {\n \tstruct grep_pat **pattern_tail;\n \tstruct grep_expr *pattern_expression;\n \tint prefix_length;\n+\tint recurse_limit;\n \tregex_t regexp;\n \tunsigned linenum:1;\n \tunsigned invert:1;\n-- \n1.5.5.67.g9a49\n"},{"id":"76236","messageId":"m3iqxr54uy.fsf@localhost.localdomain","threadId":"13399","inReplyTo":"1210094304-2450-1-git-send-email-aidan@highrise.ca","subject":"Re: [PATCH] git-grep: Add ability to limit directory recursion","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-05-07T00:34:48Z","receivedAt":"2008-05-07T00:34:48Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Aidan Van Dyk <aidan@highrise.ca> writes:\n\n> This add a -R <limit> option to git-grep which will limit the depth of the\n> directories recursed when git is doing a grep.\n> \n> This allows you to do something like:\n>         git grep -R 1 <pattern>\n> and see only the results of the grep on files in the current directory.\n> \n> It defaults to a limit of \"0\" which disables the limiting.\n\nNice idea, although I'm not sure if we shouldn't borrow \"-maxdepth\"\noption from GNU find and friends...\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"76238","messageId":"20080507004719.GJ18081@yugib.highrise.ca","threadId":"13399","inReplyTo":"m3iqxr54uy.fsf@localhost.localdomain","subject":"Re: [PATCH] git-grep: Add ability to limit directory recursion","fromName":"Aidan Van Dyk","fromEmail":"aidan@highrise.ca","sentAt":"2008-05-07T00:47:19Z","receivedAt":"2008-05-07T00:47:19Z","isPatch":true,"sender":{"key":"aidan@highrise.ca","avatar":"https://gravatar.com/avatar/853c50d90cce753dc1c390fdc6cbed558f5f969bd43fa4f5cb0118d8f71316f6?d=mp&s=160"},"body":"* Jakub Narebski <jnareb@gmail.com> [080506 20:34]:\n> Aidan Van Dyk <aidan@highrise.ca> writes:\n> \n> > This add a -R <limit> option to git-grep which will limit the depth of the\n> > directories recursed when git is doing a grep.\n> > \n> > This allows you to do something like:\n> >         git grep -R 1 <pattern>\n> > and see only the results of the grep on files in the current directory.\n> > \n> > It defaults to a limit of \"0\" which disables the limiting.\n> \n> Nice idea, although I'm not sure if we shouldn't borrow \"-maxdepth\"\n> option from GNU find and friends...\n\nGood idea - I hadn't thought of that, but I like it better.\n\na.\n-- \nAidan Van Dyk                                             Create like a god,\naidan@highrise.ca                                       command like a king,\nhttp://www.highrise.ca/                                   work like a slave.\n"},{"id":"76242","messageId":"200805070334.18500.jnareb@gmail.com","threadId":"13399","inReplyTo":"20080507004719.GJ18081@yugib.highrise.ca","subject":"Re: [PATCH] git-grep: Add ability to limit directory recursion","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-05-07T01:34:17Z","receivedAt":"2008-05-07T01:34:17Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Aidan Van Dyk wrote:\n> * Jakub Narebski <jnareb@gmail.com> [080506 20:34]:\n>> Aidan Van Dyk <aidan@highrise.ca> writes:\n>> \n>>> This add a -R <limit> option to git-grep which will limit the depth of the\n>>> directories recursed when git is doing a grep.\n>>> \n>>> This allows you to do something like:\n>>>         git grep -R 1 <pattern>\n>>> and see only the results of the grep on files in the current directory.\n>>> \n>>> It defaults to a limit of \"0\" which disables the limiting.\n>> \n>> Nice idea, although I'm not sure if we shouldn't borrow \"-maxdepth\"\n>> option from GNU find and friends...\n> \n> Good idea - I hadn't thought of that, but I like it better.\n\nNote that GNU find uses non-standard single-dash long options, and\nthat \"-maxdepth 0\" means do not recurse, but use only files provided\nas arguments.\n\nGNU wget on the other hand uses -l DEPTH/--level=DEPTH, and uses -l 0\n(or -l inf) as in your patch, i.e. infinite recursion.\n\n-- \nJakub Narebski\nPoland\n"}]}