From 4280cde95fa4e3fb012eb6d0c239a7777baaf60c Mon Sep 17 00:00:00 2001 From: Martin Koegler Date: Sun, 22 Apr 2007 22:49:25 -0700 Subject: gitweb: Show "no difference" message for empty diff Currently, gitweb shows only header and footer, if no differences are found. This patch adds a "No differences found" message for the html output. Signed-off-by: Martin Koegler Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 5e40292404..2b023bd98a 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -387,6 +387,10 @@ div.diff.incomplete { color: #cccccc; } +div.diff.nodifferences { + font-weight: bold; + color: #600000; +} div.index_include { border: solid #d9d8d1; -- cgit v1.3 From ed224deac9436215f8c0b098baa0aecfcff1c293 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 7 May 2007 01:10:04 +0200 Subject: gitweb: Add combined diff support to git_difftree_body You have to pass all parents as final parameters of git_difftree_body subroutine; the number of parents of a diff must be equal to the number derived from parsing git-diff-tree output, raw combined diff for git_difftree_body to display combined diff correctly (but it is not checked). Currently the possibility of displaying diffree of combined diff is not used in gitweb code; git_difftree_body is always caled for ordinary diff, and with only one parent. Description of output for combined diff: ---------------------------------------- The difftree table for combined diff starts with a cell with pathname of changed blob (changed file), which if possible is hidden link (class="list") to the 'blob' view of final version (if it exists), like for difftree for ordinary diff. If file was deleted in the final commit then filename is not hyperlinked. There is no cell with single file status (new, deleted, mode change, rename), as for combined diff as there is no single status: different parents might have different status. If git_difftree_body was called from git_commitdiff (for 'commitdiff' action) there is inner link to anchor to appropriate fragment (patch) in patchset body; the "patch" link does not replace "diff" link like for ordinary diff. Each of "diff" links is in separate cell, contrary to output for ordinary diff in which all links are (at least for now) in a single cell. For each parent, if file was not present we leave cell empty. If file was deleted in the result, we provide link to 'blob' view. Otherwise we provide link to 'commitdiff' view, even if patch (diff) consist only of extended diff header, and contents is not changed (pure rename, pure mode change). The only difference is that link to "blobdiff" view with no contents change is with 'nochange' class. At last, there is provided link to current version of file as "blob" link, if the file was not deleted in the result, and lik to history of a file, if there exists one. (The link to file history might be confused, at least for now, by renames.) Note that git-diff-tree raw output dor combined diff does not provide filename before change for renames and copies; we use git_get_path_by_hash to get "src" filename for renames (this means additional call to git-ls-tree for a _whole_ tree). Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 17 ++++++++ gitweb/gitweb.perl | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 136 insertions(+), 2 deletions(-) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 2b023bd98a..e795b70b2b 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -181,6 +181,23 @@ table.diff_tree { font-family: monospace; } +table.combined.diff_tree td { + padding-right: 24px; +} + +table.combined.diff_tree td.link { + padding: 0px 2px; +} + +table.combined.diff_tree td.nochange a { + color: #6666ff; +} + +table.combined.diff_tree td.nochange a:hover, +table.combined.diff_tree td.nochange a:visited { + color: #d06666; +} + table.blame { border-collapse: collapse; } diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index dfba399d8e..c6a2fef823 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1015,6 +1015,30 @@ sub git_get_hash_by_path { return $3; } +# get path of entry with given hash at given tree-ish (ref) +# used to get 'from' filename for combined diff (merge commit) for renames +sub git_get_path_by_hash { + my $base = shift || return; + my $hash = shift || return; + + local $/ = "\0"; + + open my $fd, "-|", git_cmd(), "ls-tree", '-r', '-t', '-z', $base + or return undef; + while (my $line = <$fd>) { + chomp $line; + + #'040000 tree 595596a6a9117ddba9fe379b6b012b558bac8423 gitweb' + #'100644 blob e02e90f0429be0d2a69b76571101f20b8f75530f gitweb/README' + if ($line =~ m/(?:[0-9]+) (?:.+) $hash\t(.+)$/) { + close $fd; + return $1; + } + } + close $fd; + return undef; +} + ## ...................................................................... ## git utility functions, directly accessing git repository @@ -2210,7 +2234,8 @@ sub git_print_tree_entry { ## functions printing large fragments of HTML sub git_difftree_body { - my ($difftree, $hash, $parent) = @_; + my ($difftree, $hash, @parents) = @_; + my ($parent) = $parents[0]; my ($have_blame) = gitweb_check_feature('blame'); print "
\n"; if ($#{$difftree} > 10) { @@ -2218,7 +2243,9 @@ sub git_difftree_body { } print "
\n"; - print "\n"; + print "
1 ? "combined " : "") . + "diff_tree\">\n"; my $alternate = 1; my $patchno = 0; foreach my $line (@{$difftree}) { @@ -2231,6 +2258,96 @@ sub git_difftree_body { } $alternate ^= 1; + if (exists $diff{'nparents'}) { # combined diff + + if ($diff{'to_id'} ne ('0' x 40)) { + # file exists in the result (child) commit + print "\n"; + } else { + print "\n"; + } + + if ($action eq 'commitdiff') { + # link to patch + $patchno++; + print "\n"; + } + + my $has_history = 0; + my $not_deleted = 0; + for (my $i = 0; $i < $diff{'nparents'}; $i++) { + my $hash_parent = $parents[$i]; + my $from_hash = $diff{'from_id'}[$i]; + my $from_path = undef; + my $status = $diff{'status'}[$i]; + + $has_history ||= ($status ne 'A'); + $not_deleted ||= ($status ne 'D'); + + if ($status eq 'R' || $status eq 'C') { + $from_path = git_get_path_by_hash($hash_parent, $from_hash); + } + + if ($status eq 'A') { + print "\n"; + } elsif ($status eq 'D') { + print "\n"; + } else { + if ($diff{'to_id'} eq $from_hash) { + print "\n"; + } + } + + print "\n"; + + print "\n"; + next; # instead of 'else' clause, to avoid extra indent + } + # else ordinary diff + 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)) { -- cgit v1.3 From 63fcbe00a66d7cb7d8bce9a36120a19a809a33b8 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Wed, 9 May 2007 03:41:50 +0200 Subject: gitweb: Do not use absolute font sizes Avoid specifying font sizes in pixels, since that is just pure evil. Pointed out by Chris Riddoch. Note that this is pretty much just a proposal; I didn't test if everything fits perfectly right, but things seem to be pretty much okay. repo.or.cz uses it now as a test drive - if you find any visual quirks, please point them out, with a patch if possible since I'm total CSS noob and debugging CSS is an extremely painful experience for me. Note that this patch actually does change visual look of gitweb in Firefox with my resolution and default settings - everything is bigger and I can't explain the joy of actually seeing gitweb text that is in _readable_ size; also, my horizontal screen real estate feels better used now. But judging from the look of most modern webpages on the 'net, most people prefer reading the web with strained eyes and/or a magnifying glass (I wonder what species of scientists should look into this mystifying phenomenon) - so, please tell us what you think. Maybe we might want to get rid of absolute sizes other than font sizes in the CSS file too in the long term. Signed-off-by: Petr Baudis Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index e795b70b2b..b57c8beccb 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -1,6 +1,5 @@ body { font-family: sans-serif; - font-size: 12px; border: solid #d9d8d1; border-width: 1px; margin: 10px; @@ -31,7 +30,7 @@ img.logo { div.page_header { height: 25px; padding: 8px; - font-size: 18px; + font-size: 150%; font-weight: bold; background-color: #d9d8d1; } @@ -113,7 +112,7 @@ span.signoff { div.log_link { padding: 0px 8px; - font-size: 10px; + font-size: 70%; font-family: sans-serif; font-style: normal; position: relative; @@ -204,13 +203,13 @@ table.blame { table.blame td { padding: 0px 5px; - font-size: 12px; + font-size: 100%; vertical-align: top; } th { padding: 2px 5px; - font-size: 12px; + font-size: 100%; text-align: left; } @@ -232,14 +231,14 @@ tr.dark:hover { td { padding: 2px 5px; - font-size: 12px; + font-size: 100%; vertical-align: top; } td.link, td.selflink { padding: 2px 5px; font-family: sans-serif; - font-size: 10px; + font-size: 70%; } td.selflink { @@ -416,7 +415,7 @@ div.index_include { } div.search { - font-size: 12px; + font-size: 100%; font-weight: normal; margin: 4px 8px; position: absolute; @@ -444,7 +443,7 @@ a.rss_logo { background-color: #ff6600; font-weight: bold; font-family: sans-serif; - font-size: 10px; + font-size: 70%; text-align: center; text-decoration: none; } @@ -455,7 +454,7 @@ a.rss_logo:hover { span.refs span { padding: 0px 4px; - font-size: 10px; + font-size: 70%; font-weight: normal; border: 1px solid; background-color: #ffaaff; -- cgit v1.3 From b211c320eb5d753a7a44a03eccb9a15cfbcc563b Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Wed, 16 May 2007 01:59:55 +0200 Subject: gitweb: Do not use absolute font sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit David Kågedal proposed that gitweb should explicitely request being somewhat smaller than normal, because it has good use for long lines. However gitweb presents a table with several columns, so having wider line is OK for it. Therefore explicit 'font-size: small' would make sense. Apparently many people on the list seem to agree with him. Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 1 + 1 file changed, 1 insertion(+) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index b57c8beccb..02623cbb6d 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -1,5 +1,6 @@ body { font-family: sans-serif; + font-size: small; border: solid #d9d8d1; border-width: 1px; margin: 10px; -- cgit v1.3 From e7738553723dcff0237b1aed2771886c8d87d224 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Thu, 17 May 2007 04:31:12 +0200 Subject: gitweb: Add support for grep searches The 'grep' type of search greps the currently selected tree for given regexp and shows the results in a fancy table with links into blob view. The number of shown matches is limited to 1000 and the whole feature can be turned off (grepping linux-2.6.git already makes repo.or.cz a bit unhappy). This second revision makes it in documentation explicit that grep accepts regexps, and makes grep accept extended regexps instead of basic regexps. Signed-off-by: Petr Baudis Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 4 ++ gitweb/gitweb.perl | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 125 insertions(+), 2 deletions(-) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 02623cbb6d..9f0822fab3 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -484,3 +484,7 @@ span.atnight { span.match { color: #e00000; } + +div.binary { + font-style: italic; +} diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 260d79bd78..cc16e3137e 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -146,6 +146,19 @@ our %feature = ( 'override' => 0, 'default' => [1]}, + # Enable grep search, which will list the files in currently selected + # tree containing the given string. Enabled by default. This can be + # potentially CPU-intensive, of course. + + # To enable system wide have in $GITWEB_CONFIG + # $feature{'grep'}{'default'} = [1]; + # To have project specific config enable override in $GITWEB_CONFIG + # $feature{'grep'}{'override'} = 1; + # and in project config gitweb.grep = 0|1; + 'grep' => { + 'override' => 0, + 'default' => [1]}, + # Enable the pickaxe search, which will list the commits that modified # a given string in a file. This can be practical and quite faster # alternative to 'blame', but still potentially CPU-intensive. @@ -245,6 +258,18 @@ sub gitweb_have_snapshot { return $have_snapshot; } +sub feature_grep { + my ($val) = git_get_project_config('grep', '--bool'); + + if ($val eq 'true') { + return (1); + } elsif ($val eq 'false') { + return (0); + } + + return ($_[0]); +} + sub feature_pickaxe { my ($val) = git_get_project_config('pickaxe', '--bool'); @@ -364,10 +389,17 @@ if (defined $page) { } } +our $searchtype = $cgi->param('st'); +if (defined $searchtype) { + if ($searchtype =~ m/[^a-z]/) { + die_error(undef, "Invalid searchtype parameter"); + } +} + our $searchtext = $cgi->param('s'); our $search_regexp; if (defined $searchtext) { - if ($searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) { + if ($searchtype ne 'grep' and $searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) { die_error(undef, "Invalid search parameter"); } if (length($searchtext) < 2) { @@ -1927,7 +1959,7 @@ EOF $cgi->hidden(-name => "a") . "\n" . $cgi->hidden(-name => "h") . "\n" . $cgi->popup_menu(-name => 'st', -default => 'commit', - -values => ['commit', 'author', 'committer', 'pickaxe']) . + -values => ['commit', 'grep', 'author', 'committer', 'pickaxe']) . $cgi->sup($cgi->a({-href => href(action=>"search_help")}, "?")) . " search:\n", $cgi->textfield(-name => "s", -value => $searchtext) . "\n" . @@ -4626,6 +4658,12 @@ sub git_search { die_error('403 Permission denied', "Permission denied"); } } + if ($searchtype eq 'grep') { + my ($have_grep) = gitweb_check_feature('grep'); + if (!$have_grep) { + die_error('403 Permission denied', "Permission denied"); + } + } git_header_html(); @@ -4742,6 +4780,73 @@ sub git_search { print "
" . + $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'})) . + "" . + esc_path($diff{'to_file'}) . + "" . + $cgi->a({-href => "#patch$patchno"}, "patch") . + " | " . + " | " . + $cgi->a({-href => href(action=>"blob", + hash_base=>$hash, + hash=>$from_hash, + file_name=>$from_path)}, + "blob" . ($i+1)) . + " | "; + } + print $cgi->a({-href => href(action=>"blobdiff", + hash=>$diff{'to_id'}, + hash_parent=>$from_hash, + hash_base=>$hash, + hash_parent_base=>$hash_parent, + file_name=>$diff{'to_file'}, + file_parent=>$from_path)}, + "diff" . ($i+1)) . + " | "; + if ($not_deleted) { + print $cgi->a({-href => href(action=>"blob", + 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'}, + hash_base=>$hash)}, + "history"); + } + print "
\n"; } + + if ($searchtype eq 'grep') { + git_print_page_nav('','', $hash,$co{'tree'},$hash); + git_print_header_div('commit', esc_html($co{'title'}), $hash); + + print "\n"; + my $alternate = 1; + my $matches = 0; + $/ = "\n"; + open my $fd, "-|", git_cmd(), 'grep', '-n', '-i', '-E', $searchtext, $co{'tree'}; + my $lastfile = ''; + while (my $line = <$fd>) { + chomp $line; + my ($file, $lno, $ltext, $binary); + last if ($matches++ > 1000); + if ($line =~ /^Binary file (.+) matches$/) { + $file = $1; + $binary = 1; + } else { + (undef, $file, $lno, $ltext) = split(/:/, $line, 4); + } + if ($file ne $lastfile) { + $lastfile and print "\n"; + if ($alternate++) { + print "\n"; + } else { + print "\n"; + } + print "\n"; + if ($matches > 1000) { + print "
Too many matches, listing trimmed
\n"; + } + } else { + print "
No matches found
\n"; + } + close $fd; + + print "
". + $cgi->a({-href => href(action=>"blob", hash=>$co{'hash'}, + file_name=>"$file"), + -class => "list"}, esc_path($file)); + print "\n"; + $lastfile = $file; + } + if ($binary) { + print "
Binary file
\n"; + } else { + $ltext = untabify($ltext); + if ($ltext =~ m/^(.*)($searchtext)(.*)$/i) { + $ltext = esc_html($1, -nbsp=>1); + $ltext .= ''; + $ltext .= esc_html($2, -nbsp=>1); + $ltext .= ''; + $ltext .= esc_html($3, -nbsp=>1); + } else { + $ltext = esc_html($ltext, -nbsp=>1); + } + print "
" . + $cgi->a({-href => href(action=>"blob", hash=>$co{'hash'}, + file_name=>"$file").'#l'.$lno, + -class => "linenr"}, sprintf('%4i', $lno)) + . ' ' . $ltext . "
\n"; + } + } + if ($lastfile) { + print "
\n"; + } git_footer_html(); } @@ -4752,6 +4857,20 @@ sub git_search_help {
commit
The commit messages and authorship information will be scanned for the given string.
+EOT + my ($have_grep) = gitweb_check_feature('grep'); + if ($have_grep) { + print <grep +
All files in the currently selected tree (HEAD unless you are explicitly browsing + a different one) are searched for the given +regular expression +(POSIX extended) and the matches are listed. On large +trees, this search can take a while and put some strain on the server, so please use it with +some consideration.
+EOT + } + print <author
Name and e-mail of the change author and date of birth of the patch will be scanned for the given string.
committer
-- cgit v1.3 From 47598d7a4920f02c60d7091e7186c50468d83aab Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Fri, 8 Jun 2007 13:24:56 +0200 Subject: gitweb: Provide links to commitdiff to each parent in 'commitdiff' view Since commit-fb1dde4a we show combined diff for merges in 'commitdiff' view, and since commit-208ecb2e also in 'commit' view. Sometimes though one would want to see diff to one of merge commit parents. It is easy in 'commit' view: in the commit header part there are "diff" links for each of parent header. This commit adds such links also for 'commitdiff' view. Add to difftree / whatchanged table row with "1", "2", ... links to 'commitdiff' view for diff with n-th parent for merge commits, as a table header. This is visible only in 'comitdiff' view, and only for a merge commit (comit with more than one parent). To save space links are shown as "n", where "n" is number of a parent, and not as for example shortened (to 7 characters) sha1 of a parent commit. To make it easier to discover what links is for, each link has 'title' attribute explaining the link. Note that one would need to remember that difftree table in 'commit' view has one less column (it doesn't have "patch" link column), if one would want to add such table header also in 'commit' view. Example output: 1 2 3 Makefile patch | diff1 | diff2 | diff3 | blob | history cache.h patch | diff1 | diff2 | diff3 | blob | history Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 5 +++++ gitweb/gitweb.perl | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 9f0822fab3..7908fe3b5f 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -181,10 +181,15 @@ table.diff_tree { font-family: monospace; } +table.combined.diff_tree th { + text-align: center; +} + table.combined.diff_tree td { padding-right: 24px; } +table.combined.diff_tree th.link, table.combined.diff_tree td.link { padding: 0px 2px; } diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index e92596c295..e2d52222bf 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2401,6 +2401,26 @@ sub git_difftree_body { print " 1 ? "combined " : "") . "diff_tree\">\n"; + + # header only for combined diff in 'commitdiff' view + my $has_header = @parents > 1 && $action eq 'commitdiff'; + if ($has_header) { + # table header + print "\n" . + "\n"; # filename, patchN link + for (my $i = 0; $i < @parents; $i++) { + my $par = $parents[$i]; + print "\n"; + } + print "\n\n"; + } + my $alternate = 1; my $patchno = 0; foreach my $line (@{$difftree}) { @@ -2673,6 +2693,7 @@ sub git_difftree_body { } # we should not encounter Unmerged (U) or Unknown (X) status print "\n"; } + print "" if $has_header; print "
" . + $cgi->a({-href => href(action=>"commitdiff", + hash=>$hash, hash_parent=>$par), + -title => 'commitdiff to parent number ' . + ($i+1) . ': ' . substr($par,0,7)}, + $i+1) . + " 
\n"; } -- cgit v1.3 From c956395e2bf94a50fe843935605914573f4c7787 Mon Sep 17 00:00:00 2001 From: Matt McCutchen Date: Thu, 28 Jun 2007 18:15:22 -0400 Subject: gitweb: make "No commits" in project list gray, not bold green A missing return statement in git_get_last_activity made gitweb think a project with no commits was in age class "age0", so the "No commits" appeared in bold green, which was ridiculous. I added the return so those projects get "noage" and added a block to gitweb.css to format the "No commits" text gray. Signed-off-by: Matt McCutchen Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 6 ++++++ gitweb/gitweb.perl | 1 + 2 files changed, 7 insertions(+) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 7908fe3b5f..096313bec0 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -281,6 +281,12 @@ table.diff_tree span.file_status.copied { color: #70a070; } +/* noage: "No commits" */ +table.project_list td.noage { + color: #808080; + font-style: italic; +} + /* age2: 60*60*24*2 <= age */ table.project_list td.age2, table.blame td.age2 { font-style: italic; diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 4eb7832b4a..dc609f4f86 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1526,6 +1526,7 @@ sub git_get_last_activity { my $age = time - $timestamp; return ($age, age_string($age)); } + return (undef, undef); } sub git_get_references { -- cgit v1.3 From 67aca456a3cfa9ab8420a6e171d8eee7b0ad2209 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Sun, 26 Aug 2007 21:31:32 +0200 Subject: gitweb: Fix searchbox positioning Currently, searchbox is CSS'd to have position: absolute, which has the unfortunate consequence that if the viewport is too small and can't fit into the page width together with the navbar, it gets overlapped and part of the navbar gets obscured. This makes searchbox float: right instead, thus the navbar simply gets wrapped. Discovered and fix pointed out by Michael Olson . Signed-off-by: Petr Baudis Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 096313bec0..1b8887987f 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -430,7 +430,7 @@ div.search { font-size: 100%; font-weight: normal; margin: 4px 8px; - position: absolute; + float: right; top: 56px; right: 12px } -- cgit v1.3 From 591ebf6595ac7d5e5a21abbfc7501df19a67dc89 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 19 Nov 2007 14:16:11 +0100 Subject: gitweb: Style all tables using CSS Remove all cellspacing="0" attributes from tables in gitweb, replacing it by CSS rule. Add CSS classes for all tables. While at it, change class(es) of table for commit message and commit authorship search from "grep" to "commit_search"; similarly, "grep_search" class is now used for table with results of grep (files) search. Signed-off-by: Jakub Narebski --- gitweb/gitweb.css | 4 ---- gitweb/gitweb.perl | 22 +++++++++++----------- 2 files changed, 11 insertions(+), 15 deletions(-) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 1b8887987f..17c60e4cb4 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -170,14 +170,10 @@ a.text:hover { table { padding: 8px 4px; -} - -table.project_list { border-spacing: 0; } table.diff_tree { - border-spacing: 0; font-family: monospace; } diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index e788ef90c9..3d532dc7d7 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -3544,7 +3544,7 @@ sub git_shortlog_body { $from = 0 unless defined $from; $to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to); - print "\n"; + print "
\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { my %co = %{$commitlist->[$i]}; @@ -3590,7 +3590,7 @@ sub git_history_body { $from = 0 unless defined $from; $to = $#{$commitlist} unless (defined $to && $to <= $#{$commitlist}); - print "
\n"; + print "
\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { my %co = %{$commitlist->[$i]}; @@ -3650,7 +3650,7 @@ sub git_tags_body { $from = 0 unless defined $from; $to = $#{$taglist} if (!defined $to || $#{$taglist} < $to); - print "
\n"; + print "
\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { my $entry = $taglist->[$i]; @@ -3713,7 +3713,7 @@ sub git_heads_body { $from = 0 unless defined $from; $to = $#{$headlist} if (!defined $to || $#{$headlist} < $to); - print "
\n"; + print "
\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { my $entry = $headlist->[$i]; @@ -3750,7 +3750,7 @@ sub git_search_grep_body { $from = 0 unless defined $from; $to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to); - print "
\n"; + print "
\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { my %co = %{$commitlist->[$i]}; @@ -3891,7 +3891,7 @@ sub git_summary { git_print_page_nav('summary','', $head); print "
 
\n"; - print "
\n" . + print "
\n" . "\n" . "\n"; if (defined $cd{'rfc2822'}) { @@ -3965,7 +3965,7 @@ sub git_tag { git_print_header_div('commit', esc_html($tag{'name'}), $hash); print "
\n" . - "
description" . esc_html($descr) . "
owner" . esc_html($owner) . "
\n" . + "
\n" . "\n" . "\n" . "
object" . $cgi->a({-class => "list", -href => href(action=>$tag{'type'}, hash=>$tag{'object'})}, @@ -4405,7 +4405,7 @@ sub git_tree { } git_print_page_path($file_name, 'tree', $hash_base); print "
\n"; - print "\n"; + print "
\n"; my $alternate = 1; # '..' (top directory) link if possible if (defined $hash_base && @@ -4627,7 +4627,7 @@ sub git_commit { git_print_header_div('tree', esc_html($co{'title'}) . $ref, $co{'tree'}, $hash); } print "
\n" . - "
\n"; + "
\n"; print "\n". "" . "
author" . esc_html($co{'author'}) . "
$ad{'rfc2822'}"; @@ -5226,7 +5226,7 @@ sub git_search { git_print_page_nav('','', $hash,$co{'tree'},$hash); git_print_header_div('commit', esc_html($co{'title'}), $hash); - print "\n"; + print "
\n"; my $alternate = 1; $/ = "\n"; my $git_command = git_cmd_str(); @@ -5293,7 +5293,7 @@ sub git_search { git_print_page_nav('','', $hash,$co{'tree'},$hash); git_print_header_div('commit', esc_html($co{'title'}), $hash); - print "
\n"; + print "
\n"; my $alternate = 1; my $matches = 0; $/ = "\n"; -- cgit v1.3 From 9d066745708b77ef917565d699d5d193bfb00fbd Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 19 Nov 2007 14:16:12 +0100 Subject: gitweb: Put project README in div.readme, fix its padding Put (optional) projects README on "summary" page in
element using "readme" class. This allow to style it using CSS. Add padding to project's README to make it line out with the rest of the page. Signed-off-by: Jakub Narebski --- gitweb/gitweb.css | 4 ++++ gitweb/gitweb.perl | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 17c60e4cb4..446a1c333b 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -85,6 +85,10 @@ div.title, a.title { color: #000000; } +div.readme { + padding: 8px; +} + a.title:hover { background-color: #d9d8d1; } diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 3d532dc7d7..491a3f41d2 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -3912,8 +3912,10 @@ sub git_summary { if (-s "$projectroot/$project/README.html") { if (open my $fd, "$projectroot/$project/README.html") { - print "
readme
\n"; + print "
readme
\n" . + "
\n"; print $_ while (<$fd>); + print "\n
\n"; # class="readme" close $fd; } } -- cgit v1.3 From 3562198b7da7ef6597af27b3a7fcaeee41608999 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 20 Apr 2008 22:09:48 +0200 Subject: gitweb: Use feed link according to current view Michael G. Noll said in comments to the "Switching my code repository from Subversion (SVN) to git" article (http://tinyurl.com/37v67l) in his "My digital moleskine" blog, that one of the things he is missing in gitweb from SVN::Web is an RSS feed with news/information of the current view (including RSS feed for single file or directory). This is not exactly true, as since refactoring feed generation in af6feeb (gitweb: Refactor feed generation, make output prettier, add Atom feed, 2006-11-19), gitweb can generate feeds (RSS or Atom) for history of a given branch, history limited to a given directory, or history of a given file. Nevertheless this required handcrafting the URL to get wanted RSS feed. This commit makes gitweb select feed links in the HTML header and in page footer depending on current view (action). It is more elaborate, and I guess more correct, than simple patch adding $hash ('h') parameter to *all* URLs, including feed links, by Jean-Baptiste Quenot Subject: [PATCH] gitweb: Add hash parameter in feed URL when a hash is specified in the current request Message-ID: If $hash ('h') or $hash_base ('hb') parameter is a branch name (i.e. it starts with 'refs/heads/'; all generated URLs use this form to discriminate between tags and heads), it is used in feed URLs; if $file_name ('f') is defined, it is used in feed URLs. Feed title is set according to the kind of web feed: it is either 'log' for generic feed, 'log of ', 'history of ' for generic history (using implicit or explicit HEAD, i.e. current branch) or 'history of on '. There are special cases: 'heads' and 'forks' views should use OPML providing list of available feeds; 'tags' probably also should use OPML; there is no web feed equivalent to 'search' view. Currently all those cases fallback to (show) default feed. Such feed link uses "generic" class, and is shown in slightly lighter color for distinction. Currently feed can have but one starting point, and does not support negative (exclude) commit arguments. Therefore for now for *diff views it is chosen that feed follow the "to" part: to-name, to-commit for 'blobdiff', 'treediff' and 'commitdiff' views. Generating parameters for href() for feed link was separated (refactored) into get_feed_info() subroutine. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 8 ++++ gitweb/gitweb.perl | 121 ++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 104 insertions(+), 25 deletions(-) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 446a1c333b..aa0eeca247 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -464,6 +464,14 @@ a.rss_logo:hover { background-color: #ee5500; } +a.rss_logo.generic { + background-color: #ff8800; +} + +a.rss_logo.generic:hover { + background-color: #ee7700; +} + span.refs span { padding: 0px 4px; font-size: 70%; diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index f83567ec39..2facf2db7a 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -592,7 +592,7 @@ exit; ## ====================================================================== ## action links -sub href(%) { +sub href (%) { my %params = @_; # default is to use -absolute url() i.e. $my_uri my $href = $params{-full} ? $my_url : $my_uri; @@ -1448,6 +1448,46 @@ sub format_snapshot_links { } } +## ...................................................................... +## functions returning values to be passed, perhaps after some +## transformation, to other functions; e.g. returning arguments to href() + +# returns hash to be passed to href to generate gitweb URL +# in -title key it returns description of link +sub get_feed_info { + my $format = shift || 'Atom'; + my %res = (action => lc($format)); + + # feed links are possible only for project views + return unless (defined $project); + # some views should link to OPML, or to generic project feed, + # or don't have specific feed yet (so they should use generic) + return if ($action =~ /^(?:tags|heads|forks|tag|search)$/x); + + my $branch; + # branches refs uses 'refs/heads/' prefix (fullname) to differentiate + # from tag links; this also makes possible to detect branch links + if ((defined $hash_base && $hash_base =~ m!^refs/heads/(.*)$!) || + (defined $hash && $hash =~ m!^refs/heads/(.*)$!)) { + $branch = $1; + } + # find log type for feed description (title) + my $type = 'log'; + if (defined $file_name) { + $type = "history of $file_name"; + $type .= "/" if ($action eq 'tree'); + $type .= " on '$branch'" if (defined $branch); + } else { + $type = "log of $branch" if (defined $branch); + } + + $res{-title} = $type; + $res{'hash'} = (defined $branch ? "refs/heads/$branch" : undef); + $res{'file_name'} = $file_name; + + return %res; +} + ## ---------------------------------------------------------------------- ## git utility subroutines, invoking git commands @@ -2510,30 +2550,49 @@ EOF } } if (defined $project) { - printf(''."\n", - esc_param($project), href(action=>"rss")); - printf(''."\n", - esc_param($project), href(action=>"rss", - extra_options=>"--no-merges")); - printf(''."\n", - esc_param($project), href(action=>"atom")); - printf(''."\n", - esc_param($project), href(action=>"atom", - extra_options=>"--no-merges")); + my %href_params = get_feed_info(); + if (!exists $href_params{'-title'}) { + $href_params{'-title'} = 'log'; + } + + foreach my $format qw(RSS Atom) { + my $type = lc($format); + my %link_attr = ( + '-rel' => 'alternate', + '-title' => "$project - $href_params{'-title'} - $format feed", + '-type' => "application/$type+xml" + ); + + $href_params{'action'} = $type; + $link_attr{'-href'} = href(%href_params); + print "\n"; + + $href_params{'extra_options'} = '--no-merges'; + $link_attr{'-href'} = href(%href_params); + $link_attr{'-title'} .= ' (no merges)'; + print "\n"; + } + } else { printf(''."\n", + 'href="%s" type="text/plain; charset=utf-8" />'."\n", $site_name, href(project=>undef, action=>"project_index")); printf(''."\n", + 'href="%s" type="text/x-opml" />'."\n", $site_name, href(project=>undef, action=>"opml")); } if (defined $favicon) { - print qq(\n); + print qq(\n); } print "\n" . @@ -2601,23 +2660,35 @@ EOF } sub git_footer_html { + my $feed_class = 'rss_logo'; + print "
\n"; if (defined $project) { my $descr = git_get_project_description($project); if (defined $descr) { print "\n"; } - print $cgi->a({-href => href(action=>"rss"), - -class => "rss_logo"}, "RSS") . " "; - print $cgi->a({-href => href(action=>"atom"), - -class => "rss_logo"}, "Atom") . "\n"; + + my %href_params = get_feed_info(); + if (!%href_params) { + $feed_class .= ' generic'; + } + $href_params{'-title'} ||= 'log'; + + foreach my $format qw(RSS Atom) { + $href_params{'action'} = lc($format); + print $cgi->a({-href => href(%href_params), + -title => "$href_params{'-title'} $format feed", + -class => $feed_class}, $format)."\n"; + } + } else { print $cgi->a({-href => href(project=>undef, action=>"opml"), - -class => "rss_logo"}, "OPML") . " "; + -class => $feed_class}, "OPML") . " "; print $cgi->a({-href => href(project=>undef, action=>"project_index"), - -class => "rss_logo"}, "TXT") . "\n"; + -class => $feed_class}, "TXT") . "\n"; } - print "
\n" ; + print "
\n"; # class="page_footer" if (-f $site_footer) { open (my $fd, $site_footer); -- cgit v1.3 From 4afbaefffa9095fe1391b4b61289a7dc954e9f7b Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Tue, 2 Sep 2008 21:47:05 +0200 Subject: gitweb: ref markers link to named shortlogs This patch turns ref markers for tags and heads into links to appropriate views for the ref name, depending on current context. For annotated tags, we link to the tag view, unless that's the current view, in which case we switch to shortlog. For other refs, we prefer the current view if it's history or (short)log, and default to shortlog otherwise. Appropriate changes are made in the CSS to prevent ref markers from being annoyingly blue and underlined, unless hovered. A visual indication of the target view difference is also implemented by making annotated tags show up in italic. Signed-off-by: Giuseppe Bilotta Acked-by: Petr Baudis Acked-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 13 +++++++++++++ gitweb/gitweb.perl | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 3 deletions(-) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index aa0eeca247..07f5b53788 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -481,6 +481,19 @@ span.refs span { border-color: #ffccff #ff00ee #ff00ee #ffccff; } +span.refs span a { + text-decoration: none; + color: inherit; +} + +span.refs span a:hover { + text-decoration: underline; +} + +span.refs span.indirect { + font-style: italic; +} + span.refs span.ref { background-color: #aaaaff; border-color: #ccccff #0033cc #0033cc #ccccff; diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 90cd99bf91..29e21564c8 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1090,13 +1090,23 @@ sub format_log_line_html { } # format marker of refs pointing to given object + +# the destination action is chosen based on object type and current context: +# - for annotated tags, we choose the tag view unless it's the current view +# already, in which case we go to shortlog view +# - for other refs, we keep the current view if we're in history, shortlog or +# log view, and select shortlog otherwise sub format_ref_marker { my ($refs, $id) = @_; my $markers = ''; if (defined $refs->{$id}) { foreach my $ref (@{$refs->{$id}}) { + # this code exploits the fact that non-lightweight tags are the + # only indirect objects, and that they are the only objects for which + # we want to use tag instead of shortlog as action my ($type, $name) = qw(); + my $indirect = ($ref =~ s/\^\{\}$//); # e.g. tags/v2.6.11 or heads/next if ($ref =~ m!^(.*?)s?/(.*)$!) { $type = $1; @@ -1106,8 +1116,29 @@ sub format_ref_marker { $name = $ref; } - $markers .= " " . - esc_html($name) . ""; + my $class = $type; + $class .= " indirect" if $indirect; + + my $dest_action = "shortlog"; + + if ($indirect) { + $dest_action = "tag" unless $action eq "tag"; + } elsif ($action =~ /^(history|(short)?log)$/) { + $dest_action = $action; + } + + my $dest = ""; + $dest .= "refs/" unless $ref =~ m!^refs/!; + $dest .= $ref; + + my $link = $cgi->a({ + -href => href( + action=>$dest_action, + hash=>$dest + )}, $name); + + $markers .= " " . + $link . ""; } } @@ -1918,7 +1949,7 @@ sub git_get_references { while (my $line = <$fd>) { chomp $line; - if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type/?[^^]+)!) { + if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type.*)$!) { if (defined $refs{$1}) { push @{$refs{$1}}, $2; } else { -- cgit v1.3 From 0d1d154dbe4d16a802c2e357de96e349f04d2f2c Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Fri, 3 Oct 2008 09:29:45 +0200 Subject: gitweb: Support for simple project search form This is a trivial patch adding support for searching projects by name and description, making use of the "infrastructure" provided by the tag cloud generation. Signed-off-by: Petr Baudis Signed-off-by: Shawn O. Pearce --- gitweb/gitweb.css | 4 ++++ gitweb/gitweb.perl | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 07f5b53788..a01eac814e 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -435,6 +435,10 @@ div.search { right: 12px } +p.projsearch { + text-align: center; +} + td.linenr { text-align: right; } diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 99fdb13f1f..b46af77da0 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -3767,11 +3767,14 @@ sub git_project_list_body { my $pr = $projects[$i]; next if $tagfilter and $show_ctags and not grep { lc $_ eq lc $tagfilter } keys %{$pr->{'ctags'}}; - # Weed out forks + next if $searchtext and not $pr->{'path'} =~ /$searchtext/ + and not $pr->{'descr_long'} =~ /$searchtext/; + # Weed out forks or non-matching entries of search if ($check_forks) { my $forkbase = $project; $forkbase ||= ''; $forkbase =~ s#\.git$#/#; $forkbase="^$forkbase" if $forkbase; - next if not $tagfilter and $pr->{'path'} =~ m#$forkbase.*/.*#; # regexp-safe + next if not $searchtext and not $tagfilter and $show_ctags + and $pr->{'path'} =~ m#$forkbase.*/.*#; # regexp-safe } if ($alternate) { @@ -4108,6 +4111,11 @@ sub git_project_list { close $fd; print "\n"; } + print $cgi->startform(-method => "get") . + "

Search:\n" . + $cgi->textfield(-name => "s", -value => $searchtext) . "\n" . + "

" . + $cgi->end_form() . "\n"; git_project_list_body(\@list, $order); git_footer_html(); } -- cgit v1.3 From 1c49a4e1f324dcaa000ce92ed44d0e5b9eb16843 Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Tue, 30 Jun 2009 00:00:48 +0200 Subject: gitweb: refactor author name insertion Collect all author display code in appropriate functions, making it easier to extend these functions on the CGI side. We also move some of the presentation code from hard-coded HTML to CSS, for easier customization. A side effect of the refactoring is that now localtime is always displayed with the 'at night' warning. Signed-off-by: Giuseppe Bilotta Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 5 ++- gitweb/gitweb.perl | 93 ++++++++++++++++++++++++++++++++---------------------- 2 files changed, 59 insertions(+), 39 deletions(-) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index a01eac814e..68b22ffece 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -132,11 +132,14 @@ div.list_head { font-style: italic; } +.author_date, .author { + font-style: italic; +} + div.author_date { padding: 8px; border: solid #d9d8d1; border-width: 0px 0px 1px 0px; - font-style: italic; } a.list { diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 1e7e2d8387..7fd53f68de 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1469,6 +1469,16 @@ sub format_subject_html { } } +# format the author name of the given commit with the given tag +# the author name is chopped and escaped according to the other +# optional parameters (see chop_str). +sub format_author_html { + my $tag = shift; + my $co = shift; + my $author = chop_and_escape_str($co->{'author_name'}, @_); + return "<$tag class=\"author\">" . $author . ""; +} + # format git diff header line, i.e. "diff --(git|combined|cc) ..." sub format_git_diff_header_line { my $line = shift; @@ -3214,21 +3224,50 @@ sub git_print_header_div { "\n\n"; } +sub print_local_time { + my %date = @_; + if ($date{'hour_local'} < 6) { + printf(" (%02d:%02d %s)", + $date{'hour_local'}, $date{'minute_local'}, $date{'tz_local'}); + } else { + printf(" (%02d:%02d %s)", + $date{'hour_local'}, $date{'minute_local'}, $date{'tz_local'}); + } +} + +# Outputs the author name and date in long form sub git_print_authorship { my $co = shift; + my %opts = @_; + my $tag = $opts{-tag} || 'div'; my %ad = parse_date($co->{'author_epoch'}, $co->{'author_tz'}); - print "
" . + print "<$tag class=\"author_date\">" . esc_html($co->{'author_name'}) . " [$ad{'rfc2822'}"; - if ($ad{'hour_local'} < 6) { - printf(" (%02d:%02d %s)", - $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'}); - } else { - printf(" (%02d:%02d %s)", - $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'}); + print_local_time(%ad) if ($opts{-localtime}); + print "]\n"; +} + +# Outputs table rows containing the full author or committer information, +# in the format expected for 'commit' view (& similia). +# Parameters are a commit hash reference, followed by the list of people +# to output information for. If the list is empty it defalts to both +# author and committer. +sub git_print_authorship_rows { + my $co = shift; + # too bad we can't use @people = @_ || ('author', 'committer') + my @people = @_; + @people = ('author', 'committer') unless @people; + foreach my $who (@people) { + my %wd = parse_date($co->{"${who}_epoch"}, $co->{"${who}_tz"}); + print "
\n". + "" . + "" . + "\n"; } - print "]\n"; } sub git_print_page_path { @@ -4142,11 +4181,9 @@ sub git_shortlog_body { print "\n"; } $alternate ^= 1; - my $author = chop_and_escape_str($co{'author_name'}, 10); # git_summary() used print "\n" . print "\n" . - "\n" . - "\n" . @@ -4193,11 +4230,9 @@ sub git_history_body { print "\n"; } $alternate ^= 1; - # shortlog uses chop_str($co{'author_name'}, 10) - my $author = chop_and_escape_str($co{'author_name'}, 15, 3); print "\n" . - "\n" . - "\n"; } $alternate ^= 1; - my $author = chop_and_escape_str($co{'author_name'}, 15, 5); print "\n" . - "\n" . + format_author_html('td', \%co, 15, 5) . "
$who" . esc_html($co->{$who}) . "
$wd{'rfc2822'}"; + print_local_time(%wd); + print "
$co{'age_string'}$co{'age_string_date'}" . $author . ""; + format_author_html('td', \%co, 10) . ""; print format_subject_html($co{'title'}, $co{'title_short'}, href(action=>"commit", hash=>$commit), $ref); print "
$co{'age_string_date'}" . $author . ""; + # shortlog: format_author_html('td', \%co, 10) + format_author_html('td', \%co, 15, 3) . ""; # originally git_history used chop_str($co{'title'}, 50) print format_subject_html($co{'title'}, $co{'title_short'}, href(action=>"commit", hash=>$commit), $ref); @@ -4350,9 +4385,8 @@ sub git_search_grep_body { print "
$co{'age_string_date'}" . $author . "" . $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}), -class => "list subject"}, @@ -5094,9 +5128,9 @@ sub git_log { " | " . $cgi->a({-href => href(action=>"tree", hash=>$commit, hash_base=>$commit)}, "tree") . "
\n" . - "\n" . - "" . esc_html($co{'author_name'}) . " [$ad{'rfc2822'}]
\n" . "\n"; + git_print_authorship(\%co, -tag => 'span'); + print "
\n\n"; print "
\n"; git_print_log($co{'comment'}, -final_empty_line=> 1); @@ -5115,8 +5149,6 @@ sub git_commit { $hash ||= $hash_base || "HEAD"; my %co = parse_commit($hash) or die_error(404, "Unknown commit object"); - my %ad = parse_date($co{'author_epoch'}, $co{'author_tz'}); - my %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'}); my $parent = $co{'parent'}; my $parents = $co{'parents'}; # listref @@ -5183,22 +5215,7 @@ sub git_commit { } print "
\n" . "\n"; - print "\n". - "" . - "" . - "\n"; - print "\n"; - print "\n"; + git_print_authorship_rows(\%co); print "\n"; print "" . "" . @@ -5579,7 +5596,7 @@ sub git_commitdiff { git_header_html(undef, $expires); git_print_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav); git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash); - git_print_authorship(\%co); + git_print_authorship(\%co, -localtime => 1); print "
\n"; if (@{$co{'comment'}} > 1) { print "
\n"; -- cgit v1.3 From e9fdd74e5374dd1efe1577057d14a2836b4cae78 Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Tue, 30 Jun 2009 00:00:51 +0200 Subject: gitweb: (gr)avatar support Introduce avatar support: the feature adds the appropriate img tag next to author and committer in commit(diff), history, shortlog, log and tag views. Multiple avatar providers are possible, but only gravatar is implemented at the moment. Gravatar support depends on Digest::MD5, which is a core package since Perl 5.8. If gravatars are activated but Digest::MD5 cannot be found, the feature will be automatically disabled. No avatar provider is selected by default, except in the t9500 test. Signed-off-by: Giuseppe Bilotta Signed-off-by: Junio C Hamano --- gitweb/gitweb.css | 4 ++ gitweb/gitweb.perl | 83 ++++++++++++++++++++++++++++++++-- t/t9500-gitweb-standalone-no-errors.sh | 2 + 3 files changed, 86 insertions(+), 3 deletions(-) (limited to 'gitweb/gitweb.css') diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css index 68b22ffece..d05bc37646 100644 --- a/gitweb/gitweb.css +++ b/gitweb/gitweb.css @@ -28,6 +28,10 @@ img.logo { border-width: 0px; } +img.avatar { + vertical-align: middle; +} + div.page_header { height: 25px; padding: 8px; diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index a393ac6f29..92695a3ae8 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -195,6 +195,14 @@ our %known_snapshot_format_aliases = ( 'x-zip' => undef, '' => undef, ); +# Pixel sizes for icons and avatars. If the default font sizes or lineheights +# are changed, it may be appropriate to change these values too via +# $GITWEB_CONFIG. +our %avatar_size = ( + 'default' => 16, + 'double' => 32 +); + # You define site-wide feature defaults here; override them with # $GITWEB_CONFIG as necessary. our %feature = ( @@ -365,6 +373,24 @@ our %feature = ( 'sub' => \&feature_patches, 'override' => 0, 'default' => [16]}, + + # Avatar support. When this feature is enabled, views such as + # shortlog or commit will display an avatar associated with + # the email of the committer(s) and/or author(s). + + # Currently only the gravatar provider is available, and it + # depends on Digest::MD5. If an unknown provider is specified, + # the feature is disabled. + + # To enable system wide have in $GITWEB_CONFIG + # $feature{'avatar'}{'default'} = ['gravatar']; + # To have project specific config enable override in $GITWEB_CONFIG + # $feature{'avatar'}{'override'} = 1; + # and in project config gitweb.avatar = gravatar; + 'avatar' => { + 'sub' => \&feature_avatar, + 'override' => 0, + 'default' => ['']}, ); sub gitweb_get_feature { @@ -433,6 +459,12 @@ sub feature_patches { return ($_[0]); } +sub feature_avatar { + my @val = (git_get_project_config('avatar')); + + return @val ? @val : @_; +} + # checking HEAD file with -e is fragile if the repository was # initialized long time ago (i.e. symlink HEAD) and was pack-ref'ed # and then pruned. @@ -814,6 +846,17 @@ $git_dir = "$projectroot/$project" if $project; our @snapshot_fmts = gitweb_get_feature('snapshot'); @snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts); +# check that the avatar feature is set to a known provider name, +# and for each provider check if the dependencies are satisfied. +# if the provider name is invalid or the dependencies are not met, +# reset $git_avatar to the empty string. +our ($git_avatar) = gitweb_get_feature('avatar'); +if ($git_avatar eq 'gravatar') { + $git_avatar = '' unless (eval { require Digest::MD5; 1; }); +} else { + $git_avatar = ''; +} + # dispatch if (!defined $action) { if (defined $hash) { @@ -1469,6 +1512,34 @@ sub format_subject_html { } } +# Insert an avatar for the given $email at the given $size if the feature +# is enabled. +sub git_get_avatar { + my ($email, %opts) = @_; + my $pre_white = ($opts{-pad_before} ? " " : ""); + my $post_white = ($opts{-pad_after} ? " " : ""); + $opts{-size} ||= 'default'; + my $size = $avatar_size{$opts{-size}} || $avatar_size{'default'}; + my $url = ""; + if ($git_avatar eq 'gravatar') { + $url = "http://www.gravatar.com/avatar/" . + Digest::MD5::md5_hex(lc $email) . "?s=$size"; + } + # Currently only gravatars are supported, but other forms such as + # picons can be added by putting an else up here and defining $url + # as needed. If no variant puts something in $url, we assume avatars + # are completely disabled/unavailable. + if ($url) { + return $pre_white . + "" . $post_white; + } else { + return ""; + } +} + # format the author name of the given commit with the given tag # the author name is chopped and escaped according to the other # optional parameters (see chop_str). @@ -1476,7 +1547,9 @@ sub format_author_html { my $tag = shift; my $co = shift; my $author = chop_and_escape_str($co->{'author_name'}, @_); - return "<$tag class=\"author\">" . $author . ""; + return "<$tag class=\"author\">" . + git_get_avatar($co->{'author_email'}, -pad_after => 1) . + $author . ""; } # format git diff header line, i.e. "diff --(git|combined|cc) ..." @@ -3252,7 +3325,8 @@ sub git_print_authorship { esc_html($co->{'author_name'}) . " [$ad{'rfc2822'}"; print_local_time(%ad) if ($opts{-localtime}); - print "]\n"; + print "]" . git_get_avatar($co->{'author_email'}, -pad_before => 1) + . "\n"; } # Outputs table rows containing the full author or committer information, @@ -3267,7 +3341,10 @@ sub git_print_authorship_rows { @people = ('author', 'committer') unless @people; foreach my $who (@people) { my %wd = parse_date($co->{"${who}_epoch"}, $co->{"${who}_tz"}); - print "
\n". + print "" . + "\n" . "" . "
author" . esc_html($co{'author'}) . "
$ad{'rfc2822'}"; - if ($ad{'hour_local'} < 6) { - printf(" (%02d:%02d %s)", - $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'}); - } else { - printf(" (%02d:%02d %s)", - $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'}); - } - print "
committer" . esc_html($co{'committer'}) . "
$cd{'rfc2822'}" . - sprintf(" (%02d:%02d %s)", $cd{'hour_local'}, $cd{'minute_local'}, $cd{'tz_local'}) . - "
commit$co{'id'}
tree
$who" . esc_html($co->{$who}) . "
$who" . esc_html($co->{$who}) . "" . + git_get_avatar($co->{"${who}_email"}, -size => 'double') . + "
$wd{'rfc2822'}"; print_local_time(%wd); diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index d539619e89..627518108a 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -660,6 +660,7 @@ cat >>gitweb_config.perl <