* [PATCH 1/5] gitweb: Support comparing blobs with different names @ 2007-05-20 20:23 Martin Koegler 2007-05-20 20:23 ` [PATCH 2/5] gitweb: support filename prefix in git_patchset_body/git_difftree_body Martin Koegler 0 siblings, 1 reply; 9+ messages in thread From: Martin Koegler @ 2007-05-20 20:23 UTC (permalink / raw) To: Petr Baudis; +Cc: git, Martin Koegler Currently, blobdiff can only compare blobs with different file names, if no hb/hpb parameters are present. This patch adds support for comparing two blobs specified by any combination of hb/f/h and hpb/fp/hp. Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at> --- gitweb/gitweb.perl | 148 +++++++++++++++++++--------------------------------- 1 files changed, 53 insertions(+), 95 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 5c7011a..63ed14f 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -4238,109 +4238,66 @@ sub git_blobdiff { my $fd; my @difftree; my %diffinfo; - my $expires; - - # preparing $fd and %diffinfo for git_patchset_body - # new style URI - if (defined $hash_base && defined $hash_parent_base) { - if (defined $file_name) { - # read raw output - open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, - $hash_parent_base, $hash_base, - "--", (defined $file_parent ? $file_parent : ()), $file_name - or die_error(undef, "Open git-diff-tree failed"); - @difftree = map { chomp; $_ } <$fd>; - close $fd - or die_error(undef, "Reading git-diff-tree failed"); - @difftree - or die_error('404 Not Found', "Blob diff not found"); - - } elsif (defined $hash && - $hash =~ /[0-9a-fA-F]{40}/) { - # try to find filename from $hash - - # read filtered raw output - open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, - $hash_parent_base, $hash_base, "--" - or die_error(undef, "Open git-diff-tree failed"); - @difftree = - # ':100644 100644 03b21826... 3b93d5e7... M ls-files.c' - # $hash == to_id - grep { /^:[0-7]{6} [0-7]{6} [0-9a-fA-F]{40} $hash/ } - map { chomp; $_ } <$fd>; - close $fd - or die_error(undef, "Reading git-diff-tree failed"); - @difftree - or die_error('404 Not Found', "Blob diff not found"); + my $expires = '+1d'; + my ($from, $to); - } else { - die_error('404 Not Found', "Missing one of the blob diff parameters"); - } - - if (@difftree > 1) { - die_error('404 Not Found', "Ambiguous blob diff specification"); - } + $file_parent ||= $file_name; - %diffinfo = parse_difftree_raw_line($difftree[0]); - $file_parent ||= $diffinfo{'from_file'} || $file_name || $diffinfo{'file'}; - $file_name ||= $diffinfo{'to_file'} || $diffinfo{'file'}; - - $hash_parent ||= $diffinfo{'from_id'}; - $hash ||= $diffinfo{'to_id'}; - - # non-textual hash id's can be cached - if ($hash_base =~ m/^[0-9a-fA-F]{40}$/ && - $hash_parent_base =~ m/^[0-9a-fA-F]{40}$/) { - $expires = '+1d'; - } + # non-textual hash id's can be cached + if (defined $hash && $hash !~ m/^[0-9a-fA-F]{40}$/) { + $expires = undef; + } elsif (defined $hash_parent && $hash_parent !~ m/^[0-9a-fA-F]{40}$/) { + $expires = undef; + } elsif (defined $hash_base && $hash_base !~ m/^[0-9a-fA-F]{40}$/) { + $expires = undef; + } elsif (defined $hash_parent_base && $hash_parent_base !~ m/^[0-9a-fA-F]{40}$/) { + $expires = undef; + } + + # if hash parameter is missing, read it from the commit. + if (defined $hash_base && defined $file_name && !defined $hash) { + $hash = git_get_hash_by_path($hash_base, $file_name); + } - # open patch output - open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, - '-p', ($format eq 'html' ? "--full-index" : ()), - $hash_parent_base, $hash_base, - "--", (defined $file_parent ? $file_parent : ()), $file_name - or die_error(undef, "Open git-diff-tree failed"); + if (defined $hash_parent_base && defined $file_parent && !defined $hash_parent) { + $hash_parent = git_get_hash_by_path($hash_parent_base, $file_parent); + } + + if (!defined $hash || ! defined $hash_parent) { + die_error('404 Not Found', "Missing one of the blob diff parameters"); } - # old/legacy style URI - if (!%diffinfo && # if new style URI failed - defined $hash && defined $hash_parent) { - # fake git-diff-tree raw output - $diffinfo{'from_mode'} = $diffinfo{'to_mode'} = "blob"; - $diffinfo{'from_id'} = $hash_parent; - $diffinfo{'to_id'} = $hash; - if (defined $file_name) { - if (defined $file_parent) { - $diffinfo{'status'} = '2'; - $diffinfo{'from_file'} = $file_parent; - $diffinfo{'to_file'} = $file_name; - } else { # assume not renamed - $diffinfo{'status'} = '1'; - $diffinfo{'from_file'} = $file_name; - $diffinfo{'to_file'} = $file_name; - } - } else { # no filename given - $diffinfo{'status'} = '2'; - $diffinfo{'from_file'} = $hash_parent; - $diffinfo{'to_file'} = $hash; - } + if (defined $hash_base && defined $file_name) { + $to = $hash_base . ':' . $file_name; + } else { + $to = $hash; + } - # non-textual hash id's can be cached - if ($hash =~ m/^[0-9a-fA-F]{40}$/ && - $hash_parent =~ m/^[0-9a-fA-F]{40}$/) { - $expires = '+1d'; - } + if (defined $hash_parent_base && defined $file_parent) { + $from = $hash_parent_base . ':' . $file_parent; + } else { + $from = $hash_parent; + } - # open patch output - open $fd, "-|", git_cmd(), "diff", @diff_opts, - '-p', ($format eq 'html' ? "--full-index" : ()), - $hash_parent, $hash, "--" - or die_error(undef, "Open git-diff failed"); - } else { - die_error('404 Not Found', "Missing one of the blob diff parameters") - unless %diffinfo; + # fake git-diff-tree raw output + $diffinfo{'from_mode'} = $diffinfo{'to_mode'} = "blob"; + $diffinfo{'from_id'} = $hash_parent; + $diffinfo{'to_id'} = $hash; + if (defined $file_name) { + $diffinfo{'status'} = '2'; + $diffinfo{'from_file'} = $file_parent; + $diffinfo{'to_file'} = $file_name; + } else { # no filename given + $diffinfo{'status'} = '2'; + $diffinfo{'from_file'} = $hash_parent; + $diffinfo{'to_file'} = $hash; } + # open patch output + open $fd, "-|", git_cmd(), "diff", @diff_opts, '-p', "--full-index", + ($format eq 'html' ? "--raw" : ()), $from, $to, "--" + or die_error(undef, "Open git-diff failed"); + # header if ($format eq 'html') { my $formats_nav = @@ -4364,11 +4321,12 @@ sub git_blobdiff { } } elsif ($format eq 'plain') { + my $patch_file_name = $file_name || $hash; print $cgi->header( -type => 'text/plain', -charset => 'utf-8', -expires => $expires, - -content_disposition => 'inline; filename="' . "$file_name" . '.patch"'); + -content_disposition => 'inline; filename="' . "$patch_file_name" . '.patch"'); print "X-Git-Url: " . $cgi->self_url() . "\n\n"; -- 1.5.2.rc3.802.g4b4b7 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/5] gitweb: support filename prefix in git_patchset_body/git_difftree_body 2007-05-20 20:23 [PATCH 1/5] gitweb: Support comparing blobs with different names Martin Koegler @ 2007-05-20 20:23 ` Martin Koegler 2007-05-20 20:23 ` [PATCH 3/5] gitweb: Add treediff view Martin Koegler 0 siblings, 1 reply; 9+ messages in thread From: Martin Koegler @ 2007-05-20 20:23 UTC (permalink / raw) To: Petr Baudis; +Cc: git, Martin Koegler git_treediff supports comparing subdirectories. As the output of git-difftree is missing the path to the compared directories, the links in the output would be wrong. The patch adds two new parameters to add the missing path prefix. Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at> --- gitweb/gitweb.perl | 72 +++++++++++++++++++++++++++++----------------------- 1 files changed, 40 insertions(+), 32 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 63ed14f..33aba86 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2366,9 +2366,13 @@ sub from_ids_eq { sub git_difftree_body { - my ($difftree, $hash, @parents) = @_; + my ($difftree, $from_prefix, $to_prefix, $hash, @parents) = @_; my ($parent) = $parents[0]; my ($have_blame) = gitweb_check_feature('blame'); + + $from_prefix = !defined $from_prefix ? '' : $from_prefix.'/'; + $to_prefix = !defined $to_prefix ? '' : $to_prefix . '/'; + print "<div class=\"list_head\">\n"; if ($#{$difftree} > 10) { print(($#{$difftree} + 1) . " files changed:\n"); @@ -2405,7 +2409,7 @@ sub git_difftree_body { # file exists in the result (child) commit print "<td>" . $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - file_name=>$diff->{'to_file'}, + file_name=>$to_prefix.$diff->{'to_file'}, hash_base=>$hash), -class => "list"}, esc_path($diff->{'to_file'})) . "</td>\n"; @@ -2442,7 +2446,7 @@ sub git_difftree_body { $cgi->a({-href => href(action=>"blob", hash_base=>$hash, hash=>$from_hash, - file_name=>$from_path)}, + file_name=>$from_prefix.$from_path)}, "blob" . ($i+1)) . " | </td>\n"; } else { @@ -2456,8 +2460,8 @@ sub git_difftree_body { hash_parent=>$from_hash, hash_base=>$hash, hash_parent_base=>$hash_parent, - file_name=>$diff->{'to_file'}, - file_parent=>$from_path)}, + file_name=>$to_prefix.$diff->{'to_file'}, + file_parent=>$from_prefix.$from_path)}, "diff" . ($i+1)) . " | </td>\n"; } @@ -2467,14 +2471,14 @@ sub git_difftree_body { if ($not_deleted) { print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - file_name=>$diff->{'to_file'}, + file_name=>$to_prefix.$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=>$to_prefix.$diff->{'to_file'}, hash_base=>$hash)}, "history"); } @@ -2508,7 +2512,7 @@ sub git_difftree_body { $mode_chng .= "]</span>"; print "<td>"; print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - hash_base=>$hash, file_name=>$diff->{'file'}), + hash_base=>$hash, file_name=>$to_prefix.$diff->{'file'}), -class => "list"}, esc_path($diff->{'file'})); print "</td>\n"; print "<td>$mode_chng</td>\n"; @@ -2520,7 +2524,7 @@ sub git_difftree_body { print " | "; } print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - hash_base=>$hash, file_name=>$diff->{'file'})}, + hash_base=>$hash, file_name=>$to_prefix.$diff->{'file'})}, "blob"); print "</td>\n"; @@ -2528,7 +2532,7 @@ sub git_difftree_body { my $mode_chng = "<span class=\"file_status deleted\">[deleted $from_file_type]</span>"; print "<td>"; print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'from_id'}, - hash_base=>$parent, file_name=>$diff->{'file'}), + hash_base=>$parent, file_name=>$from_prefix.$diff->{'file'}), -class => "list"}, esc_path($diff->{'file'})); print "</td>\n"; print "<td>$mode_chng</td>\n"; @@ -2540,15 +2544,15 @@ sub git_difftree_body { print " | "; } print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'from_id'}, - hash_base=>$parent, file_name=>$diff->{'file'})}, + hash_base=>$parent, file_name=>$from_prefix.$diff->{'file'})}, "blob") . " | "; if ($have_blame) { print $cgi->a({-href => href(action=>"blame", hash_base=>$parent, - file_name=>$diff->{'file'})}, + file_name=>$from_prefix.$diff->{'file'})}, "blame") . " | "; } print $cgi->a({-href => href(action=>"history", hash_base=>$parent, - file_name=>$diff->{'file'})}, + file_name=>$from_prefix.$diff->{'file'})}, "history"); print "</td>\n"; @@ -2570,7 +2574,7 @@ sub git_difftree_body { } print "<td>"; print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - hash_base=>$hash, file_name=>$diff->{'file'}), + hash_base=>$hash, file_name=>$to_prefix.$diff->{'file'}), -class => "list"}, esc_path($diff->{'file'})); print "</td>\n"; print "<td>$mode_chnge</td>\n"; @@ -2585,20 +2589,21 @@ sub git_difftree_body { print $cgi->a({-href => href(action=>"blobdiff", hash=>$diff->{'to_id'}, hash_parent=>$diff->{'from_id'}, hash_base=>$hash, hash_parent_base=>$parent, - file_name=>$diff->{'file'})}, + file_name=>$to_prefix.$diff->{'file'}, + file_parent=>$from_prefix.$diff->{'file'})}, "diff") . " | "; } print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - hash_base=>$hash, file_name=>$diff->{'file'})}, + hash_base=>$hash, file_name=>$to_prefix.$diff->{'file'})}, "blob") . " | "; if ($have_blame) { print $cgi->a({-href => href(action=>"blame", hash_base=>$hash, - file_name=>$diff->{'file'})}, + file_name=>$to_prefix.$diff->{'file'})}, "blame") . " | "; } print $cgi->a({-href => href(action=>"history", hash_base=>$hash, - file_name=>$diff->{'file'})}, + file_name=>$to_prefix.$diff->{'file'})}, "history"); print "</td>\n"; @@ -2612,11 +2617,11 @@ sub git_difftree_body { } print "<td>" . $cgi->a({-href => href(action=>"blob", hash_base=>$hash, - hash=>$diff->{'to_id'}, file_name=>$diff->{'to_file'}), + hash=>$diff->{'to_id'}, file_name=>$to_prefix.$diff->{'to_file'}), -class => "list"}, esc_path($diff->{'to_file'})) . "</td>\n" . "<td><span class=\"file_status $nstatus\">[$nstatus from " . $cgi->a({-href => href(action=>"blob", hash_base=>$parent, - hash=>$diff->{'from_id'}, file_name=>$diff->{'from_file'}), + hash=>$diff->{'from_id'}, file_name=>$from_prefix.$diff->{'from_file'}), -class => "list"}, esc_path($diff->{'from_file'})) . " with " . (int $diff->{'similarity'}) . "% similarity$mode_chng]</span></td>\n" . "<td class=\"link\">"; @@ -2630,20 +2635,20 @@ sub git_difftree_body { print $cgi->a({-href => href(action=>"blobdiff", 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=>$to_prefix.$diff->{'to_file'}, file_parent=>$from_prefix.$diff->{'from_file'})}, "diff") . " | "; } print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - hash_base=>$parent, file_name=>$diff->{'to_file'})}, + hash_base=>$parent, file_name=>$to_prefix.$diff->{'to_file'})}, "blob") . " | "; if ($have_blame) { print $cgi->a({-href => href(action=>"blame", hash_base=>$hash, - file_name=>$diff->{'to_file'})}, + file_name=>$to_prefix.$diff->{'to_file'})}, "blame") . " | "; } print $cgi->a({-href => href(action=>"history", hash_base=>$hash, - file_name=>$diff->{'to_file'})}, + file_name=>$to_prefix.$diff->{'to_file'})}, "history"); print "</td>\n"; @@ -2654,7 +2659,7 @@ sub git_difftree_body { } sub git_patchset_body { - my ($fd, $difftree, $hash, @hash_parents) = @_; + my ($fd, $difftree, $from_prefix, $to_prefix, $hash, @hash_parents) = @_; my ($hash_parent) = $hash_parents[0]; my $patch_idx = 0; @@ -2663,6 +2668,9 @@ sub git_patchset_body { my $diffinfo; my (%from, %to); + $from_prefix = !defined $from_prefix ? '' : $from_prefix.'/'; + $to_prefix = !defined $to_prefix ? '' : $to_prefix . '/'; + print "<div class=\"patchset\">\n"; # skip to first patch @@ -2733,7 +2741,7 @@ sub git_patchset_body { $from{'href'}[$i] = href(action=>"blob", hash_base=>$hash_parents[$i], hash=>$diffinfo->{'from_id'}[$i], - file_name=>$from{'file'}[$i]); + file_name=>$from_prefix.$from{'file'}[$i]); } else { $from{'href'}[$i] = undef; } @@ -2743,7 +2751,7 @@ sub git_patchset_body { if ($diffinfo->{'status'} ne "A") { # not new (added) file $from{'href'} = href(action=>"blob", hash_base=>$hash_parent, hash=>$diffinfo->{'from_id'}, - file_name=>$from{'file'}); + file_name=>$from_prefix.$from{'file'}); } else { delete $from{'href'}; } @@ -2753,7 +2761,7 @@ sub git_patchset_body { if ($diffinfo->{'to_id'} ne ('0' x 40)) { # file exists in result $to{'href'} = href(action=>"blob", hash_base=>$hash, hash=>$diffinfo->{'to_id'}, - file_name=>$to{'file'}); + file_name=>$to_prefix.$to{'file'}); } else { delete $to{'href'}; } @@ -4180,7 +4188,7 @@ sub git_commit { git_print_log($co{'comment'}); print "</div>\n"; - git_difftree_body(\@difftree, $hash, @$parents); + git_difftree_body(\@difftree, undef, undef, $hash, @$parents); git_footer_html(); } @@ -4338,7 +4346,7 @@ sub git_blobdiff { if ($format eq 'html') { print "<div class=\"page_body\">\n"; - git_patchset_body($fd, [ \%diffinfo ], $hash_base, $hash_parent_base); + git_patchset_body($fd, [ \%diffinfo ], undef, undef, $hash_base, $hash_parent_base); close $fd; print "</div>\n"; # class="page_body" @@ -4495,10 +4503,10 @@ TEXT # write patch if ($format eq 'html') { - git_difftree_body(\@difftree, $hash, $hash_parent || @{$co{'parents'}}); + git_difftree_body(\@difftree, undef, undef, $hash, $hash_parent || @{$co{'parents'}}); print "<br/>\n"; - git_patchset_body($fd, \@difftree, $hash, $hash_parent || @{$co{'parents'}}); + git_patchset_body($fd, \@difftree, undef, undef, $hash, $hash_parent || @{$co{'parents'}}); close $fd; print "</div>\n"; # class="page_body" git_footer_html(); -- 1.5.2.rc3.802.g4b4b7 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/5] gitweb: Add treediff view 2007-05-20 20:23 ` [PATCH 2/5] gitweb: support filename prefix in git_patchset_body/git_difftree_body Martin Koegler @ 2007-05-20 20:23 ` Martin Koegler 2007-05-20 20:23 ` [PATCH 4/5] gitweb: Selecting diffs in JavaScript Martin Koegler 0 siblings, 1 reply; 9+ messages in thread From: Martin Koegler @ 2007-05-20 20:23 UTC (permalink / raw) To: Petr Baudis; +Cc: git, Martin Koegler git_treediff supports comparing different trees. A tree can be specified either as hash or as base hash and filename. Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at> --- gitweb/gitweb.perl | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 116 insertions(+), 0 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 33aba86..d161c8b 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -480,6 +480,8 @@ my %actions = ( "tag" => \&git_tag, "tags" => \&git_tags, "tree" => \&git_tree, + "treediff" => \&git_treediff, + "treediff_plain" => \&git_treediff_plain, "snapshot" => \&git_snapshot, "object" => \&git_object, # those below don't need $project @@ -4523,6 +4525,120 @@ sub git_commitdiff_plain { git_commitdiff('plain'); } +sub git_treediff { + my $format = shift || 'html'; + my $expires = '+1d'; + + # non-textual hash id's can be cached + if (defined $hash && $hash !~ m/^[0-9a-fA-F]{40}$/) { + $expires = undef; + } elsif (defined $hash_parent && $hash_parent !~ m/^[0-9a-fA-F]{40}$/) { + $expires = undef; + } elsif (defined $hash_base && $hash_base !~ m/^[0-9a-fA-F]{40}$/) { + $expires = undef; + } elsif (defined $hash_parent_base && $hash_parent_base !~ m/^[0-9a-fA-F]{40}$/) { + $expires = undef; + } + + # we need to prepare $formats_nav before any parameter munging + my $formats_nav; + if ($format eq 'html') { + $formats_nav = + $cgi->a({-href => href(action=>"treediff_plain", + hash=>$hash, hash_parent=>$hash_parent, + hash_base=>$hash_base, hash_parent_base=>$hash_parent_base, + file_name=>$file_name, file_parent=>$file_parent)}, + "raw"); + } + + if (!defined $hash) { + if (!defined $hash_base) { + die_error(undef,'tree parameter missing'); + } + $hash = $hash_base; + $hash .= ":".$file_name if (defined $file_name); + } + + if (!defined $hash_parent) { + if (!defined $hash_parent_base) { + die_error(undef,'tree parameter missing'); + } + $hash_parent = $hash_parent_base; + $hash_parent .= ":".$file_parent if (defined $file_parent); + } + + # read treediff + my $fd; + my @difftree; + if ($format eq 'html') { + open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, + "--no-commit-id", "--patch-with-raw", "--full-index", + $hash_parent, $hash, "--" + or die_error(undef, "Open git-diff-tree failed"); + + while (my $line = <$fd>) { + chomp $line; + # empty line ends raw part of diff-tree output + last unless $line; + push @difftree, $line; + } + + } elsif ($format eq 'plain') { + open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, + '-p', $hash_parent, $hash, "--" + or die_error(undef, "Open git-diff-tree failed"); + + } else { + die_error(undef, "Unknown treediff format"); + } + + # write header + if ($format eq 'html') { + git_header_html(undef, $expires); + if (defined $hash_base && (my %co = parse_commit($hash_base))) { + git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); + git_print_header_div('commit', esc_html($co{'title'}), $hash_base); + } else { + print "<div class=\"page_nav\"><br/>$formats_nav<br/></div>\n"; + print "<div class=\"title\">$hash vs $hash_parent</div>\n"; + } + print "<div class=\"page_body\">\n"; + + } elsif ($format eq 'plain') { + my $filename = basename($project) . "-$hash-$hash_parent.patch"; + + print $cgi->header( + -type => 'text/plain', + -charset => 'utf-8', + -expires => $expires, + -content_disposition => 'inline; filename="' . "$filename" . '"'); + + print "X-Git-Url: " . $cgi->self_url() . "\n\n"; + print "---\n\n"; + } + + # write patch + if ($format eq 'html') { + git_difftree_body(\@difftree, $file_parent, $file_name, $hash_base, $hash_parent_base); + print "<br/>\n"; + + git_patchset_body($fd, \@difftree, $file_parent, $file_name, $hash_base, $hash_parent_base); + close $fd; + print "</div>\n"; # class="page_body" + git_footer_html(); + + } elsif ($format eq 'plain') { + local $/ = undef; + print <$fd>; + close $fd + or print "Reading git-diff-tree failed\n"; + } +} + +sub git_treediff_plain { + git_treediff('plain'); +} + sub git_history { if (!defined $hash_base) { $hash_base = git_get_head_hash($project); -- 1.5.2.rc3.802.g4b4b7 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/5] gitweb: Selecting diffs in JavaScript 2007-05-20 20:23 ` [PATCH 3/5] gitweb: Add treediff view Martin Koegler @ 2007-05-20 20:23 ` Martin Koegler 2007-05-20 20:23 ` [PATCH 5/5] gitweb: Incremental blame Martin Koegler 2007-08-26 1:17 ` [PATCH 4/5] gitweb: Selecting diffs in JavaScript Petr Baudis 0 siblings, 2 replies; 9+ messages in thread From: Martin Koegler @ 2007-05-20 20:23 UTC (permalink / raw) To: Petr Baudis; +Cc: git, Martin Koegler The adds support for selecting arbitrary diffs, if the client browser supports JavaScript. Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at> --- Makefile | 6 +- git-instaweb.sh | 7 ++ gitweb/gitweb.js | 298 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gitweb/gitweb.perl | 6 + 4 files changed, 316 insertions(+), 1 deletions(-) create mode 100644 gitweb/gitweb.js diff --git a/Makefile b/Makefile index 521c003..2d04ef9 100644 --- a/Makefile +++ b/Makefile @@ -167,6 +167,7 @@ GITWEB_HOMETEXT = indextext.html GITWEB_CSS = gitweb.css GITWEB_LOGO = git-logo.png GITWEB_FAVICON = git-favicon.png +GITWEB_JS = gitweb.js GITWEB_SITE_HEADER = GITWEB_SITE_FOOTER = @@ -811,13 +812,14 @@ gitweb/gitweb.cgi: gitweb/gitweb.perl -e 's|++GITWEB_CSS++|$(GITWEB_CSS)|g' \ -e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \ -e 's|++GITWEB_FAVICON++|$(GITWEB_FAVICON)|g' \ + -e 's|++GITWEB_JS++|$(GITWEB_JS)|g' \ -e 's|++GITWEB_SITE_HEADER++|$(GITWEB_SITE_HEADER)|g' \ -e 's|++GITWEB_SITE_FOOTER++|$(GITWEB_SITE_FOOTER)|g' \ $< >$@+ && \ chmod +x $@+ && \ mv $@+ $@ -git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css +git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css gitweb/gitweb.js $(QUIET_GEN)rm -f $@ $@+ && \ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ @@ -826,6 +828,8 @@ git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css -e '/@@GITWEB_CGI@@/d' \ -e '/@@GITWEB_CSS@@/r gitweb/gitweb.css' \ -e '/@@GITWEB_CSS@@/d' \ + -e '/@@GITWEB_JS@@/r gitweb/gitweb.js' \ + -e '/@@GITWEB_JS@@/d' \ $@.sh > $@+ && \ chmod +x $@+ && \ mv $@+ $@ diff --git a/git-instaweb.sh b/git-instaweb.sh index cbc7418..8cb62f1 100755 --- a/git-instaweb.sh +++ b/git-instaweb.sh @@ -233,8 +233,15 @@ gitweb_css () { EOFGITWEB } +gitweb_js () { + cat > "$1" <<\EOFGITWEB +@@GITWEB_JS@@ +EOFGITWEB +} + gitweb_cgi $GIT_DIR/gitweb/gitweb.cgi gitweb_css $GIT_DIR/gitweb/gitweb.css +gitweb_js $GIT_DIR/gitweb/gitweb.js case "$httpd" in *lighttpd*) diff --git a/gitweb/gitweb.js b/gitweb/gitweb.js new file mode 100644 index 0000000..cacab5a --- /dev/null +++ b/gitweb/gitweb.js @@ -0,0 +1,298 @@ +/* Javascript functions for gitweb + + (C) 2007 Martin Koegler <mkoegler@auto.tuwien.ac.at> + + This file is licensed under the GPL v2, or (at your option) any later version. +*/ + +function getCookie (name) +{ + var name = name + "="; + var c = document.cookie; + var p = c.indexOf (name); + if (p == -1) + return null; + c = c.substr (p + name.length, c.length); + p = c.indexOf (";"); + if (p == -1) + return c; + else + return c.substr (0, p); +} + +function insertAfter (elem, node) +{ + if (node.nextSibling) + node.parentNode.insertBefore (elem, node.nextSibling); + else + node.parentNode.appendChild (elem); +} + +function createLink (href, linktext) +{ + var l = document.createElement ("a"); + l.appendChild (document.createTextNode (linktext)); + l.href = href; + return l; +} + +function createLinkGroup (href1, basetxt, href2, difftxt) +{ + var l = document.createElement ("span"); + l.appendChild (document.createTextNode (" (")); + l.appendChild (createLink (href1, basetxt)); + l.appendChild (document.createTextNode (" | ")); + l.appendChild (createLink (href2, difftxt)); + l.appendChild (document.createTextNode (") ")); + return l; +} + +function GitRef () +{ + this.t = null; + this.h = null; + this.hb = null; + this.f = null; + this.p = null; + this.ToRef = ToRef; +} + +function ToRef () +{ + var parts = new Array (); + if (this.f) + parts.push ("f=" + this.f); + if (this.h) + parts.push ("h=" + this.h); + if (this.hb) + parts.push ("hb=" + this.hb); + if (this.t) + parts.push ("t=" + this.t); + if (this.p) + parts.push ("p=" + this.p); + return parts.join ("@"); +} + +function splitGitRef (ref) +{ + var parts = ref.split ("@"); + var res = new GitRef (); + var i; + for (i = 0; i < parts.length; i++) + { + var p = parts[i].split ("="); + res[p[0]] = p[1]; + } + return res; +} + +function GitURL (base) +{ + this.base = base; + this.p = null; + this.a = null; + this.f = null; + this.fp = null; + this.h = null; + this.hp = null; + this.hb = null; + this.hpb = null; + this.pg = null; + this.o = null; + this.s = null; + this.st = null; + this.ToURL = ToURL; + this.ToRef = UrlToRef; + this.ToDUrl = ToDUrl; +} + +function ToURL () +{ + var parts = new Array (); + if (this.p) + parts.push ("p=" + this.p); + if (this.a) + parts.push ("a=" + this.a); + if (this.f) + parts.push ("f=" + this.f); + if (this.fp) + parts.push ("fp=" + this.fp); + if (this.h) + parts.push ("h=" + this.h); + if (this.hp) + parts.push ("hp=" + this.hp); + if (this.hb) + parts.push ("hb=" + this.hb); + if (this.hpb) + parts.push ("hpb=" + this.hpb); + if (this.o) + parts.push ("o=" + this.o); + if (this.s) + parts.push ("s=" + this.s); + if (this.st) + parts.push ("st=" + this.st); + return this.base + "?" + parts.join (";"); +} + +function UrlToRef (type) +{ + var res = new GitRef; + res.f = this.f; + res.h = this.h; + res.hb = this.hb; + res.t = type; + res.p = this.p; + return res.ToRef (); +} + +function ToDUrl (type) +{ + var res = new GitURL (this.base); + res.f = this.f; + res.h = this.h; + res.hb = this.hb; + res.p = this.p; + res.a = type; + return res.ToURL (); +} + +function splitGitURL (url) +{ + var Urls = url.split ("?"); + var res = new GitURL (Urls[0]); + if (Urls.length > 1) + { + var parts = Urls[1].split (";"); + var i; + for (i = 0; i < parts.length; i++) + { + var p = parts[i].split ("="); + res[p[0]] = p[1]; + } + } + return res; +} + +function base (ref) +{ + document.cookie = "basename=" + ref; +} + +function diff (url) +{ + var c = getCookie ("basename"); + if (!c) + { + alert ("no diff base selected"); + return; + } + c = splitGitRef (c); + url = splitGitURL (url); + + if (c.p != url.p) + { + alert ("base object in an other repository"); + return; + } + + if (c.t == 'commit' && url.a == 'commit') + { + url.a = 'commitdiff'; + if (!c.h || !url.h) + { + alert ("commit diff not possible"); + return; + } + url.hb = null; + url.f = null; + url.hp = c.h; + document.location.href = url.ToURL (); + return; + } + if (c.t == 'blob' && url.a == 'blob') + { + url.a = 'blobdiff'; + url.hp = c.h; + url.hpb = c.hb; + url.fp = c.f; + document.location.href = url.ToURL (); + return; + } + if (c.t == 'tree' && url.a == 'tree') + { + url.a = 'treediff'; + url.hpb = c.hb; + url.hp = c.h; + url.fp = c.f; + document.location.href = url.ToURL (); + return; + } + if (c.t == 'commit' && url.a == 'tree') + { + url.a = 'treediff'; + url.hpb = c.h; + url.hp = null; + url.fp = null; + document.location.href = url.ToURL (); + return; + } + if (c.t == 'tree' && url.a == 'commit') + { + url.a = 'treediff'; + url.hpb = c.hb; + url.hp = c.h; + url.fp = c.f; + url.hb = url.h; + url.h = null; + document.location.href = url.ToURL (); + return; + } + alert ("diff not possible"); +} + +function GitAddLinks () +{ + var links = document.getElementsByTagName ("a"); + var i; + + for (i = 0; i < links.length; i++) + { + var link = links[i]; + var url = splitGitURL (link.href); + if (link.innerHTML == 'commit' || link.innerHTML == 'tag') + { + if (!url.h) + continue; + var l = + createLinkGroup ("javascript:base('" + url.ToRef ('commit') + + "')", "base", + "javascript:diff('" + url.ToDUrl ('commit') + + "')", "diff"); + insertAfter (l, link); + } + if (link.innerHTML == 'blob') + { + if (!url.h && !(url.hb && url.f)) + continue; + var l = + createLinkGroup ("javascript:base('" + url.ToRef ('blob') + "')", + "base", + "javascript:diff('" + url.ToDUrl ('blob') + "')", + "diff"); + insertAfter (l, link); + } + if (link.innerHTML == 'tree') + { + if (!url.h && !(url.hb && url.f)) + continue; + var l = + createLinkGroup ("javascript:base('" + url.ToRef ('tree') + "')", + "base", + "javascript:diff('" + url.ToDUrl ('tree') + "')", + "diff"); + insertAfter (l, link); + } + } +} + +window.onload = GitAddLinks; diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index d161c8b..f59a4b5 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -61,6 +61,8 @@ our $stylesheet = undef; our $logo = "++GITWEB_LOGO++"; # URI of GIT favicon, assumed to be image/png type our $favicon = "++GITWEB_FAVICON++"; +# URI of gitweb.js +our $gitwebjs = "++GITWEB_JS++"; # URI and label (title) of GIT logo link #our $logo_url = "http://www.kernel.org/pub/software/scm/git/docs/"; @@ -1909,6 +1911,10 @@ EOF print qq(<link rel="shortcut icon" href="$favicon" type="image/png"/>\n); } + if (defined $gitwebjs) { + print qq(<script src="$gitwebjs" type="text/javascript"></script>\n); + } + print "</head>\n" . "<body>\n"; -- 1.5.2.rc3.802.g4b4b7 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/5] gitweb: Incremental blame 2007-05-20 20:23 ` [PATCH 4/5] gitweb: Selecting diffs in JavaScript Martin Koegler @ 2007-05-20 20:23 ` Martin Koegler 2007-08-26 1:17 ` [PATCH 4/5] gitweb: Selecting diffs in JavaScript Petr Baudis 1 sibling, 0 replies; 9+ messages in thread From: Martin Koegler @ 2007-05-20 20:23 UTC (permalink / raw) To: Petr Baudis; +Cc: git, Martin Koegler Rewrite ontop of diff patches + some performance tuning. --- The first chunk is the new version of the link rewriting for git-blame. It does not need the blamelink class. As gitweb.js is included in each page (and I didn't wanted to add a second JavaScript file), I added the content of blame.js at the end of gitweb.js. I also tried some optimizations. In IceWeasel 2.0.0.3 (= FireFox), the blame of sha1_file.c needs now 33 instead of 46 seconds on my computer. The "optimizations" are not tested in other browsers. According to my experience, I expect that the incremental blame in IE will be slower then in Mozilla. gitweb/gitweb.js | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gitweb/gitweb.perl | 92 ++++++++++++++++++++++++--- 2 files changed, 264 insertions(+), 9 deletions(-) diff --git a/gitweb/gitweb.js b/gitweb/gitweb.js index cacab5a..001fac6 100644 --- a/gitweb/gitweb.js +++ b/gitweb/gitweb.js @@ -259,6 +259,11 @@ function GitAddLinks () { var link = links[i]; var url = splitGitURL (link.href); + if (url.a == "blame") + { + url.a = "blame_incremental"; + link.href = url.ToURL(); + } if (link.innerHTML == 'commit' || link.innerHTML == 'tag') { if (!url.h) @@ -296,3 +301,179 @@ function GitAddLinks () } window.onload = GitAddLinks; + +// Blame Javascript functions +// Copyright (C) 2007, Fredrik Kuivinen <frekui@gmail.com> +// modifed by Martin Koegler <mkoegler@auto.tuwien.ac.at> + +function createRequestObject() { + var ro; + if (window.XMLHttpRequest) { + ro = new XMLHttpRequest(); + } else { + ro = new ActiveXObject("Microsoft.XMLHTTP"); + } + return ro; +} + +var http; +var baseUrl; + +// 'commits' is an associative map. It maps SHA1s to Commit objects. +var commits = new Object(); + +function Commit(sha1) +{ + this.sha1 = sha1; +} + +function zeroPad(n) +{ + if (n < 10) + return '0' + n; + else + return n.toString(); +} + +function handleLine(commit) +{ + /* This is the structure of the HTML fragment we are working + with: + + <tr id="l123" class="light2"> + <td class="sha1" title=""> + <a href=""></a> + </td> + <td class="linenr"> + <a class="linenr" href="">123</a> + </td> + <td class="pre"># times (my ext3 doesn't).</td> + </tr> + */ + var tr = document.getElementById('l'+commit.resline); + var linkurl = baseUrl + ';a=blame_incremental;hb=' + commit.sha1 + + ';f=' + commit.filename + '#l' + commit.srcline; + + var date = new Date(); + date.setTime(commit.authorTime * 1000); + var dateStr = date.getUTCFullYear() + '-' + + zeroPad(date.getUTCMonth()+1) + '-' + + zeroPad(date.getUTCDate()); + var timeStr = zeroPad(date.getUTCHours()) + ':' + + zeroPad(date.getUTCMinutes()) + ':' + + zeroPad(date.getUTCSeconds()); + var title = commit.author + ', ' + dateStr + ' ' + timeStr; + + for (var i = 0; i < commit.numlines; i++) { + tr.firstChild.title = title; + var shaAnchor = tr.firstChild.firstChild; + if (i == 0) { + shaAnchor.href = baseUrl + ';a=commit;h=' + commit.sha1; + shaAnchor.innerHTML = commit.sha1.substr(0, 8); + } else { + if (shaAnchor.innerHTML != '') + shaAnchor.innerHTML = ''; + } + + tr.firstChild.nextSibling.firstChild.href = linkurl; + + tr = tr.nextSibling; + while (tr && tr.nodeType == 3) + tr = tr.nextSibling; + } +} + +function fixColors() +{ + var colorClasses = ['light2', 'dark2']; + var tr = document.getElementById('l1'); + var colorClass = 0; + + while (tr) { + if (tr.firstChild.firstChild.innerHTML != '') + colorClass = (colorClass+1)%2; + + if (tr.className != colorClasses[colorClass]) + tr.className = colorClasses[colorClass]; + tr = tr.nextSibling; + while (tr && tr.nodeType == 3) + tr = tr.nextSibling; + } +} + +var prevDataLength = -1; +var nextLine = 0; +var inProgress = false; + +var curCommit = new Commit(); + +function handleResponse() { + if (http.readyState != 4 && http.readyState != 3) + return; + + // In konqueror http.responseText is sometimes null here... + if (http.responseText === null) + return; + + if (inProgress) + return; + else + inProgress = true; + + while (prevDataLength != http.responseText.length) { + if (http.readyState == 4 + && prevDataLength == http.responseText.length) { + break; + } + + prevDataLength = http.responseText.length; + var response = http.responseText.substring(nextLine); + var lines = response.split('\n'); + nextLine = nextLine + response.lastIndexOf('\n') + 1; + if (response[response.length-1] != '\n') { + lines.pop(); + } + + for (var i = 0; i < lines.length; i++) { + var split = lines[i].split(' '); + if (split.length == 4 && split[0].length == 40) { + var sha1 = split[0]; + var c = commits[sha1]; + if (!c) { + c = new Commit(sha1); + commits[sha1] = c; + } + + c.srcline = split[1]; + c.resline = split[2]; + c.numlines = split[3]; + curCommit = c; + } else { + var info = split[0]; + var data = lines[i].substr (info.length + 1); + if (info == 'filename') { + curCommit.filename = data; + handleLine(curCommit); + } else if (info == 'author') { + curCommit.author = data; + } else if (info == 'author-time') { + curCommit.authorTime = parseInt(data); + } + } + } + } + + if (http.readyState == 4 && prevDataLength == http.responseText.length) + fixColors(); + + inProgress = false; +} + +function startBlame(blamedataUrl, bUrl) +{ + baseUrl = bUrl; + http = createRequestObject(); + http.open('get', blamedataUrl); + http.onreadystatechange = handleResponse; + http.send(null); +} diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index f59a4b5..45787a6 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -462,6 +462,8 @@ $git_dir = "$projectroot/$project" if $project; # dispatch my %actions = ( "blame" => \&git_blame2, + "blame_incremental" => \&git_blame_incremental, + "blame_data" => \&git_blame_data, "blobdiff" => \&git_blobdiff, "blobdiff_plain" => \&git_blobdiff_plain, "blob" => \&git_blob, @@ -562,7 +564,7 @@ sub href(%) { push @result, $symbol . "=" . esc_param($params{$name}); } } - $href .= "?" . join(';', @result) if scalar @result; + $href .= "?" . join(';', @result) if $params{-partial_query} or scalar @result; return $href; } @@ -3517,7 +3519,47 @@ sub git_tag { git_footer_html(); } -sub git_blame2 { +sub git_blame_data { + my $fd; + my $ftype; + + my ($have_blame) = gitweb_check_feature('blame'); + if (!$have_blame) { + die_error('403 Permission denied', "Permission denied"); + } + die_error('404 Not Found', "File name not defined") if (!$file_name); + $hash_base ||= git_get_head_hash($project); + die_error(undef, "Couldn't find base commit") unless ($hash_base); + my %co = parse_commit($hash_base) + or die_error(undef, "Reading commit failed"); + if (!defined $hash) { + $hash = git_get_hash_by_path($hash_base, $file_name, "blob") + or die_error(undef, "Error looking up file"); + } + $ftype = git_get_type($hash); + if ($ftype !~ "blob") { + die_error("400 Bad Request", "Object is not a blob"); + } + open ($fd, "-|", git_cmd(), "blame", '--incremental', $hash_base, '--', + $file_name) + or die_error(undef, "Open git-blame --incremental failed"); + + print $cgi->header(-type=>"text/plain", -charset => 'utf-8', + -status=> "200 OK"); + + while(<$fd>) { + if (/^([0-9a-f]{40}) ([0-9]+) ([0-9]+) ([0-9]+)/ or + /^author-time |^author |^filename /) { + print; + } + } + + close $fd or print "Reading blame data failed\n"; +} + +sub git_blame_common { + my ($type) = @_; + my $fd; my $ftype; @@ -3536,11 +3578,16 @@ sub git_blame2 { } $ftype = git_get_type($hash); if ($ftype !~ "blob") { - die_error('400 Bad Request', "Object is not a blob"); + die_error("400 Bad Request", "Object is not a blob"); + } + if ($type eq 'incremental') { + open ($fd, "-|", git_cmd(), 'cat-file', 'blob', $hash) + or die_error(undef, "Open git-cat-file failed"); + } else { + open ($fd, "-|", git_cmd(), 'blame', '-p', '--', + $file_name, $hash_base) + or die_error(undef, "Open git-blame failed"); } - open ($fd, "-|", git_cmd(), "blame", '-p', '--', - $file_name, $hash_base) - or die_error(undef, "Open git-blame failed"); git_header_html(); my $formats_nav = $cgi->a({-href => href(action=>"blob", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)}, @@ -3564,9 +3611,19 @@ sub git_blame2 { <tr><th>Commit</th><th>Line</th><th>Data</th></tr> HTML my %metainfo = (); - while (1) { - $_ = <$fd>; - last unless defined $_; + my $linenr = 0; + while (<$fd>) { + chomp; + if ($type eq 'incremental') { + # Empty stage with just the file contents + $linenr += 1; + print "<tr id=\"l$linenr\" class=\"light2\">"; + print '<td class="sha1"><a href=""></a></td>'; + print "<td class=\"linenr\"><a class=\"linenr\" href=\"\">$linenr</a></td><td class=\"pre\">" . esc_html($_) . "</td>\n"; + print "</tr>\n"; + next; + } + my ($full_rev, $orig_lineno, $lineno, $group_size) = /^([0-9a-f]{40}) (\d+) (\d+)(?: (\d+))?$/; if (!exists $metainfo{$full_rev}) { @@ -3618,13 +3675,30 @@ HTML print "<td class=\"pre\">" . esc_html($data) . "</td>\n"; print "</tr>\n"; } + print "</table>\n"; print "</div>"; close $fd or print "Reading blob failed\n"; + + if ($type eq 'incremental') { + print "<script type=\"text/javascript\">\n"; + print "startBlame(\"" . href(action=>"blame_data", hash_base=>$hash_base, file_name=>$file_name) . "\", \"" . + href(-partial_query=>1) . "\");\n"; + print "</script>\n"; + } + git_footer_html(); } +sub git_blame_incremental { + git_blame_common('incremental'); +} + +sub git_blame2 { + git_blame_common('oneshot'); +} + sub git_blame { my $fd; -- 1.5.2.rc3.802.g4b4b7 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 4/5] gitweb: Selecting diffs in JavaScript 2007-05-20 20:23 ` [PATCH 4/5] gitweb: Selecting diffs in JavaScript Martin Koegler 2007-05-20 20:23 ` [PATCH 5/5] gitweb: Incremental blame Martin Koegler @ 2007-08-26 1:17 ` Petr Baudis 2007-08-26 16:17 ` Martin Koegler 1 sibling, 1 reply; 9+ messages in thread From: Petr Baudis @ 2007-08-26 1:17 UTC (permalink / raw) To: Martin Koegler; +Cc: git On Sun, May 20, 2007 at 10:23:31PM CEST, Martin Koegler wrote: > The adds support for selecting arbitrary diffs, if the client browser supports > JavaScript. > > Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at> JFYI, I've just enabled it on repo.or.cz experimentally. Please anyone tell me what you think. (Just click at almost any view in gitweb and marvel at the extra base and diff links smiling everywhere.) I'll dump my mind state here, horribly sleepy. Sorry for the incomprehensible rant. :-) One thing for certain is that I would get rid of GitAddLinks and instead have href() add the extra links there, by default display: none and javascript code making it show. Also, there are obvious UI bugs, like commit and tree entries for commits having redundant base/diff links; and Firefox doesn't expand table cells properly for the additional links. None of these bugs is easily fixable I think. But maybe it needs more general overhaul and the links added explicitly in the views, because it really makes sense to have only a single linkpair per entry and it would be good to have this always at the same place, and perhaps in a different color. Hmm. And it seems that it's getting in the way, overally. Hmm. What about having another item in the main action menu, 'diff'? Base/diff links are by default display: none but show up when you click at 'diff', in green. They will keep showing up until you click 'diff' again. When you click 'base', both the selected base link and main 'diff' link changes color to red. Oh the naivity that I've already lost about that someone might make a patch while I'm sleeping... ;-) -- Petr "Pasky" Baudis Ever try. Ever fail. No matter. // Try again. Fail again. Fail better. -- Samuel Beckett ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 4/5] gitweb: Selecting diffs in JavaScript 2007-08-26 1:17 ` [PATCH 4/5] gitweb: Selecting diffs in JavaScript Petr Baudis @ 2007-08-26 16:17 ` Martin Koegler 2007-08-26 17:21 ` Petr Baudis 0 siblings, 1 reply; 9+ messages in thread From: Martin Koegler @ 2007-08-26 16:17 UTC (permalink / raw) To: Petr Baudis; +Cc: git On Sun, Aug 26, 2007 at 03:17:43AM +0200, Petr Baudis wrote: > On Sun, May 20, 2007 at 10:23:31PM CEST, Martin Koegler wrote: > > The adds support for selecting arbitrary diffs, if the client browser supports > > JavaScript. > > > > Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at> > > JFYI, I've just enabled it on repo.or.cz experimentally. Please anyone > tell me what you think. I would also be interessed in this. > (Just click at almost any view in gitweb and marvel at the extra base > and diff links smiling everywhere.) > > I'll dump my mind state here, horribly sleepy. Sorry for the > incomprehensible rant. :-) I can't see them. http://repo.or.cz/w/git/repo.git?a=search&h=HEAD&st=grep&s=GitAddLinks reveals, that the function GitAddLinks is never called. You should add a call to GitAddLinks in fixBlameLinks or call both functions in <body onload="...">. > One thing for certain is that I would get rid of GitAddLinks and instead > have href() add the extra links there, by default display: none and > javascript code making it show. display: none will only work in CSS capable browses, but not text browsers. Also why do we want do increase the size of each generated page? > Also, there are obvious UI bugs, like > commit and tree entries for commits having redundant base/diff links; Is this really a bug? I think it makes the interface more consistent. Would it be clear for a (new) user, why some tree entries have the base/diff links and some not? > and Firefox doesn't expand table cells properly for the additional > links. None of these bugs is easily fixable I think. In which context? In eg. http://repo.or.cz/w/git.git?a=log;h=gitgui-0.8.1, there are display errors (even without the base/diff links), if the font size is zommed. In this case, the problem is that there is no real table. The links (div.log_link) are position: relative, so they don't increate the height of the enclosing div. Additionall it has an hardcoded width in pixels. > But maybe it needs more general overhaul and the links added explicitly > in the views, because it really makes sense to have only a single > linkpair per entry and it would be good to have this always at the same > place, and perhaps in a different color. Hmm. And it seems that it's > getting in the way, overally. Unless this should be come part of the official gitweb, adding each link explicitly would be a maintaince nightmare. Changing the color of the base/diff links is no problem. If somebody is interessed in this (and tells me, which colors I should use), I can adapt my patch. > What about having another item in the main action menu, 'diff'? > Base/diff links are by default display: none but show up when you click > at 'diff', in green. They will keep showing up until you click 'diff' > again. When you click 'base', both the selected base link and main > 'diff' link changes color to red. We could call GitAddLinks, if the user clicks on the diff link instead of calling GitAddLinks at page load time. I could rewrite the JavaScript for this, if you think it is so more useful. mfg Martin Kögler ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 4/5] gitweb: Selecting diffs in JavaScript 2007-08-26 16:17 ` Martin Koegler @ 2007-08-26 17:21 ` Petr Baudis 0 siblings, 0 replies; 9+ messages in thread From: Petr Baudis @ 2007-08-26 17:21 UTC (permalink / raw) To: Martin Koegler; +Cc: git On Sun, Aug 26, 2007 at 06:17:01PM CEST, Martin Koegler wrote: > http://repo.or.cz/w/git/repo.git?a=search&h=HEAD&st=grep&s=GitAddLinks > reveals, that the function GitAddLinks is never called. > You should add a call to GitAddLinks in fixBlameLinks or call > both functions in <body onload="...">. Whoops, sorry - I already had that in, but must have accidentally removed it again. > > One thing for certain is that I would get rid of GitAddLinks and instead > > have href() add the extra links there, by default display: none and > > javascript code making it show. > > display: none will only work in CSS capable browses, but not text > browsers. Also why do we want do increase the size of each generated > page? These are both good points. The only thing I'm worried about is browser performance; at least my Firefox can take noticeable few hundreds of milliseconds to insert the links to only moderately sized pages. > > Also, there are obvious UI bugs, like > > commit and tree entries for commits having redundant base/diff links; > > Is this really a bug? I think it makes the interface more consistent. > > Would it be clear for a (new) user, why some tree entries have the > base/diff links and some not? My aim is rather to have every single _entry_ to have a single base/diff linkpair. Having two linkpairs seems more confusing to me. > > But maybe it needs more general overhaul and the links added explicitly > > in the views, because it really makes sense to have only a single > > linkpair per entry and it would be good to have this always at the same > > place, and perhaps in a different color. Hmm. And it seems that it's > > getting in the way, overally. > > Unless this should be come part of the official gitweb, adding each > link explicitly would be a maintaince nightmare. This should become part of the official gitweb, what's the point otherwise. :-) > Changing the color of the base/diff links is no problem. If somebody > is interessed in this (and tells me, which colors I should use), I can > adapt my patch. > > > What about having another item in the main action menu, 'diff'? > > Base/diff links are by default display: none but show up when you click > > at 'diff', in green. They will keep showing up until you click 'diff' > > again. When you click 'base', both the selected base link and main > > 'diff' link changes color to red. > > We could call GitAddLinks, if the user clicks on the diff link instead > of calling GitAddLinks at page load time. > > I could rewrite the JavaScript for this, if you think it is so more useful. That would be awesome. -- Petr "Pasky" Baudis Ever try. Ever fail. No matter. // Try again. Fail again. Fail better. -- Samuel Beckett ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 0/5] gitweb: Support for arbitrary diffs @ 2007-09-02 14:46 Martin Koegler 2007-09-02 14:46 ` [PATCH 1/5] gitweb: Support comparing blobs with different names Martin Koegler 0 siblings, 1 reply; 9+ messages in thread From: Martin Koegler @ 2007-09-02 14:46 UTC (permalink / raw) To: Petr Baudis; +Cc: git, Martin Koegler Resend of the complete patch serie (again next). Patch 1-3 are unchanged. Patch 4 now only generates the links, if they are enabled. The header contains a new link to show/hide the links. The state is remembered via a cookie across pages. Patch 5 is the foundation for showing the base/diff links in an other color. mfg Martin Kögler PS: I develop the patches via StGit. If you think that I should publish them in a different way, please tell me. ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/5] gitweb: Support comparing blobs with different names 2007-09-02 14:46 [PATCH 0/5] gitweb: Support for arbitrary diffs Martin Koegler @ 2007-09-02 14:46 ` Martin Koegler 2007-09-02 14:46 ` [PATCH 2/5] gitweb: support filename prefix in git_patchset_body/git_difftree_body Martin Koegler 0 siblings, 1 reply; 9+ messages in thread From: Martin Koegler @ 2007-09-02 14:46 UTC (permalink / raw) To: Petr Baudis; +Cc: git, Martin Koegler Currently, blobdiff can only compare blobs with different file names, if no hb/hpb parameters are present. This patch adds support for comparing two blobs specified by any combination of hb/f/h and hpb/fp/hp. Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at> --- gitweb/gitweb.perl | 148 +++++++++++++++++++--------------------------------- 1 files changed, 53 insertions(+), 95 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index b2bae1b..05bfb26 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -4645,109 +4645,66 @@ sub git_blobdiff { my $fd; my @difftree; my %diffinfo; - my $expires; - - # preparing $fd and %diffinfo for git_patchset_body - # new style URI - if (defined $hash_base && defined $hash_parent_base) { - if (defined $file_name) { - # read raw output - open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, - $hash_parent_base, $hash_base, - "--", (defined $file_parent ? $file_parent : ()), $file_name - or die_error(undef, "Open git-diff-tree failed"); - @difftree = map { chomp; $_ } <$fd>; - close $fd - or die_error(undef, "Reading git-diff-tree failed"); - @difftree - or die_error('404 Not Found', "Blob diff not found"); - - } elsif (defined $hash && - $hash =~ /[0-9a-fA-F]{40}/) { - # try to find filename from $hash - - # read filtered raw output - open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, - $hash_parent_base, $hash_base, "--" - or die_error(undef, "Open git-diff-tree failed"); - @difftree = - # ':100644 100644 03b21826... 3b93d5e7... M ls-files.c' - # $hash == to_id - grep { /^:[0-7]{6} [0-7]{6} [0-9a-fA-F]{40} $hash/ } - map { chomp; $_ } <$fd>; - close $fd - or die_error(undef, "Reading git-diff-tree failed"); - @difftree - or die_error('404 Not Found', "Blob diff not found"); + my $expires = '+1d'; + my ($from, $to); - } else { - die_error('404 Not Found', "Missing one of the blob diff parameters"); - } - - if (@difftree > 1) { - die_error('404 Not Found', "Ambiguous blob diff specification"); - } + $file_parent ||= $file_name; - %diffinfo = parse_difftree_raw_line($difftree[0]); - $file_parent ||= $diffinfo{'from_file'} || $file_name || $diffinfo{'file'}; - $file_name ||= $diffinfo{'to_file'} || $diffinfo{'file'}; - - $hash_parent ||= $diffinfo{'from_id'}; - $hash ||= $diffinfo{'to_id'}; - - # non-textual hash id's can be cached - if ($hash_base =~ m/^[0-9a-fA-F]{40}$/ && - $hash_parent_base =~ m/^[0-9a-fA-F]{40}$/) { - $expires = '+1d'; - } + # non-textual hash id's can be cached + if (defined $hash && $hash !~ m/^[0-9a-fA-F]{40}$/) { + $expires = undef; + } elsif (defined $hash_parent && $hash_parent !~ m/^[0-9a-fA-F]{40}$/) { + $expires = undef; + } elsif (defined $hash_base && $hash_base !~ m/^[0-9a-fA-F]{40}$/) { + $expires = undef; + } elsif (defined $hash_parent_base && $hash_parent_base !~ m/^[0-9a-fA-F]{40}$/) { + $expires = undef; + } + + # if hash parameter is missing, read it from the commit. + if (defined $hash_base && defined $file_name && !defined $hash) { + $hash = git_get_hash_by_path($hash_base, $file_name); + } - # open patch output - open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, - '-p', ($format eq 'html' ? "--full-index" : ()), - $hash_parent_base, $hash_base, - "--", (defined $file_parent ? $file_parent : ()), $file_name - or die_error(undef, "Open git-diff-tree failed"); + if (defined $hash_parent_base && defined $file_parent && !defined $hash_parent) { + $hash_parent = git_get_hash_by_path($hash_parent_base, $file_parent); + } + + if (!defined $hash || ! defined $hash_parent) { + die_error('404 Not Found', "Missing one of the blob diff parameters"); } - # old/legacy style URI - if (!%diffinfo && # if new style URI failed - defined $hash && defined $hash_parent) { - # fake git-diff-tree raw output - $diffinfo{'from_mode'} = $diffinfo{'to_mode'} = "blob"; - $diffinfo{'from_id'} = $hash_parent; - $diffinfo{'to_id'} = $hash; - if (defined $file_name) { - if (defined $file_parent) { - $diffinfo{'status'} = '2'; - $diffinfo{'from_file'} = $file_parent; - $diffinfo{'to_file'} = $file_name; - } else { # assume not renamed - $diffinfo{'status'} = '1'; - $diffinfo{'from_file'} = $file_name; - $diffinfo{'to_file'} = $file_name; - } - } else { # no filename given - $diffinfo{'status'} = '2'; - $diffinfo{'from_file'} = $hash_parent; - $diffinfo{'to_file'} = $hash; - } + if (defined $hash_base && defined $file_name) { + $to = $hash_base . ':' . $file_name; + } else { + $to = $hash; + } - # non-textual hash id's can be cached - if ($hash =~ m/^[0-9a-fA-F]{40}$/ && - $hash_parent =~ m/^[0-9a-fA-F]{40}$/) { - $expires = '+1d'; - } + if (defined $hash_parent_base && defined $file_parent) { + $from = $hash_parent_base . ':' . $file_parent; + } else { + $from = $hash_parent; + } - # open patch output - open $fd, "-|", git_cmd(), "diff", @diff_opts, - '-p', ($format eq 'html' ? "--full-index" : ()), - $hash_parent, $hash, "--" - or die_error(undef, "Open git-diff failed"); - } else { - die_error('404 Not Found', "Missing one of the blob diff parameters") - unless %diffinfo; + # fake git-diff-tree raw output + $diffinfo{'from_mode'} = $diffinfo{'to_mode'} = "blob"; + $diffinfo{'from_id'} = $hash_parent; + $diffinfo{'to_id'} = $hash; + if (defined $file_name) { + $diffinfo{'status'} = '2'; + $diffinfo{'from_file'} = $file_parent; + $diffinfo{'to_file'} = $file_name; + } else { # no filename given + $diffinfo{'status'} = '2'; + $diffinfo{'from_file'} = $hash_parent; + $diffinfo{'to_file'} = $hash; } + # open patch output + open $fd, "-|", git_cmd(), "diff", @diff_opts, '-p', "--full-index", + ($format eq 'html' ? "--raw" : ()), $from, $to, "--" + or die_error(undef, "Open git-diff failed"); + # header if ($format eq 'html') { my $formats_nav = @@ -4771,11 +4728,12 @@ sub git_blobdiff { } } elsif ($format eq 'plain') { + my $patch_file_name = $file_name || $hash; print $cgi->header( -type => 'text/plain', -charset => 'utf-8', -expires => $expires, - -content_disposition => 'inline; filename="' . "$file_name" . '.patch"'); + -content_disposition => 'inline; filename="' . "$patch_file_name" . '.patch"'); print "X-Git-Url: " . $cgi->self_url() . "\n\n"; -- 1.5.3.rc7.849.g2f5f ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/5] gitweb: support filename prefix in git_patchset_body/git_difftree_body 2007-09-02 14:46 ` [PATCH 1/5] gitweb: Support comparing blobs with different names Martin Koegler @ 2007-09-02 14:46 ` Martin Koegler 0 siblings, 0 replies; 9+ messages in thread From: Martin Koegler @ 2007-09-02 14:46 UTC (permalink / raw) To: Petr Baudis; +Cc: git, Martin Koegler git_treediff supports comparing subdirectories. As the output of git-difftree is missing the path to the compared directories, the links in the output would be wrong. The patch adds two new parameters to add the missing path prefix. Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at> --- gitweb/gitweb.perl | 88 +++++++++++++++++++++++++++++---------------------- 1 files changed, 50 insertions(+), 38 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 05bfb26..5f67d73 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1173,10 +1173,10 @@ sub format_diff_from_to_header { $cgi->a({-href=>href(action=>"blobdiff", hash_parent=>$diffinfo->{'from_id'}[$i], hash_parent_base=>$parents[$i], - file_parent=>$from->{'file'}[$i], + file_parent=>$diffinfo->{'from_prefix'}.$from->{'file'}[$i], hash=>$diffinfo->{'to_id'}, hash_base=>$hash, - file_name=>$to->{'file'}), + file_name=>$diffinfo->{'to_prefix'}.$to->{'file'}), -class=>"path", -title=>"diff" . ($i+1)}, $i+1) . @@ -1219,7 +1219,7 @@ sub format_diff_cc_simplified { $result .= $cgi->a({-href => href(action=>"blob", hash_base=>$hash, hash=>$diffinfo->{'to_id'}, - file_name=>$diffinfo->{'to_file'}), + file_name=>$diffinfo->{'to_prefix'}.$diffinfo->{'to_file'}), -class => "path"}, esc_path($diffinfo->{'to_file'})); } else { @@ -2027,7 +2027,7 @@ sub parse_from_to_diffinfo { $from->{'href'}[$i] = href(action=>"blob", hash_base=>$parents[$i], hash=>$diffinfo->{'from_id'}[$i], - file_name=>$from->{'file'}[$i]); + file_name=>$diffinfo->{'from_prefix'}.$from->{'file'}[$i]); } else { $from->{'href'}[$i] = undef; } @@ -2037,7 +2037,7 @@ sub parse_from_to_diffinfo { if ($diffinfo->{'status'} ne "A") { # not new (added) file $from->{'href'} = href(action=>"blob", hash_base=>$hash_parent, hash=>$diffinfo->{'from_id'}, - file_name=>$from->{'file'}); + file_name=>$diffinfo->{'from_prefix'}.$from->{'file'}); } else { delete $from->{'href'}; } @@ -2047,7 +2047,7 @@ sub parse_from_to_diffinfo { if (!is_deleted($diffinfo)) { # file exists in result $to->{'href'} = href(action=>"blob", hash_base=>$hash, hash=>$diffinfo->{'to_id'}, - file_name=>$to->{'file'}); + file_name=>$diffinfo->{'to_prefix'}.$to->{'file'}); } else { delete $to->{'href'}; } @@ -2795,9 +2795,13 @@ sub is_deleted { } sub git_difftree_body { - my ($difftree, $hash, @parents) = @_; + my ($difftree, $from_prefix, $to_prefix, $hash, @parents) = @_; my ($parent) = $parents[0]; my ($have_blame) = gitweb_check_feature('blame'); + + $from_prefix = !defined $from_prefix ? '' : $from_prefix.'/'; + $to_prefix = !defined $to_prefix ? '' : $to_prefix . '/'; + print "<div class=\"list_head\">\n"; if ($#{$difftree} > 10) { print(($#{$difftree} + 1) . " files changed:\n"); @@ -2854,7 +2858,7 @@ sub git_difftree_body { # file exists in the result (child) commit print "<td>" . $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - file_name=>$diff->{'to_file'}, + file_name=>$to_prefix.$diff->{'to_file'}, hash_base=>$hash), -class => "list"}, esc_path($diff->{'to_file'})) . "</td>\n"; @@ -2891,7 +2895,7 @@ sub git_difftree_body { $cgi->a({-href => href(action=>"blob", hash_base=>$hash, hash=>$from_hash, - file_name=>$from_path)}, + file_name=>$from_prefix.$from_path)}, "blob" . ($i+1)) . " | </td>\n"; } else { @@ -2905,8 +2909,8 @@ sub git_difftree_body { hash_parent=>$from_hash, hash_base=>$hash, hash_parent_base=>$hash_parent, - file_name=>$diff->{'to_file'}, - file_parent=>$from_path)}, + file_name=>$to_prefix.$diff->{'to_file'}, + file_parent=>$from_prefix.$from_path)}, "diff" . ($i+1)) . " | </td>\n"; } @@ -2916,14 +2920,14 @@ sub git_difftree_body { if ($not_deleted) { print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - file_name=>$diff->{'to_file'}, + file_name=>$to_prefix.$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=>$to_prefix.$diff->{'to_file'}, hash_base=>$hash)}, "history"); } @@ -2957,7 +2961,7 @@ sub git_difftree_body { $mode_chng .= "]</span>"; print "<td>"; print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - hash_base=>$hash, file_name=>$diff->{'file'}), + hash_base=>$hash, file_name=>$to_prefix.$diff->{'file'}), -class => "list"}, esc_path($diff->{'file'})); print "</td>\n"; print "<td>$mode_chng</td>\n"; @@ -2969,7 +2973,7 @@ sub git_difftree_body { print " | "; } print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - hash_base=>$hash, file_name=>$diff->{'file'})}, + hash_base=>$hash, file_name=>$to_prefix.$diff->{'file'})}, "blob"); print "</td>\n"; @@ -2977,7 +2981,7 @@ sub git_difftree_body { my $mode_chng = "<span class=\"file_status deleted\">[deleted $from_file_type]</span>"; print "<td>"; print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'from_id'}, - hash_base=>$parent, file_name=>$diff->{'file'}), + hash_base=>$parent, file_name=>$from_prefix.$diff->{'file'}), -class => "list"}, esc_path($diff->{'file'})); print "</td>\n"; print "<td>$mode_chng</td>\n"; @@ -2989,15 +2993,15 @@ sub git_difftree_body { print " | "; } print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'from_id'}, - hash_base=>$parent, file_name=>$diff->{'file'})}, + hash_base=>$parent, file_name=>$from_prefix.$diff->{'file'})}, "blob") . " | "; if ($have_blame) { print $cgi->a({-href => href(action=>"blame", hash_base=>$parent, - file_name=>$diff->{'file'})}, + file_name=>$from_prefix.$diff->{'file'})}, "blame") . " | "; } print $cgi->a({-href => href(action=>"history", hash_base=>$parent, - file_name=>$diff->{'file'})}, + file_name=>$from_prefix.$diff->{'file'})}, "history"); print "</td>\n"; @@ -3019,7 +3023,7 @@ sub git_difftree_body { } print "<td>"; print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - hash_base=>$hash, file_name=>$diff->{'file'}), + hash_base=>$hash, file_name=>$to_prefix.$diff->{'file'}), -class => "list"}, esc_path($diff->{'file'})); print "</td>\n"; print "<td>$mode_chnge</td>\n"; @@ -3034,20 +3038,21 @@ sub git_difftree_body { print $cgi->a({-href => href(action=>"blobdiff", hash=>$diff->{'to_id'}, hash_parent=>$diff->{'from_id'}, hash_base=>$hash, hash_parent_base=>$parent, - file_name=>$diff->{'file'})}, + file_name=>$to_prefix.$diff->{'file'}, + file_parent=>$from_prefix.$diff->{'file'})}, "diff") . " | "; } print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - hash_base=>$hash, file_name=>$diff->{'file'})}, + hash_base=>$hash, file_name=>$to_prefix.$diff->{'file'})}, "blob") . " | "; if ($have_blame) { print $cgi->a({-href => href(action=>"blame", hash_base=>$hash, - file_name=>$diff->{'file'})}, + file_name=>$to_prefix.$diff->{'file'})}, "blame") . " | "; } print $cgi->a({-href => href(action=>"history", hash_base=>$hash, - file_name=>$diff->{'file'})}, + file_name=>$to_prefix.$diff->{'file'})}, "history"); print "</td>\n"; @@ -3061,11 +3066,11 @@ sub git_difftree_body { } print "<td>" . $cgi->a({-href => href(action=>"blob", hash_base=>$hash, - hash=>$diff->{'to_id'}, file_name=>$diff->{'to_file'}), + hash=>$diff->{'to_id'}, file_name=>$to_prefix.$diff->{'to_file'}), -class => "list"}, esc_path($diff->{'to_file'})) . "</td>\n" . "<td><span class=\"file_status $nstatus\">[$nstatus from " . $cgi->a({-href => href(action=>"blob", hash_base=>$parent, - hash=>$diff->{'from_id'}, file_name=>$diff->{'from_file'}), + hash=>$diff->{'from_id'}, file_name=>$from_prefix.$diff->{'from_file'}), -class => "list"}, esc_path($diff->{'from_file'})) . " with " . (int $diff->{'similarity'}) . "% similarity$mode_chng]</span></td>\n" . "<td class=\"link\">"; @@ -3079,20 +3084,20 @@ sub git_difftree_body { print $cgi->a({-href => href(action=>"blobdiff", 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=>$to_prefix.$diff->{'to_file'}, file_parent=>$from_prefix.$diff->{'from_file'})}, "diff") . " | "; } print $cgi->a({-href => href(action=>"blob", hash=>$diff->{'to_id'}, - hash_base=>$parent, file_name=>$diff->{'to_file'})}, + hash_base=>$parent, file_name=>$to_prefix.$diff->{'to_file'})}, "blob") . " | "; if ($have_blame) { print $cgi->a({-href => href(action=>"blame", hash_base=>$hash, - file_name=>$diff->{'to_file'})}, + file_name=>$to_prefix.$diff->{'to_file'})}, "blame") . " | "; } print $cgi->a({-href => href(action=>"history", hash_base=>$hash, - file_name=>$diff->{'to_file'})}, + file_name=>$to_prefix.$diff->{'to_file'})}, "history"); print "</td>\n"; @@ -3104,7 +3109,7 @@ sub git_difftree_body { } sub git_patchset_body { - my ($fd, $difftree, $hash, @hash_parents) = @_; + my ($fd, $difftree, $from_prefix, $to_prefix, $hash, @hash_parents) = @_; my ($hash_parent) = $hash_parents[0]; my $patch_idx = 0; @@ -3113,6 +3118,9 @@ sub git_patchset_body { my $diffinfo; my (%from, %to); + $from_prefix = !defined $from_prefix ? '' : $from_prefix.'/'; + $to_prefix = !defined $to_prefix ? '' : $to_prefix . '/'; + print "<div class=\"patchset\">\n"; # skip to first patch @@ -3160,6 +3168,8 @@ sub git_patchset_body { $diffinfo->{'to_id'} eq $to_id) { # this is continuation of a split patch print "<div class=\"patch cont\">\n"; + $diffinfo->{'from_prefix'} = $from_prefix; + $diffinfo->{'to_prefix'} = $to_prefix; } else { # advance raw git-diff output if needed $patch_idx++ if defined $diffinfo; @@ -3191,6 +3201,8 @@ sub git_patchset_body { } } until (!defined $to_name || $to_name eq $diffinfo->{'to_file'} || $patch_idx > $#$difftree); + $diffinfo->{'from_prefix'} = $from_prefix; + $diffinfo->{'to_prefix'} = $to_prefix; # modifies %from, %to hashes parse_from_to_diffinfo($diffinfo, \%from, \%to, @hash_parents); if ($diffinfo->{'nparents'}) { @@ -3205,7 +3217,7 @@ sub git_patchset_body { $from{'href'}[$i] = href(action=>"blob", hash_base=>$hash_parents[$i], hash=>$diffinfo->{'from_id'}[$i], - file_name=>$from{'file'}[$i]); + file_name=>$from_prefix.$from{'file'}[$i]); } else { $from{'href'}[$i] = undef; } @@ -3215,7 +3227,7 @@ sub git_patchset_body { if ($diffinfo->{'status'} ne "A") { # not new (added) file $from{'href'} = href(action=>"blob", hash_base=>$hash_parent, hash=>$diffinfo->{'from_id'}, - file_name=>$from{'file'}); + file_name=>$from_prefix.$from{'file'}); } else { delete $from{'href'}; } @@ -3225,7 +3237,7 @@ sub git_patchset_body { if (!is_deleted($diffinfo)) { # file exists in result $to{'href'} = href(action=>"blob", hash_base=>$hash, hash=>$diffinfo->{'to_id'}, - file_name=>$to{'file'}); + file_name=>$to_prefix.$to{'file'}); } else { delete $to{'href'}; } @@ -4587,7 +4599,7 @@ sub git_commit { git_print_log($co{'comment'}); print "</div>\n"; - git_difftree_body(\@difftree, $hash, @$parents); + git_difftree_body(\@difftree, undef, undef, $hash, @$parents); git_footer_html(); } @@ -4745,7 +4757,7 @@ sub git_blobdiff { if ($format eq 'html') { print "<div class=\"page_body\">\n"; - git_patchset_body($fd, [ \%diffinfo ], $hash_base, $hash_parent_base); + git_patchset_body($fd, [ \%diffinfo ], undef, undef, $hash_base, $hash_parent_base); close $fd; print "</div>\n"; # class="page_body" @@ -4928,11 +4940,11 @@ TEXT if ($format eq 'html') { my $use_parents = !defined $hash_parent || $hash_parent eq '-c' || $hash_parent eq '--cc'; - git_difftree_body(\@difftree, $hash, + git_difftree_body(\@difftree, undef, undef, $hash, $use_parents ? @{$co{'parents'}} : $hash_parent); print "<br/>\n"; - git_patchset_body($fd, \@difftree, $hash, + git_patchset_body($fd, \@difftree, undef, undef, $hash, $use_parents ? @{$co{'parents'}} : $hash_parent); close $fd; print "</div>\n"; # class="page_body" -- 1.5.3.rc7.849.g2f5f ^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2007-09-02 14:47 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-05-20 20:23 [PATCH 1/5] gitweb: Support comparing blobs with different names Martin Koegler 2007-05-20 20:23 ` [PATCH 2/5] gitweb: support filename prefix in git_patchset_body/git_difftree_body Martin Koegler 2007-05-20 20:23 ` [PATCH 3/5] gitweb: Add treediff view Martin Koegler 2007-05-20 20:23 ` [PATCH 4/5] gitweb: Selecting diffs in JavaScript Martin Koegler 2007-05-20 20:23 ` [PATCH 5/5] gitweb: Incremental blame Martin Koegler 2007-08-26 1:17 ` [PATCH 4/5] gitweb: Selecting diffs in JavaScript Petr Baudis 2007-08-26 16:17 ` Martin Koegler 2007-08-26 17:21 ` Petr Baudis -- strict thread matches above, loose matches on Subject: below -- 2007-09-02 14:46 [PATCH 0/5] gitweb: Support for arbitrary diffs Martin Koegler 2007-09-02 14:46 ` [PATCH 1/5] gitweb: Support comparing blobs with different names Martin Koegler 2007-09-02 14:46 ` [PATCH 2/5] gitweb: support filename prefix in git_patchset_body/git_difftree_body Martin Koegler
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).