X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gitweb%2Fgitweb.perl;h=c8ba3a27a345b11aae29f8de74aed6e36f4f5a1d;hb=d60a6a662fac58f833efde93c962314fd5d83541;hp=13114bc9c62015ebbc50ded7caf2912aea5ee069;hpb=deaa01a9f59875dcfd0c9e08ce48f4168f29cb81;p=git.git diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 13114bc9c..c8ba3a27a 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -71,6 +71,9 @@ our $logo_label = "git homepage"; # source of projects list our $projects_list = "++GITWEB_LIST++"; +# the width (in characters) of the projects list "Description" column +our $projects_list_description_width = 25; + # default order of projects list # valid values are none, project, descr, owner, and age our $default_projects_order = "project"; @@ -383,6 +386,23 @@ if (defined $hash_base) { } } +my %allowed_options = ( + "--no-merges" => [ qw(rss atom log shortlog history) ], +); + +our @extra_options = $cgi->param('opt'); +if (defined @extra_options) { + foreach(@extra_options) + { + if (not grep(/^$_$/, keys %allowed_options)) { + die_error(undef, "Invalid option parameter"); + } + if (not grep(/^$action$/, @{$allowed_options{$_}})) { + die_error(undef, "Invalid option parameter for this action"); + } + } +} + our $hash_parent_base = $cgi->param('hpb'); if (defined $hash_parent_base) { if (!validate_refname($hash_parent_base)) { @@ -534,6 +554,7 @@ sub href(%) { action => "a", file_name => "f", file_parent => "fp", + extra_options => "opt", hash => "h", hash_parent => "hp", hash_base => "hb", @@ -1058,7 +1079,7 @@ sub format_extended_diff_header_line { # format from-file/to-file diff header sub format_diff_from_to_header { - my ($from_line, $to_line, $diffinfo, $from, $to) = @_; + my ($from_line, $to_line, $diffinfo, $from, $to, @parents) = @_; my $line; my $result = ''; @@ -1084,7 +1105,17 @@ sub format_diff_from_to_header { for (my $i = 0; $i < $diffinfo->{'nparents'}; $i++) { if ($from->{'href'}[$i]) { $line = '--- ' . - ($i+1) . "/" . + $cgi->a({-href=>href(action=>"blobdiff", + hash_parent=>$diffinfo->{'from_id'}[$i], + hash_parent_base=>$parents[$i], + file_parent=>$from->{'file'}[$i], + hash=>$diffinfo->{'to_id'}, + hash_base=>$hash, + file_name=>$to->{'file'}), + -class=>"path", + -title=>"diff" . ($i+1)}, + $i+1) . + '/' . $cgi->a({-href=>$from->{'href'}[$i], -class=>"path"}, esc_path($from->{'file'}[$i])); } else { @@ -1112,6 +1143,31 @@ sub format_diff_from_to_header { return $result; } +# create note for patch simplified by combined diff +sub format_diff_cc_simplified { + my ($diffinfo, @parents) = @_; + my $result = ''; + + $result .= "
" . + "diff --cc "; + if (!is_deleted($diffinfo)) { + $result .= $cgi->a({-href => href(action=>"blob", + hash_base=>$hash, + hash=>$diffinfo->{'to_id'}, + file_name=>$diffinfo->{'to_file'}), + -class => "path"}, + esc_path($diffinfo->{'to_file'})); + } else { + $result .= esc_path($diffinfo->{'to_file'}); + } + $result .= "
\n" . # class="diff header" + "
" . + "Simple merge" . + "
\n"; # class="diff nodifferences" + + return $result; +} + # format patch (diff) line (not to be used for diff headers) sub format_diff_line { my $line = shift; @@ -1430,12 +1486,12 @@ sub git_get_projects_list { return @list; } -sub git_get_project_owner { - my $project = shift; - my $owner; +our $gitweb_project_owner = undef; +sub git_get_project_list_from_file { - return undef unless $project; + return if (defined $gitweb_project_owner); + $gitweb_project_owner = {}; # read from file (url-encoded): # 'git%2Fgit.git Linus+Torvalds' # 'libs%2Fklibc%2Fklibc.git H.+Peter+Anvin' @@ -1447,13 +1503,25 @@ sub git_get_project_owner { my ($pr, $ow) = split ' ', $line; $pr = unescape($pr); $ow = unescape($ow); - if ($pr eq $project) { - $owner = to_utf8($ow); - last; - } + $gitweb_project_owner->{$pr} = to_utf8($ow); } close $fd; } +} + +sub git_get_project_owner { + my $project = shift; + my $owner; + + return undef unless $project; + + if (!defined $gitweb_project_owner) { + git_get_project_list_from_file(); + } + + if (exists $gitweb_project_owner->{$project}) { + $owner = $gitweb_project_owner->{$project}; + } if (!defined $owner) { $owner = get_file_owner("$projectroot/$project"); } @@ -1479,6 +1547,7 @@ sub git_get_last_activity { my $age = time - $timestamp; return ($age, age_string($age)); } + return (undef, undef); } sub git_get_references { @@ -1722,6 +1791,7 @@ sub parse_commits { ($arg ? ($arg) : ()), ("--max-count=" . $maxcount), ("--skip=" . $skip), + @extra_options, $commit_id, "--", ($filename ? ($filename) : ()) @@ -2166,12 +2236,18 @@ EOF } else { $search_hash = "HEAD"; } + my $action = $my_uri; + my ($use_pathinfo) = gitweb_check_feature('pathinfo'); + if ($use_pathinfo) { + $action .= "/$project"; + } else { + $cgi->param("p", $project); + } $cgi->param("a", "search"); $cgi->param("h", $search_hash); - $cgi->param("p", $project); - print $cgi->startform(-method => "get", -action => $my_uri) . + print $cgi->startform(-method => "get", -action => $action) . "
\n" . - $cgi->hidden(-name => "p") . "\n" . + (!$use_pathinfo && $cgi->hidden(-name => "p") . "\n") . $cgi->hidden(-name => "a") . "\n" . $cgi->hidden(-name => "h") . "\n" . $cgi->popup_menu(-name => 'st', -default => 'commit', @@ -2963,13 +3039,33 @@ sub git_patchset_body { # advance raw git-diff output if needed $patch_idx++ if defined $diffinfo; - # read and prepare patch information - if (ref($difftree->[$patch_idx]) eq "HASH") { - # pre-parsed (or generated by hand) - $diffinfo = $difftree->[$patch_idx]; - } else { - $diffinfo = parse_difftree_raw_line($difftree->[$patch_idx]); + # compact combined diff output can have some patches skipped + # find which patch (using pathname of result) we are at now + my $to_name; + if ($diff_header[0] =~ m!^diff --cc "?(.*)"?$!) { + $to_name = $1; } + + do { + # read and prepare patch information + if (ref($difftree->[$patch_idx]) eq "HASH") { + # pre-parsed (or generated by hand) + $diffinfo = $difftree->[$patch_idx]; + } else { + $diffinfo = parse_difftree_raw_line($difftree->[$patch_idx]); + } + + # check if current raw line has no patch (it got simplified) + if (defined $to_name && $to_name ne $diffinfo->{'to_file'}) { + print "
\n" . + format_diff_cc_simplified($diffinfo, @hash_parents) . + "
\n"; # class="patch" + + $patch_idx++; + $patch_number++; + } + } until (!defined $to_name || $to_name eq $diffinfo->{'to_file'} || + $patch_idx > $#$difftree); # modifies %from, %to hashes parse_from_to_diffinfo($diffinfo, \%from, \%to, @hash_parents); if ($diffinfo->{'nparents'}) { @@ -3042,7 +3138,8 @@ sub git_patchset_body { #assert($patch_line =~ m/^\+\+\+/) if DEBUG; print format_diff_from_to_header($last_patch_line, $patch_line, - $diffinfo, \%from, \%to); + $diffinfo, \%from, \%to, + @hash_parents); # the patch itself LINE: @@ -3058,6 +3155,27 @@ sub git_patchset_body { print "
\n"; # class="patch" } + # for compact combined (--cc) format, with chunk and patch simpliciaction + # patchset might be empty, but there might be unprocessed raw lines + for ($patch_idx++ if $patch_number > 0; + $patch_idx < @$difftree; + $patch_idx++) { + # read and prepare patch information + if (ref($difftree->[$patch_idx]) eq "HASH") { + # pre-parsed (or generated by hand) + $diffinfo = $difftree->[$patch_idx]; + } else { + $diffinfo = parse_difftree_raw_line($difftree->[$patch_idx]); + } + + # generate anchor for "patch" links in difftree / whatchanged part + print "
\n" . + format_diff_cc_simplified($diffinfo, @hash_parents) . + "
\n"; # class="patch" + + $patch_number++; + } + if ($patch_number == 0) { if (@hash_parents > 1) { print "
Trivial merge
\n"; @@ -3086,10 +3204,10 @@ sub git_project_list_body { if (!defined $pr->{'descr'}) { my $descr = git_get_project_description($pr->{'path'}) || ""; $pr->{'descr_long'} = to_utf8($descr); - $pr->{'descr'} = chop_str($descr, 25, 5); + $pr->{'descr'} = chop_str($descr, $projects_list_description_width, 5); } if (!defined $pr->{'owner'}) { - $pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}") || ""; + $pr->{'owner'} = git_get_project_owner("$pr->{'path'}") || ""; } if ($check_forks) { my $pname = $pr->{'path'}; @@ -3513,7 +3631,7 @@ sub git_project_index { foreach my $pr (@projects) { if (!exists $pr->{'owner'}) { - $pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}"); + $pr->{'owner'} = git_get_project_owner("$pr->{'path'}"); } my ($path, $owner) = ($pr->{'path'}, $pr->{'owner'}); @@ -4129,8 +4247,10 @@ sub git_snapshot { my $git = git_cmd_str(); my $name = $project; + $name =~ s,([^/])/*\.git$,$1,; + $name = basename($name); + my $filename = to_utf8($name); $name =~ s/\047/\047\\\047\047/g; - my $filename = to_utf8(basename($project)); my $cmd; if ($suffix eq 'zip') { $filename .= "-$hash.$suffix"; @@ -4571,7 +4691,11 @@ sub git_commitdiff { die_error(undef, "Unknown commit object"); } - # we need to prepare $formats_nav before any parameter munging + # choose format for commitdiff for merge + if (! defined $hash_parent && @{$co{'parents'}} > 1) { + $hash_parent = '--cc'; + } + # we need to prepare $formats_nav before almost any parameter munging my $formats_nav; if ($format eq 'html') { $formats_nav = @@ -4579,7 +4703,8 @@ sub git_commitdiff { hash=>$hash, hash_parent=>$hash_parent)}, "raw"); - if (defined $hash_parent) { + if (defined $hash_parent && + $hash_parent ne '-c' && $hash_parent ne '--cc') { # commitdiff with two commits given my $hash_parent_short = $hash_parent; if ($hash_parent =~ m/^[0-9a-fA-F]{40}$/) { @@ -4611,6 +4736,17 @@ sub git_commitdiff { ')'; } else { # merge commit + if ($hash_parent eq '--cc') { + $formats_nav .= ' | ' . + $cgi->a({-href => href(action=>"commitdiff", + hash=>$hash, hash_parent=>'-c')}, + 'combined'); + } else { # $hash_parent eq '-c' + $formats_nav .= ' | ' . + $cgi->a({-href => href(action=>"commitdiff", + hash=>$hash, hash_parent=>'--cc')}, + 'compact'); + } $formats_nav .= ' (merge: ' . join(' ', map { @@ -4623,9 +4759,10 @@ sub git_commitdiff { } my $hash_parent_param = $hash_parent; - if (!defined $hash_parent) { + if (!defined $hash_parent_param) { + # --cc for multiple parents, --root for parentless $hash_parent_param = - @{$co{'parents'}} > 1 ? '-c' : $co{'parent'} || '--root'; + @{$co{'parents'}} > 1 ? '--cc' : $co{'parent'} || '--root'; } # read commitdiff @@ -4702,10 +4839,14 @@ TEXT # write patch if ($format eq 'html') { - git_difftree_body(\@difftree, $hash, $hash_parent || @{$co{'parents'}}); + my $use_parents = !defined $hash_parent || + $hash_parent eq '-c' || $hash_parent eq '--cc'; + git_difftree_body(\@difftree, $hash, + $use_parents ? @{$co{'parents'}} : $hash_parent); print "
\n"; - git_patchset_body($fd, \@difftree, $hash, $hash_parent || @{$co{'parents'}}); + git_patchset_body($fd, \@difftree, $hash, + $use_parents ? @{$co{'parents'}} : $hash_parent); close $fd; print "\n"; # class="page_body" git_footer_html();