From 493e01db51ae003255a27dbcc81953fbfdab958a Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 7 May 2007 01:10:06 +0200 Subject: [PATCH] gitweb: Make it possible to use pre-parsed info in git_difftree_body Make it possible to use pre-parsed, or generated by hand, difftree info in git_difftree_body, similarly to how was and is it done in git_patchset_body. Use just introduced feature in git_commitdiff to parse difftree info (raw diff output) only once: difftree info is now parsed in git_commitdiff directly, and parsed information is passed to both git_difftree_body and git_patchset_body. (Till now only git_blobdiff made use of git_patchset_body ability to use pre-parsed or hand generated info.) Additionally this makes rename info for combined diff with renames (or copies) calculated only once in git_difftree_body; the $difftree is modified and git_patchset_body makes use of added info. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 139 ++++++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 66 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 53ae0b83f1..b3e2e07a2b 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2330,7 +2330,13 @@ sub git_difftree_body { my $alternate = 1; my $patchno = 0; foreach my $line (@{$difftree}) { - my %diff = parse_difftree_raw_line($line); + my $diff; + if (ref($line) eq "HASH") { + # pre-parsed (or generated by hand) + $diff = $line; + } else { + $diff = parse_difftree_raw_line($line); + } if ($alternate) { print "\n"; @@ -2339,21 +2345,22 @@ sub git_difftree_body { } $alternate ^= 1; - if (exists $diff{'nparents'}) { # combined diff + if (exists $diff->{'nparents'}) { # combined diff - fill_from_file_info(\%diff, @parents); + fill_from_file_info($diff, @parents) + unless exists $diff->{'from_file'}; - if ($diff{'to_id'} ne ('0' x 40)) { + if ($diff->{'to_id'} ne ('0' x 40)) { # file exists in the result (child) commit print "" . - $cgi->a({-href => href(action=>"blob", hash=>$diff{'to_id'}, - file_name=>$diff{'to_file'}, + $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, + file_name=>$diff->{'to_file'}, hash_base=>$hash), - -class => "list"}, esc_path($diff{'to_file'})) . + -class => "list"}, esc_path($diff->{'to_file'})) . "\n"; } else { print "" . - esc_path($diff{'to_file'}) . + esc_path($diff->{'to_file'}) . "\n"; } @@ -2368,11 +2375,11 @@ sub git_difftree_body { my $has_history = 0; my $not_deleted = 0; - for (my $i = 0; $i < $diff{'nparents'}; $i++) { + for (my $i = 0; $i < $diff->{'nparents'}; $i++) { my $hash_parent = $parents[$i]; - my $from_hash = $diff{'from_id'}[$i]; - my $from_path = $diff{'from_file'}[$i]; - my $status = $diff{'status'}[$i]; + my $from_hash = $diff->{'from_id'}[$i]; + my $from_path = $diff->{'from_file'}[$i]; + my $status = $diff->{'status'}[$i]; $has_history ||= ($status ne 'A'); $not_deleted ||= ($status ne 'D'); @@ -2388,17 +2395,17 @@ sub git_difftree_body { "blob" . ($i+1)) . " | \n"; } else { - if ($diff{'to_id'} eq $from_hash) { + if ($diff->{'to_id'} eq $from_hash) { print ""; } else { print ""; } print $cgi->a({-href => href(action=>"blobdiff", - hash=>$diff{'to_id'}, + hash=>$diff->{'to_id'}, hash_parent=>$from_hash, hash_base=>$hash, hash_parent_base=>$hash_parent, - file_name=>$diff{'to_file'}, + file_name=>$diff->{'to_file'}, file_parent=>$from_path)}, "diff" . ($i+1)) . " | \n"; @@ -2408,15 +2415,15 @@ sub git_difftree_body { print ""; if ($not_deleted) { print $cgi->a({-href => href(action=>"blob", - hash=>$diff{'to_id'}, - file_name=>$diff{'to_file'}, + hash=>$diff->{'to_id'}, + file_name=>$diff->{'to_file'}, hash_base=>$hash)}, "blob"); print " | " if ($has_history); } if ($has_history) { print $cgi->a({-href => href(action=>"history", - file_name=>$diff{'to_file'}, + file_name=>$diff->{'to_file'}, hash_base=>$hash)}, "history"); } @@ -2429,29 +2436,29 @@ sub git_difftree_body { my ($to_mode_oct, $to_mode_str, $to_file_type); my ($from_mode_oct, $from_mode_str, $from_file_type); - if ($diff{'to_mode'} ne ('0' x 6)) { - $to_mode_oct = oct $diff{'to_mode'}; + if ($diff->{'to_mode'} ne ('0' x 6)) { + $to_mode_oct = oct $diff->{'to_mode'}; if (S_ISREG($to_mode_oct)) { # only for regular file $to_mode_str = sprintf("%04o", $to_mode_oct & 0777); # permission bits } - $to_file_type = file_type($diff{'to_mode'}); + $to_file_type = file_type($diff->{'to_mode'}); } - if ($diff{'from_mode'} ne ('0' x 6)) { - $from_mode_oct = oct $diff{'from_mode'}; + if ($diff->{'from_mode'} ne ('0' x 6)) { + $from_mode_oct = oct $diff->{'from_mode'}; if (S_ISREG($to_mode_oct)) { # only for regular file $from_mode_str = sprintf("%04o", $from_mode_oct & 0777); # permission bits } - $from_file_type = file_type($diff{'from_mode'}); + $from_file_type = file_type($diff->{'from_mode'}); } - if ($diff{'status'} eq "A") { # created + if ($diff->{'status'} eq "A") { # created my $mode_chng = "[new $to_file_type"; $mode_chng .= " with mode: $to_mode_str" if $to_mode_str; $mode_chng .= "]"; print ""; - print $cgi->a({-href => href(action=>"blob", hash=>$diff{'to_id'}, - hash_base=>$hash, file_name=>$diff{'file'}), - -class => "list"}, esc_path($diff{'file'})); + print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, + hash_base=>$hash, file_name=>$diff->{'file'}), + -class => "list"}, esc_path($diff->{'file'})); print "\n"; print "$mode_chng\n"; print ""; @@ -2461,17 +2468,17 @@ sub git_difftree_body { print $cgi->a({-href => "#patch$patchno"}, "patch"); print " | "; } - print $cgi->a({-href => href(action=>"blob", hash=>$diff{'to_id'}, - hash_base=>$hash, file_name=>$diff{'file'})}, + print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, + hash_base=>$hash, file_name=>$diff->{'file'})}, "blob"); print "\n"; - } elsif ($diff{'status'} eq "D") { # deleted + } elsif ($diff->{'status'} eq "D") { # deleted my $mode_chng = "[deleted $from_file_type]"; print ""; - print $cgi->a({-href => href(action=>"blob", hash=>$diff{'from_id'}, - hash_base=>$parent, file_name=>$diff{'file'}), - -class => "list"}, esc_path($diff{'file'})); + print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'from_id'}, + hash_base=>$parent, file_name=>$diff->{'file'}), + -class => "list"}, esc_path($diff->{'file'})); print "\n"; print "$mode_chng\n"; print ""; @@ -2481,22 +2488,22 @@ sub git_difftree_body { print $cgi->a({-href => "#patch$patchno"}, "patch"); print " | "; } - print $cgi->a({-href => href(action=>"blob", hash=>$diff{'from_id'}, - hash_base=>$parent, file_name=>$diff{'file'})}, + print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'from_id'}, + hash_base=>$parent, file_name=>$diff->{'file'})}, "blob") . " | "; if ($have_blame) { print $cgi->a({-href => href(action=>"blame", hash_base=>$parent, - file_name=>$diff{'file'})}, + file_name=>$diff->{'file'})}, "blame") . " | "; } print $cgi->a({-href => href(action=>"history", hash_base=>$parent, - file_name=>$diff{'file'})}, + file_name=>$diff->{'file'})}, "history"); print "\n"; - } elsif ($diff{'status'} eq "M" || $diff{'status'} eq "T") { # modified, or type changed + } elsif ($diff->{'status'} eq "M" || $diff->{'status'} eq "T") { # modified, or type changed my $mode_chnge = ""; - if ($diff{'from_mode'} != $diff{'to_mode'}) { + if ($diff->{'from_mode'} != $diff->{'to_mode'}) { $mode_chnge = "[changed"; if ($from_file_type ne $to_file_type) { $mode_chnge .= " from $from_file_type to $to_file_type"; @@ -2511,9 +2518,9 @@ sub git_difftree_body { $mode_chnge .= "]\n"; } print ""; - print $cgi->a({-href => href(action=>"blob", hash=>$diff{'to_id'}, - hash_base=>$hash, file_name=>$diff{'file'}), - -class => "list"}, esc_path($diff{'file'})); + print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, + hash_base=>$hash, file_name=>$diff->{'file'}), + -class => "list"}, esc_path($diff->{'file'})); print "\n"; print "$mode_chnge\n"; print ""; @@ -2522,70 +2529,70 @@ sub git_difftree_body { $patchno++; print $cgi->a({-href => "#patch$patchno"}, "patch") . " | "; - } elsif ($diff{'to_id'} ne $diff{'from_id'}) { + } elsif ($diff->{'to_id'} ne $diff->{'from_id'}) { # "commit" view and modified file (not onlu mode changed) print $cgi->a({-href => href(action=>"blobdiff", - hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'}, + hash=>$diff->{'to_id'}, hash_parent=>$diff->{'from_id'}, hash_base=>$hash, hash_parent_base=>$parent, - file_name=>$diff{'file'})}, + file_name=>$diff->{'file'})}, "diff") . " | "; } - print $cgi->a({-href => href(action=>"blob", hash=>$diff{'to_id'}, - hash_base=>$hash, file_name=>$diff{'file'})}, + print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, + hash_base=>$hash, file_name=>$diff->{'file'})}, "blob") . " | "; if ($have_blame) { print $cgi->a({-href => href(action=>"blame", hash_base=>$hash, - file_name=>$diff{'file'})}, + file_name=>$diff->{'file'})}, "blame") . " | "; } print $cgi->a({-href => href(action=>"history", hash_base=>$hash, - file_name=>$diff{'file'})}, + file_name=>$diff->{'file'})}, "history"); print "\n"; - } elsif ($diff{'status'} eq "R" || $diff{'status'} eq "C") { # renamed or copied + } elsif ($diff->{'status'} eq "R" || $diff->{'status'} eq "C") { # renamed or copied my %status_name = ('R' => 'moved', 'C' => 'copied'); - my $nstatus = $status_name{$diff{'status'}}; + my $nstatus = $status_name{$diff->{'status'}}; my $mode_chng = ""; - if ($diff{'from_mode'} != $diff{'to_mode'}) { + if ($diff->{'from_mode'} != $diff->{'to_mode'}) { # mode also for directories, so we cannot use $to_mode_str $mode_chng = sprintf(", mode: %04o", $to_mode_oct & 0777); } print "" . $cgi->a({-href => href(action=>"blob", hash_base=>$hash, - hash=>$diff{'to_id'}, file_name=>$diff{'to_file'}), - -class => "list"}, esc_path($diff{'to_file'})) . "\n" . + hash=>$diff->{'to_id'}, file_name=>$diff->{'to_file'}), + -class => "list"}, esc_path($diff->{'to_file'})) . "\n" . "[$nstatus from " . $cgi->a({-href => href(action=>"blob", hash_base=>$parent, - hash=>$diff{'from_id'}, file_name=>$diff{'from_file'}), - -class => "list"}, esc_path($diff{'from_file'})) . - " with " . (int $diff{'similarity'}) . "% similarity$mode_chng]\n" . + hash=>$diff->{'from_id'}, file_name=>$diff->{'from_file'}), + -class => "list"}, esc_path($diff->{'from_file'})) . + " with " . (int $diff->{'similarity'}) . "% similarity$mode_chng]\n" . ""; if ($action eq 'commitdiff') { # link to patch $patchno++; print $cgi->a({-href => "#patch$patchno"}, "patch") . " | "; - } elsif ($diff{'to_id'} ne $diff{'from_id'}) { + } elsif ($diff->{'to_id'} ne $diff->{'from_id'}) { # "commit" view and modified file (not only pure rename or copy) print $cgi->a({-href => href(action=>"blobdiff", - hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'}, + hash=>$diff->{'to_id'}, hash_parent=>$diff->{'from_id'}, hash_base=>$hash, hash_parent_base=>$parent, - file_name=>$diff{'to_file'}, file_parent=>$diff{'from_file'})}, + file_name=>$diff->{'to_file'}, file_parent=>$diff->{'from_file'})}, "diff") . " | "; } - print $cgi->a({-href => href(action=>"blob", hash=>$diff{'to_id'}, - hash_base=>$parent, file_name=>$diff{'to_file'})}, + print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, + hash_base=>$parent, file_name=>$diff->{'to_file'})}, "blob") . " | "; if ($have_blame) { print $cgi->a({-href => href(action=>"blame", hash_base=>$hash, - file_name=>$diff{'to_file'})}, + file_name=>$diff->{'to_file'})}, "blame") . " | "; } print $cgi->a({-href => href(action=>"history", hash_base=>$hash, - file_name=>$diff{'to_file'})}, + file_name=>$diff->{'to_file'})}, "history"); print "\n"; @@ -4401,7 +4408,7 @@ sub git_commitdiff { chomp $line; # empty line ends raw part of diff-tree output last unless $line; - push @difftree, $line; + push @difftree, scalar parse_difftree_raw_line($line); } } elsif ($format eq 'plain') {