@matheusbsbs / matheus-bagliano / commits / c582abae46
Fork 0

gitweb: Fix and simplify pickaxe search

Instead of using "git-rev-list | git-diff-tree" pipeline for pickaxe search, use git-log with appropriate options. Besides reducing number of forks by one, this allows to use list form of open, which in turn allow to not worry about quoting arguments and to avoid forking shell. The options to git-log were chosen to reduce required changes in pickaxe git command output parsing; gitweb still parses returned commits one by one. Parsing "pickaxe" output is simplified: git_search now reuses parse_difftree_raw_line and writes affected files as they arrive using the fact that commit name goes always before [raw] diff. While at it long bug of pickaxe search was fixed, namely that the last commit found by pickaxe search was never shown. Signed-off-by: Jakub Narebski <jnareb@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jakub Narebski committed Mar 5, 2008 at 09:31 UTC c582abae46725504cee9ff91816c979989632f07
1 file changed +43 -42
gitweb/gitweb.perl
+43 -42
@@ -5305,51 +5305,19 @@ sub git_search {
5305 print "<table class=\"pickaxe search\">\n";
5306 my $alternate = 1;
5307 $/ = "\n";
5308 - my $git_command = git_cmd_str();
5309 - my $searchqtext = $searchtext;
5310 - $searchqtext =~ s/'/'\\''/;
5311 - my $pickaxe_flags = $search_use_regexp ? '--pickaxe-regex' : '';
5312 - open my $fd, "-|", "$git_command rev-list $hash | " .
5313 - "$git_command diff-tree -r --stdin -S\'$searchqtext\' $pickaxe_flags";
5308 + open my $fd, '-|', git_cmd(), '--no-pager', 'log', @diff_opts,
5309 + '--pretty=format:%H', '--no-abbrev', '--raw', "-S$searchtext",
5310 + ($search_use_regexp ? '--pickaxe-regex' : ());
5311 undef %co;
5312 my @files;
5313 while (my $line = <$fd>) {
5317 - if (%co && $line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/) {
5318 - my %set;
5319 - $set{'file'} = $6;
5320 - $set{'from_id'} = $3;
5321 - $set{'to_id'} = $4;
5322 - $set{'id'} = $set{'to_id'};
5323 - if ($set{'id'} =~ m/0{40}/) {
5324 - $set{'id'} = $set{'from_id'};
5325 - }
5326 - if ($set{'id'} =~ m/0{40}/) {
5327 - next;
5328 - }
5329 - push @files, \%set;
5330 - } elsif ($line =~ m/^([0-9a-fA-F]{40})$/){
5314 + chomp $line;
5315 + next unless $line;
5316 +
5317 + my %set = parse_difftree_raw_line($line);
5318 + if (defined $set{'commit'}) {
5319 + # finish previous commit
5320 if (%co) {
5332 - if ($alternate) {
5333 - print "<tr class=\"dark\">\n";
5334 - } else {
5335 - print "<tr class=\"light\">\n";
5336 - }
5337 - $alternate ^= 1;
5338 - my $author = chop_and_escape_str($co{'author_name'}, 15, 5);
5339 - print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
5340 - "<td><i>" . $author . "</i></td>\n" .
5341 - "<td>" .
5342 - $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}),
5343 - -class => "list subject"},
5344 - chop_and_escape_str($co{'title'}, 50) . "<br/>");
5345 - while (my $setref = shift @files) {
5346 - my %set = %$setref;
5347 - print $cgi->a({-href => href(action=>"blob", hash_base=>$co{'id'},
5348 - hash=>$set{'id'}, file_name=>$set{'file'}),
5349 - -class => "list"},
5350 - "<span class=\"match\">" . esc_path($set{'file'}) . "</span>") .
5351 - "<br/>\n";
5352 - }
5321 print "</td>\n" .
5322 "<td class=\"link\">" .
5323 $cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, "commit") .
@@ -5358,11 +5326,44 @@ sub git_search {
5326 print "</td>\n" .
5327 "</tr>\n";
5328 }
5361 - %co = parse_commit($1);
5329 +
5330 + if ($alternate) {
5331 + print "<tr class=\"dark\">\n";
5332 + } else {
5333 + print "<tr class=\"light\">\n";
5334 + }
5335 + $alternate ^= 1;
5336 + %co = parse_commit($set{'commit'});
5337 + my $author = chop_and_escape_str($co{'author_name'}, 15, 5);
5338 + print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
5339 + "<td><i>$author</i></td>\n" .
5340 + "<td>" .
5341 + $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}),
5342 + -class => "list subject"},
5343 + chop_and_escape_str($co{'title'}, 50) . "<br/>");
5344 + } elsif (defined $set{'to_id'}) {
5345 + next if ($set{'to_id'} =~ m/^0{40}$/);
5346 +
5347 + print $cgi->a({-href => href(action=>"blob", hash_base=>$co{'id'},
5348 + hash=>$set{'to_id'}, file_name=>$set{'to_file'}),
5349 + -class => "list"},
5350 + "<span class=\"match\">" . esc_path($set{'file'}) . "</span>") .
5351 + "<br/>\n";
5352 }
5353 }
5354 close $fd;
5355
5356 + # finish last commit (warning: repetition!)
5357 + if (%co) {
5358 + print "</td>\n" .
5359 + "<td class=\"link\">" .
5360 + $cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, "commit") .
5361 + " | " .
5362 + $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$co{'id'})}, "tree");
5363 + print "</td>\n" .
5364 + "</tr>\n";
5365 + }
5366 +
5367 print "</table>\n";
5368 }
5369