{"thread":{"id":"8187","subject":"[PATCH] gitweb: Add support for grep searches","startedAt":"2007-05-17T02:31:12Z","lastAt":"2007-05-19T00:43:48Z","messageCount":5,"participants":["Petr Baudis","Jakub Narebski"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"42363","messageId":"20070517023112.21056.62390.stgit@rover","threadId":"8187","inReplyTo":null,"subject":"[PATCH] gitweb: Add support for grep searches","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2007-05-17T02:31:12Z","receivedAt":"2007-05-17T02:31:12Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"The 'grep' type of search greps the currently selected tree for given\nregexp and shows the results in a fancy table with links into blob view.\nThe number of shown matches is limited to 1000 and the whole feature\ncan be turned off (grepping linux-2.6.git already makes repo.or.cz a bit\nunhappy).\n\nThis second revision makes it in documentation explicit that grep accepts\nregexps, and makes grep accept extended regexps instead of basic regexps.\n\nSigned-off-by: Petr Baudis <pasky@suse.cz>\n---\n\n gitweb/gitweb.css  |    4 ++\n gitweb/gitweb.perl |  123 +++++++++++++++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 125 insertions(+), 2 deletions(-)\n\ndiff --git a/gitweb/gitweb.css b/gitweb/gitweb.css\nindex 02623cb..9f0822f 100644\n--- a/gitweb/gitweb.css\n+++ b/gitweb/gitweb.css\n@@ -484,3 +484,7 @@ span.atnight {\n span.match {\n \tcolor: #e00000;\n }\n+\n+div.binary {\n+\tfont-style: italic;\n+}\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 549e027..f37fa0c 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -146,6 +146,19 @@ our %feature = (\n \t\t'override' => 0,\n \t\t'default' => [1]},\n \n+\t# Enable grep search, which will list the files in currently selected\n+\t# tree containing the given string. Enabled by default. This can be\n+\t# potentially CPU-intensive, of course.\n+\n+\t# To enable system wide have in $GITWEB_CONFIG\n+\t# $feature{'grep'}{'default'} = [1];\n+\t# To have project specific config enable override in $GITWEB_CONFIG\n+\t# $feature{'grep'}{'override'} = 1;\n+\t# and in project config gitweb.grep = 0|1;\n+\t'grep' => {\n+\t\t'override' => 0,\n+\t\t'default' => [1]},\n+\n \t# Enable the pickaxe search, which will list the commits that modified\n \t# a given string in a file. This can be practical and quite faster\n \t# alternative to 'blame', but still potentially CPU-intensive.\n@@ -245,6 +258,18 @@ sub gitweb_have_snapshot {\n \treturn $have_snapshot;\n }\n \n+sub feature_grep {\n+\tmy ($val) = git_get_project_config('grep', '--bool');\n+\n+\tif ($val eq 'true') {\n+\t\treturn (1);\n+\t} elsif ($val eq 'false') {\n+\t\treturn (0);\n+\t}\n+\n+\treturn ($_[0]);\n+}\n+\n sub feature_pickaxe {\n \tmy ($val) = git_get_project_config('pickaxe', '--bool');\n \n@@ -364,10 +389,17 @@ if (defined $page) {\n \t}\n }\n \n+our $searchtype = $cgi->param('st');\n+if (defined $searchtype) {\n+\tif ($searchtype =~ m/[^a-z]/) {\n+\t\tdie_error(undef, \"Invalid searchtype parameter\");\n+\t}\n+}\n+\n our $searchtext = $cgi->param('s');\n our $search_regexp;\n if (defined $searchtext) {\n-\tif ($searchtext =~ m/[^a-zA-Z0-9_\\.\\/\\-\\+\\:\\@ ]/) {\n+\tif ($searchtype ne 'grep' and $searchtext =~ m/[^a-zA-Z0-9_\\.\\/\\-\\+\\:\\@ ]/) {\n \t\tdie_error(undef, \"Invalid search parameter\");\n \t}\n \tif (length($searchtext) < 2) {\n@@ -1923,7 +1955,7 @@ EOF\n \t\t      $cgi->hidden(-name => \"a\") . \"\\n\" .\n \t\t      $cgi->hidden(-name => \"h\") . \"\\n\" .\n \t\t      $cgi->popup_menu(-name => 'st', -default => 'commit',\n-\t\t                       -values => ['commit', 'author', 'committer', 'pickaxe']) .\n+\t\t                       -values => ['commit', 'grep', 'author', 'committer', 'pickaxe']) .\n \t\t      $cgi->sup($cgi->a({-href => href(action=>\"search_help\")}, \"?\")) .\n \t\t      \" search:\\n\",\n \t\t      $cgi->textfield(-name => \"s\", -value => $searchtext) . \"\\n\" .\n@@ -4615,6 +4647,12 @@ sub git_search {\n \t\t\tdie_error('403 Permission denied', \"Permission denied\");\n \t\t}\n \t}\n+\tif ($searchtype eq 'grep') {\n+\t\tmy ($have_grep) = gitweb_check_feature('grep');\n+\t\tif (!$have_grep) {\n+\t\t\tdie_error('403 Permission denied', \"Permission denied\");\n+\t\t}\n+\t}\n \n \tgit_header_html();\n \n@@ -4731,6 +4769,73 @@ sub git_search {\n \n \t\tprint \"</table>\\n\";\n \t}\n+\n+\tif ($searchtype eq 'grep') {\n+\t\tgit_print_page_nav('','', $hash,$co{'tree'},$hash);\n+\t\tgit_print_header_div('commit', esc_html($co{'title'}), $hash);\n+\n+\t\tprint \"<table cellspacing=\\\"0\\\">\\n\";\n+\t\tmy $alternate = 1;\n+\t\tmy $matches = 0;\n+\t\t$/ = \"\\n\";\n+\t\topen my $fd, \"-|\", git_cmd(), 'grep', '-n', '-i', '-E', $searchtext, $co{'tree'};\n+\t\tmy $lastfile = '';\n+\t\twhile (my $line = <$fd>) {\n+\t\t\tchomp $line;\n+\t\t\tmy ($file, $lno, $ltext, $binary);\n+\t\t\tlast if ($matches++ > 1000);\n+\t\t\tif ($line =~ /^Binary file (.+) matches$/) {\n+\t\t\t\t$file = $1;\n+\t\t\t\t$binary = 1;\n+\t\t\t} else {\n+\t\t\t\t(undef, $file, $lno, $ltext) = split(/:/, $line, 4);\n+\t\t\t}\n+\t\t\tif ($file ne $lastfile) {\n+\t\t\t\t$lastfile and print \"</td></tr>\\n\";\n+\t\t\t\tif ($alternate++) {\n+\t\t\t\t\tprint \"<tr class=\\\"dark\\\">\\n\";\n+\t\t\t\t} else {\n+\t\t\t\t\tprint \"<tr class=\\\"light\\\">\\n\";\n+\t\t\t\t}\n+\t\t\t\tprint \"<td class=\\\"list\\\">\".\n+\t\t\t\t\t$cgi->a({-href => href(action=>\"blob\", hash=>$co{'hash'},\n+\t\t\t\t\t\t\t       file_name=>\"$file\"),\n+\t\t\t\t\t\t-class => \"list\"}, esc_path($file));\n+\t\t\t\tprint \"</td><td>\\n\";\n+\t\t\t\t$lastfile = $file;\n+\t\t\t}\n+\t\t\tif ($binary) {\n+\t\t\t\tprint \"<div class=\\\"binary\\\">Binary file</div>\\n\";\n+\t\t\t} else {\n+\t\t\t\t$ltext = untabify($ltext);\n+\t\t\t\tif ($ltext =~ m/^(.*)($searchtext)(.*)$/i) {\n+\t\t\t\t\t$ltext = esc_html($1, -nbsp=>1);\n+\t\t\t\t\t$ltext .= '<span class=\"match\">';\n+\t\t\t\t\t$ltext .= esc_html($2, -nbsp=>1);\n+\t\t\t\t\t$ltext .= '</span>';\n+\t\t\t\t\t$ltext .= esc_html($3, -nbsp=>1);\n+\t\t\t\t} else {\n+\t\t\t\t\t$ltext = esc_html($ltext, -nbsp=>1);\n+\t\t\t\t}\n+\t\t\t\tprint \"<div class=\\\"pre\\\">\" .\n+\t\t\t\t\t$cgi->a({-href => href(action=>\"blob\", hash=>$co{'hash'},\n+\t\t\t\t\t\t\t       file_name=>\"$file\").'#l'.$lno,\n+\t\t\t\t\t\t-class => \"linenr\"}, sprintf('%4i', $lno))\n+\t\t\t\t\t. ' ' .  $ltext . \"</div>\\n\";\n+\t\t\t}\n+\t\t}\n+\t\tif ($lastfile) {\n+\t\t\tprint \"</td></tr>\\n\";\n+\t\t\tif ($matches > 1000) {\n+\t\t\t\tprint \"<div class=\\\"diff nodifferences\\\">Too many matches, listing trimmed</div>\\n\";\n+\t\t\t}\n+\t\t} else {\n+\t\t\tprint \"<div class=\\\"diff nodifferences\\\">No matches found</div>\\n\";\n+\t\t}\n+\t\tclose $fd;\n+\n+\t\tprint \"</table>\\n\";\n+\t}\n \tgit_footer_html();\n }\n \n@@ -4741,6 +4846,20 @@ sub git_search_help {\n <dl>\n <dt><b>commit</b></dt>\n <dd>The commit messages and authorship information will be scanned for the given string.</dd>\n+EOT\n+\tmy ($have_grep) = gitweb_check_feature('grep');\n+\tif ($have_grep) {\n+\t\tprint <<EOT;\n+<dt><b>grep</b></dt>\n+<dd>All files in the currently selected tree (HEAD unless you are explicitly browsing\n+    a different one) are searched for the given\n+<a href=\"http://en.wikipedia.org/wiki/Regular_expression\">regular expression</a>\n+(POSIX extended) and the matches are listed. On large\n+trees, this search can take a while and put some strain on the server, so please use it with\n+some consideration.</dd>\n+EOT\n+\t}\n+\tprint <<EOT;\n <dt><b>author</b></dt>\n <dd>Name and e-mail of the change author and date of birth of the patch will be scanned for the given string.</dd>\n <dt><b>committer</b></dt>\n"},{"id":"42383","messageId":"f2h59r$sge$1@sea.gmane.org","threadId":"8187","inReplyTo":"20070517023112.21056.62390.stgit@rover","subject":"Re: [PATCH] gitweb: Add support for grep searches","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-05-17T09:00:10Z","receivedAt":"2007-05-17T09:00:10Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Petr Baudis wrote:\n\n> This second revision makes it in documentation explicit that grep accepts\n> regexps, and makes grep accept extended regexps instead of basic regexps.\n\nI have thought about adding \"[ ] regular expression\" (or \"Perl\nextended regexp\", or something like that) checkbox for all searches:\n'commit' (message), 'pickaxe' and the new 'grep'.\n\nI have thought also about replaceing pickaxe search pipeline by\n  git log --pretty=format:%H -r --no-abbrev --raw -S<search> <hash>\nbut I'm not sure if pager would be turned off, and of performance\ncompared to current pipeline:\n  git rev-list <hash> | git diff-tree -r --stdin -S<search>\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"42471","messageId":"f2k4d5$879$1@sea.gmane.org","threadId":"8187","inReplyTo":"20070517023112.21056.62390.stgit@rover","subject":"Re: [PATCH] gitweb: Add support for grep searches","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-05-18T11:58:28Z","receivedAt":"2007-05-18T11:58:28Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"[Cc: Petr Baudis <pasky@suse.cz>, Junio C Hamano <junkio@cox.net>, \n git@vger.kernel.org]\n\nPetr Baudis wrote:\n\n> The 'grep' type of search greps the currently selected tree for given\n> regexp and shows the results in a fancy table with links into blob view.\n> The number of shown matches is limited to 1000 and the whole feature\n> can be turned off (grepping linux-2.6.git already makes repo.or.cz a bit\n> unhappy).\n\nAck, FWIW.\n\nBy the way, I wonder if we should make search context (view) sensitive.\nFor example for 'history' view search would be limited to given pathspec,\ngrep search in a 'tree' view would search given tree only.\n\nAdditionally it would be nice to have links from search results page to\nhave search match highlighted, like search results on GitWiki.\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"42477","messageId":"20070518123538.GW4489@pasky.or.cz","threadId":"8187","inReplyTo":"f2k4d5$879$1@sea.gmane.org","subject":"Re: [PATCH] gitweb: Add support for grep searches","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2007-05-18T12:35:38Z","receivedAt":"2007-05-18T12:35:38Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Fri, May 18, 2007 at 01:58:28PM CEST, Jakub Narebski wrote:\n> [Cc: Petr Baudis <pasky@suse.cz>, Junio C Hamano <junkio@cox.net>, \n>  git@vger.kernel.org]\n\nYour MUA seems to have finally decided to go completely crazy or\nsomething. :-) Different mails go to us and the list.\n\n> Petr Baudis wrote:\n> \n> > The 'grep' type of search greps the currently selected tree for given\n> > regexp and shows the results in a fancy table with links into blob view.\n> > The number of shown matches is limited to 1000 and the whole feature\n> > can be turned off (grepping linux-2.6.git already makes repo.or.cz a bit\n> > unhappy).\n> \n> Ack, FWIW.\n\nI want to implement the regexp checkbox.\n\n> By the way, I wonder if we should make search context (view) sensitive.\n> For example for 'history' view search would be limited to given pathspec,\n> grep search in a 'tree' view would search given tree only.\n\nI think it would be nice (if it's clearly visible that the results are\nfiltered), but I'm probably not the one who is going to implement this.\n;-)\n\n> Additionally it would be nice to have links from search results page to\n> have search match highlighted, like search results on GitWiki.\n\nI'm sorry, I don't understand.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nEver try. Ever fail. No matter. // Try again. Fail again. Fail better.\n\t\t-- Samuel Beckett\n"},{"id":"42573","messageId":"200705190243.49788.jnareb@gmail.com","threadId":"8187","inReplyTo":"20070518123538.GW4489@pasky.or.cz","subject":"Re: [PATCH] gitweb: Add support for grep searches","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-05-19T00:43:48Z","receivedAt":"2007-05-19T00:43:48Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Petr Baudis wrote:\n> On Fri, May 18, 2007 at 01:58:28PM CEST, Jakub Narebski wrote:\n\n>> Additionally it would be nice to have links from search results page to\n>> have search match highlighted, like search results on GitWiki.\n\nFor example \n  http://git.or.cz/gitwiki/SubprojectSupport?highlight=%28Subproject%29\n \n> I'm sorry, I don't understand.\n\nFor example search results for commit search ('author', 'committer'\nand 'commit' searches have link to 'commit' view. Pickaxe has link\nto 'commitdiff' view. Grep search would have link(s) to blob views.\nIn those views the 's' (searchtext) parameter could be passed, and\nmatched fragment should be somehow higlighted, e.g. using background\ncolor to not interfere with syntax highlighting.\n\n-- \nJakub Narebski\nPoland\n"}]}