aboutsummaryrefslogtreecommitdiff
path: root/gitweb
diff options
context:
space:
mode:
authorPetr Baudis <pasky@suse.cz>2007-05-17 04:31:12 +0200
committerJunio C Hamano <junkio@cox.net>2007-05-17 17:37:31 -0700
commite7738553723dcff0237b1aed2771886c8d87d224 (patch)
tree8fcfebfcbb2a894f11c3d461bb5ed63bdc56bd3d /gitweb
parentd77b5673e90f47309d6bf87a7653896169945da0 (diff)
downloadgit-e7738553723dcff0237b1aed2771886c8d87d224.tar.gz
git-e7738553723dcff0237b1aed2771886c8d87d224.tar.xz
gitweb: Add support for grep searches
The 'grep' type of search greps the currently selected tree for given regexp and shows the results in a fancy table with links into blob view. The number of shown matches is limited to 1000 and the whole feature can be turned off (grepping linux-2.6.git already makes repo.or.cz a bit unhappy). This second revision makes it in documentation explicit that grep accepts regexps, and makes grep accept extended regexps instead of basic regexps. Signed-off-by: Petr Baudis <pasky@suse.cz> Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'gitweb')
-rw-r--r--gitweb/gitweb.css4
-rwxr-xr-xgitweb/gitweb.perl123
2 files changed, 125 insertions, 2 deletions
diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 02623cbb6..9f0822fab 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -484,3 +484,7 @@ span.atnight {
span.match {
color: #e00000;
}
+
+div.binary {
+ font-style: italic;
+}
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 260d79bd7..cc16e3137 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -146,6 +146,19 @@ our %feature = (
'override' => 0,
'default' => [1]},
+ # Enable grep search, which will list the files in currently selected
+ # tree containing the given string. Enabled by default. This can be
+ # potentially CPU-intensive, of course.
+
+ # To enable system wide have in $GITWEB_CONFIG
+ # $feature{'grep'}{'default'} = [1];
+ # To have project specific config enable override in $GITWEB_CONFIG
+ # $feature{'grep'}{'override'} = 1;
+ # and in project config gitweb.grep = 0|1;
+ 'grep' => {
+ 'override' => 0,
+ 'default' => [1]},
+
# Enable the pickaxe search, which will list the commits that modified
# a given string in a file. This can be practical and quite faster
# alternative to 'blame', but still potentially CPU-intensive.
@@ -245,6 +258,18 @@ sub gitweb_have_snapshot {
return $have_snapshot;
}
+sub feature_grep {
+ my ($val) = git_get_project_config('grep', '--bool');
+
+ if ($val eq 'true') {
+ return (1);
+ } elsif ($val eq 'false') {
+ return (0);
+ }
+
+ return ($_[0]);
+}
+
sub feature_pickaxe {
my ($val) = git_get_project_config('pickaxe', '--bool');
@@ -364,10 +389,17 @@ if (defined $page) {
}
}
+our $searchtype = $cgi->param('st');
+if (defined $searchtype) {
+ if ($searchtype =~ m/[^a-z]/) {
+ die_error(undef, "Invalid searchtype parameter");
+ }
+}
+
our $searchtext = $cgi->param('s');
our $search_regexp;
if (defined $searchtext) {
- if ($searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) {
+ if ($searchtype ne 'grep' and $searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) {
die_error(undef, "Invalid search parameter");
}
if (length($searchtext) < 2) {
@@ -1927,7 +1959,7 @@ EOF
$cgi->hidden(-name => "a") . "\n" .
$cgi->hidden(-name => "h") . "\n" .
$cgi->popup_menu(-name => 'st', -default => 'commit',
- -values => ['commit', 'author', 'committer', 'pickaxe']) .
+ -values => ['commit', 'grep', 'author', 'committer', 'pickaxe']) .
$cgi->sup($cgi->a({-href => href(action=>"search_help")}, "?")) .
" search:\n",
$cgi->textfield(-name => "s", -value => $searchtext) . "\n" .
@@ -4626,6 +4658,12 @@ sub git_search {
die_error('403 Permission denied', "Permission denied");
}
}
+ if ($searchtype eq 'grep') {
+ my ($have_grep) = gitweb_check_feature('grep');
+ if (!$have_grep) {
+ die_error('403 Permission denied', "Permission denied");
+ }
+ }
git_header_html();
@@ -4742,6 +4780,73 @@ sub git_search {
print "</table>\n";
}
+
+ if ($searchtype eq 'grep') {
+ git_print_page_nav('','', $hash,$co{'tree'},$hash);
+ git_print_header_div('commit', esc_html($co{'title'}), $hash);
+
+ print "<table cellspacing=\"0\">\n";
+ my $alternate = 1;
+ my $matches = 0;
+ $/ = "\n";
+ open my $fd, "-|", git_cmd(), 'grep', '-n', '-i', '-E', $searchtext, $co{'tree'};
+ my $lastfile = '';
+ while (my $line = <$fd>) {
+ chomp $line;
+ my ($file, $lno, $ltext, $binary);
+ last if ($matches++ > 1000);
+ if ($line =~ /^Binary file (.+) matches$/) {
+ $file = $1;
+ $binary = 1;
+ } else {
+ (undef, $file, $lno, $ltext) = split(/:/, $line, 4);
+ }
+ if ($file ne $lastfile) {
+ $lastfile and print "</td></tr>\n";
+ if ($alternate++) {
+ print "<tr class=\"dark\">\n";
+ } else {
+ print "<tr class=\"light\">\n";
+ }
+ print "<td class=\"list\">".
+ $cgi->a({-href => href(action=>"blob", hash=>$co{'hash'},
+ file_name=>"$file"),
+ -class => "list"}, esc_path($file));
+ print "</td><td>\n";
+ $lastfile = $file;
+ }
+ if ($binary) {
+ print "<div class=\"binary\">Binary file</div>\n";
+ } else {
+ $ltext = untabify($ltext);
+ if ($ltext =~ m/^(.*)($searchtext)(.*)$/i) {
+ $ltext = esc_html($1, -nbsp=>1);
+ $ltext .= '<span class="match">';
+ $ltext .= esc_html($2, -nbsp=>1);
+ $ltext .= '</span>';
+ $ltext .= esc_html($3, -nbsp=>1);
+ } else {
+ $ltext = esc_html($ltext, -nbsp=>1);
+ }
+ print "<div class=\"pre\">" .
+ $cgi->a({-href => href(action=>"blob", hash=>$co{'hash'},
+ file_name=>"$file").'#l'.$lno,
+ -class => "linenr"}, sprintf('%4i', $lno))
+ . ' ' . $ltext . "</div>\n";
+ }
+ }
+ if ($lastfile) {
+ print "</td></tr>\n";
+ if ($matches > 1000) {
+ print "<div class=\"diff nodifferences\">Too many matches, listing trimmed</div>\n";
+ }
+ } else {
+ print "<div class=\"diff nodifferences\">No matches found</div>\n";
+ }
+ close $fd;
+
+ print "</table>\n";
+ }
git_footer_html();
}
@@ -4752,6 +4857,20 @@ sub git_search_help {
<dl>
<dt><b>commit</b></dt>
<dd>The commit messages and authorship information will be scanned for the given string.</dd>
+EOT
+ my ($have_grep) = gitweb_check_feature('grep');
+ if ($have_grep) {
+ print <<EOT;
+<dt><b>grep</b></dt>
+<dd>All files in the currently selected tree (HEAD unless you are explicitly browsing
+ a different one) are searched for the given
+<a href="http://en.wikipedia.org/wiki/Regular_expression">regular expression</a>
+(POSIX extended) and the matches are listed. On large
+trees, this search can take a while and put some strain on the server, so please use it with
+some consideration.</dd>
+EOT
+ }
+ print <<EOT;
<dt><b>author</b></dt>
<dd>Name and e-mail of the change author and date of birth of the patch will be scanned for the given string.</dd>
<dt><b>committer</b></dt>