X-Git-Url: https://git.ladys.computer/Gitweb/blobdiff_plain/8863cf4b7d0138f789fb2724cd7b28527fe8bb6af0ce2e8e18e22ac8fa16321e..3425bbdec70034ac0d88f89e3c38b4bd6cbcf9450123257ecc7476ffd999ec29:/gitweb.cgi?ds=sidebyside diff --git a/gitweb.cgi b/gitweb.cgi index 35cce31..3dd7eb1 100755 --- a/gitweb.cgi +++ b/gitweb.cgi @@ -2,8 +2,8 @@ # gitweb - simple web interface to track changes in git repositories # -# (C) 2005, Kay Sievers -# (C) 2005, Christian Gierke +# (C) 2005-2006, Kay Sievers +# (C) 2005, Christian Gierke # # This program is licensed under the GPLv2 @@ -17,7 +17,7 @@ use Fcntl ':mode'; binmode STDOUT, ':utf8'; my $cgi = new CGI; -my $version = "262"; +my $version = "267"; my $my_url = $cgi->url(); my $my_uri = $cgi->url(-absolute => 1); my $rss_link = ""; @@ -203,6 +203,9 @@ if (!defined $action || $action eq "summary") { } elsif ($action eq "tag") { git_tag(); exit; +} elsif ($action eq "blame") { + git_blame(); + exit; } else { undef $action; die_error(undef, "Unknown action."); @@ -253,7 +256,7 @@ sub git_header_html { - + @@ -404,12 +407,13 @@ sub git_read_head { if (open my $fd, "-|", "$gitbin/git-rev-parse", "--verify", "HEAD") { my $head = <$fd>; close $fd; - chomp $head; - if ($head =~ m/^[0-9a-fA-F]{40}$/) { - $retval = $head; + if (defined $head && $head =~ /^([0-9a-fA-F]{40})$/) { + $retval = $1; } } - $ENV{'GIT_DIR'} = $oENV; + if (defined $oENV) { + $ENV{'GIT_DIR'} = $oENV; + } return $retval; } @@ -786,7 +790,7 @@ sub get_file_owner { } my $owner = $gcos; $owner =~ s/[,;].*$//; - return $owner; + return decode("utf8", $owner, Encode::FB_DEFAULT); } sub git_read_projects { @@ -822,7 +826,7 @@ sub git_read_projects { if (-e "$projectroot/$path/HEAD") { my $pr = { path => $path, - owner => $owner, + owner => decode("utf8", $owner, Encode::FB_DEFAULT), }; push @list, $pr } @@ -833,6 +837,25 @@ sub git_read_projects { return @list; } +sub git_get_project_config { + my $key = shift; + + return unless ($key); + $key =~ s/^gitweb\.//; + return if ($key =~ m/\W/); + + my $val = qx(git-repo-config --get gitweb.$key); + return ($val); +} + +sub git_get_project_config_bool { + my $val = git_get_project_config (@_); + if ($val and $val =~ m/true|yes|on/) { + return (1); + } + return; # implicit false +} + sub git_project_list { my @list = git_read_projects(); my @projects; @@ -1024,7 +1047,7 @@ sub git_summary { $pr = unescape($pr); $ow = unescape($ow); if ($pr eq $project) { - $owner = $ow; + $owner = decode("utf8", $ow, Encode::FB_DEFAULT); last; } } @@ -1227,6 +1250,108 @@ sub git_tag { git_footer_html(); } +sub git_blame { + my $fd; + die_error('403 Permission denied', "Permission denied.") if (!git_get_project_config_bool ('blame')); + die_error('404 Not Found', "What file will it be, master?") if (!$file_name); + $hash_base ||= git_read_head($project); + die_error(undef, "Reading commit failed.") unless ($hash_base); + my %co = git_read_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 lookup file."); + } + open ($fd, "-|", "$gitbin/git-annotate", '-l', '-t', '-r', $file_name, $hash_base) + or die_error(undef, "Open failed."); + git_header_html(); + print "
\n" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base")}, "commit") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash_base")}, "tree") . "
\n"; + print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name")}, "blob") . + " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;f=$file_name")}, "head") . "
\n"; + print "
\n". + "
" . + $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . + "
\n"; + print "
" . esc_html($file_name) . "
\n"; + print "
\n"; + print < + + Commit + Age + Author + Line + Data + +HTML + my @line_class = (qw(light dark)); + my $line_class_len = scalar (@line_class); + my $line_class_num = $#line_class; + while (my $line = <$fd>) { + my $long_rev; + my $short_rev; + my $author; + my $time; + my $lineno; + my $data; + my $age; + my $age_str; + my $age_style; + + chomp $line; + $line_class_num = ($line_class_num + 1) % $line_class_len; + + if ($line =~ m/^([0-9a-fA-F]{40})\t\(\s*([^\t]+)\t(\d+) \+\d\d\d\d\t(\d+)\)(.*)$/) { + $long_rev = $1; + $author = $2; + $time = $3; + $lineno = $4; + $data = $5; + } else { + print qq( Unable to parse: $line\n); + next; + } + $short_rev = substr ($long_rev, 0, 8); + $age = time () - $time; + $age_str = age_string ($age); + $age_str =~ s/ / /g; + $age_style = 'font-style: italic;'; + $age_style .= ' color: #009900; background: transparent;' if ($age < 60*60*24*2); + $age_style .= ' font-weight: bold;' if ($age < 60*60*2); + $author = esc_html ($author); + $author =~ s/ / /g; + # escape tabs + while ((my $pos = index($data, "\t")) != -1) { + if (my $count = (8 - ($pos % 8))) { + my $spaces = ' ' x $count; + $data =~ s/\t/$spaces/; + } + } + $data = esc_html ($data); + $data =~ s/ / /g; + + print < + $short_rev.. + $age_str + $author + $lineno + $data + +HTML + } # while (my $line = <$fd>) + print "\n\n"; + close $fd or print "Reading blob failed.\n"; + print "
"; + git_footer_html(); +} + sub git_tags { my $head = git_read_head($project); git_header_html(); @@ -1363,6 +1488,7 @@ sub git_blob { my $base = $hash_base || git_read_head($project); $hash = git_get_hash_by_path($base, $file_name, "blob") || die_error(undef, "Error lookup file."); } + my $have_blame = git_get_project_config_bool ('blame'); open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or die_error(undef, "Open failed."); git_header_html(); if (defined $hash_base && (my %co = git_read_commit($hash_base))) { @@ -1374,6 +1500,9 @@ sub git_blob { " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") . " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash_base")}, "tree") . "
\n"; if (defined $file_name) { + if ($have_blame) { + print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$hash;hb=$hash_base;f=$file_name")}, "blame") . " | "; + } print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash;f=$file_name")}, "plain") . " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;hb=HEAD;f=$file_name")}, "head") . "
\n"; } else { @@ -1495,6 +1624,7 @@ sub git_tree { "\n" . "" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$t_hash$base_key;f=$base$t_name")}, "blob") . +# " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$t_hash$base_key;f=$base$t_name")}, "blame") . " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$hash_base;f=$base$t_name")}, "history") . "\n"; } elsif ($t_type eq "tree") { @@ -2122,7 +2252,7 @@ sub git_history { "\n"; print "
/" . esc_html($file_name) . "
\n"; - open my $fd, "-|", "$gitbin/git-rev-list $hash | $gitbin/git-diff-tree -r --stdin \'$file_name\'"; + open my $fd, "-|", "$gitbin/git-rev-list $hash | $gitbin/git-diff-tree -r --stdin -- \'$file_name\'"; my $commit; print "\n"; my $alternate = 0;