Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 1 | #!/usr/bin/perl |
| 2 | |
Kay Sievers | 22fafb9 | 2005-08-07 19:56:59 +0200 | [diff] [blame] | 3 | # gitweb.pl - simple web interface to track changes in git repositories |
| 4 | # |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 5 | # (C) 2005, Kay Sievers <kay.sievers@vrfy.org> |
| 6 | # (C) 2005, Christian Gierke <ch@gierke.de> |
Kay Sievers | 823d5dc | 2005-08-07 19:57:58 +0200 | [diff] [blame] | 7 | # |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 8 | # This program is licensed under the GPL v2, or a later version |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 9 | |
| 10 | use strict; |
| 11 | use warnings; |
| 12 | use CGI qw(:standard :escapeHTML); |
| 13 | use CGI::Carp qw(fatalsToBrowser); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 14 | use Fcntl ':mode'; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 15 | |
Kay Sievers | 3e02929 | 2005-08-07 20:05:15 +0200 | [diff] [blame] | 16 | my $cgi = new CGI; |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 17 | my $version = "142"; |
Kay Sievers | 3e02929 | 2005-08-07 20:05:15 +0200 | [diff] [blame] | 18 | my $my_url = $cgi->url(); |
| 19 | my $my_uri = $cgi->url(-absolute => 1); |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 20 | my $rss_link = ""; |
Kay Sievers | 44ad297 | 2005-08-07 19:59:24 +0200 | [diff] [blame] | 21 | |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 22 | # absolute fs-path which will be prepended to the project path |
| 23 | my $projectroot = "/pub/scm"; |
| 24 | |
| 25 | # location of the git-core binaries |
| 26 | my $gitbin = "/usr/bin"; |
| 27 | |
| 28 | # location for temporary files needed for diffs |
| 29 | my $gittmp = "/tmp/gitweb"; |
| 30 | |
| 31 | # target of the home link on top of all pages |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 32 | my $home_link = $my_uri; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 33 | |
Kay Sievers | 8ab1da2 | 2005-08-07 20:22:53 +0200 | [diff] [blame] | 34 | # html text to include at home page |
| 35 | my $home_text = "indextext.html"; |
| 36 | |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 37 | # source of projects list |
| 38 | #my $projects_list = $projectroot; |
| 39 | my $projects_list = "index/index.txt"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 40 | |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 41 | # input validation and dispatch |
| 42 | my $action = $cgi->param('a'); |
| 43 | if (defined $action) { |
| 44 | if ($action =~ m/[^0-9a-zA-Z\.\-]+/) { |
| 45 | undef $action; |
| 46 | die_error(undef, "Invalid action parameter."); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 47 | } |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 48 | if ($action eq "git-logo.png") { |
| 49 | git_logo(); |
| 50 | exit; |
| 51 | } |
| 52 | } else { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 53 | $action = "summary"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 54 | } |
| 55 | |
Kay Sievers | 022be3d | 2005-08-07 20:06:09 +0200 | [diff] [blame] | 56 | my $project = $cgi->param('p'); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 57 | if (defined $project) { |
| 58 | if ($project =~ m/(^|\/)(|\.|\.\.)($|\/)/) { |
| 59 | undef $project; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 60 | die_error(undef, "Non-canonical project parameter."); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 61 | } |
| 62 | if ($project =~ m/[^a-zA-Z0-9_\.\/\-\+\#\~]/) { |
| 63 | undef $project; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 64 | die_error(undef, "Invalid character in project parameter."); |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 65 | } |
| 66 | if (!(-d "$projectroot/$project")) { |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 67 | undef $project; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 68 | die_error(undef, "No such directory."); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 69 | } |
| 70 | if (!(-e "$projectroot/$project/HEAD")) { |
| 71 | undef $project; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 72 | die_error(undef, "No such project."); |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 73 | } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 74 | $rss_link = "<link rel=\"alternate\" title=\"$project log\" href=\"$my_uri?p=$project;a=rss\" type=\"application/rss+xml\"/>"; |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 75 | $ENV{'GIT_OBJECT_DIRECTORY'} = "$projectroot/$project/objects"; |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 76 | $ENV{'SHA1_FILE_DIRECTORY'} = "$projectroot/$project/objects"; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 77 | } else { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 78 | git_project_list(); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 79 | exit; |
Kay Sievers | 2ad9331 | 2005-08-07 20:14:48 +0200 | [diff] [blame] | 80 | } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 81 | |
| 82 | my $file_name = $cgi->param('f'); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 83 | if (defined $file_name) { |
| 84 | if ($file_name =~ m/(^|\/)(|\.|\.\.)($|\/)/) { |
| 85 | undef $file_name; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 86 | die_error(undef, "Non-canonical file parameter."); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 87 | } |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 88 | if ($file_name =~ m/[^a-zA-Z0-9_\.\/\-\+\#\~\:\!]/) { |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 89 | undef $file_name; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 90 | die_error(undef, "Invalid character in file parameter."); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 91 | } |
Kay Sievers | d51e902 | 2005-08-07 20:16:07 +0200 | [diff] [blame] | 92 | } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 93 | |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 94 | my $hash = $cgi->param('h'); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 95 | if (defined $hash && !($hash =~ m/^[0-9a-fA-F]{40}$/)) { |
| 96 | undef $hash; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 97 | die_error(undef, "Invalid hash parameter."); |
Kay Sievers | a59d4af | 2005-08-07 20:15:44 +0200 | [diff] [blame] | 98 | } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 99 | |
| 100 | my $hash_parent = $cgi->param('hp'); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 101 | if (defined $hash_parent && !($hash_parent =~ m/^[0-9a-fA-F]{40}$/)) { |
| 102 | undef $hash_parent; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 103 | die_error(undef, "Invalid hash_parent parameter."); |
| 104 | } |
| 105 | |
| 106 | my $hash_base = $cgi->param('hb'); |
| 107 | if (defined $hash_base && !($hash_base =~ m/^[0-9a-fA-F]{40}$/)) { |
| 108 | undef $hash_base; |
| 109 | die_error(undef, "Invalid parent hash parameter."); |
Kay Sievers | a59d4af | 2005-08-07 20:15:44 +0200 | [diff] [blame] | 110 | } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 111 | |
| 112 | my $time_back = $cgi->param('t'); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 113 | if (defined $time_back) { |
| 114 | if ($time_back =~ m/^[^0-9]+$/) { |
| 115 | undef $time_back; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 116 | die_error(undef, "Invalid time parameter."); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 117 | } |
Kay Sievers | a59d4af | 2005-08-07 20:15:44 +0200 | [diff] [blame] | 118 | } |
Kay Sievers | 823d5dc | 2005-08-07 19:57:58 +0200 | [diff] [blame] | 119 | |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 120 | if ($action eq "summary") { |
| 121 | git_summary(); |
| 122 | exit; |
| 123 | } elsif ($action eq "tags") { |
| 124 | git_tags(); |
| 125 | exit; |
| 126 | } elsif ($action eq "blob") { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 127 | git_blob(); |
| 128 | exit; |
| 129 | } elsif ($action eq "tree") { |
| 130 | git_tree(); |
| 131 | exit; |
| 132 | } elsif ($action eq "rss") { |
| 133 | git_rss(); |
| 134 | exit; |
| 135 | } elsif ($action eq "commit") { |
| 136 | git_commit(); |
| 137 | exit; |
| 138 | } elsif ($action eq "log") { |
| 139 | git_log(); |
| 140 | exit; |
| 141 | } elsif ($action eq "blobdiff") { |
| 142 | git_blobdiff(); |
| 143 | exit; |
| 144 | } elsif ($action eq "commitdiff") { |
| 145 | git_commitdiff(); |
| 146 | exit; |
| 147 | } elsif ($action eq "history") { |
| 148 | git_history(); |
| 149 | exit; |
| 150 | } else { |
| 151 | undef $action; |
| 152 | die_error(undef, "Unknown action."); |
| 153 | exit; |
| 154 | } |
| 155 | |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 156 | sub git_header_html { |
Kay Sievers | a59d4af | 2005-08-07 20:15:44 +0200 | [diff] [blame] | 157 | my $status = shift || "200 OK"; |
| 158 | |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 159 | my $title = "git"; |
| 160 | if (defined $project) { |
| 161 | $title .= " - $project"; |
| 162 | if (defined $action) { |
| 163 | $title .= "/$action"; |
| 164 | } |
| 165 | } |
Kay Sievers | a59d4af | 2005-08-07 20:15:44 +0200 | [diff] [blame] | 166 | print $cgi->header(-type=>'text/html', -charset => 'utf-8', -status=> $status); |
| 167 | print <<EOF; |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 168 | <?xml version="1.0" encoding="utf-8"?> |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 169 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 170 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US"> |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 171 | <!-- git web interface v$version, (C) 2005, Kay Sievers <kay.sievers\@vrfy.org>, Christian Gierke <ch\@gierke.de> --> |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 172 | <head> |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 173 | <title>$title</title> |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 174 | $rss_link |
| 175 | <style type="text/css"> |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 176 | body { font-family: sans-serif; font-size: 12px; margin:0px; border:solid #d9d8d1; border-width:1px; margin:10px; } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 177 | a { color:#0000cc; } |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 178 | a:hover, a:visited, a:active { color:#880000; } |
| 179 | div.page_header { height:25px; padding:8px; font-size:18px; font-weight:bold; background-color:#d9d8d1; } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 180 | div.page_header a:visited { color:#0000cc; } |
| 181 | div.page_header a:hover { color:#880000; } |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 182 | div.page_nav { padding:8px; } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 183 | div.page_nav a:visited { color:#0000cc; } |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 184 | div.page_path { font-weight:bold; padding:8px; border:solid #d9d8d1; border-width:0px 0px 1px} |
| 185 | div.page_footer { height:17px; padding:4px 8px; background-color: #d9d8d1; } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 186 | div.page_footer_text { float:left; color:#555555; font-style:italic; } |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 187 | div.page_body { padding:8px; } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 188 | div.title, a.title { |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 189 | display:block; padding:6px 8px; |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 190 | font-weight:bold; background-color:#edece6; text-decoration:none; color:#000000; |
| 191 | } |
| 192 | a.title:hover { background-color: #d9d8d1; } |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 193 | div.title_text { padding:6px 8px; border: solid #d9d8d1; border-width:0px 0px 1px; } |
| 194 | div.log_body { padding:8px 8px 8px 150px; } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 195 | span.log_age { position:relative; float:left; width:142px; font-style:italic; } |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 196 | div.log_link { |
| 197 | font-size:10px; font-family:sans-serif; font-style:normal; |
| 198 | position:relative; float:left; width:142px; |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 199 | } |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 200 | div.list { display:block; padding:4px 8px 2px; } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 201 | div.list_head { |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 202 | display:block; padding:6px 6px 4px; border:solid #d9d8d1; |
| 203 | border-width:0px 0px 1px; font-style:italic; |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 204 | } |
| 205 | div.list a { text-decoration:none; color:#000000; } |
| 206 | div.list a:hover { color:#880000; } |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 207 | div.list_link { |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 208 | padding:4px 8px 6px; border:solid #d9d8d1; border-width:0px 0px 1px; |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 209 | font-family:sans-serif; font-size:10px; |
| 210 | } |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 211 | td { padding:5px 15px 0px 0px; font-size:12px; } |
| 212 | th { padding-right:10px; font-size:12px; text-align:left; } |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 213 | td.link { font-family:sans-serif; font-size:10px; } |
| 214 | td.pre { font-family:monospace; font-size:12px; white-space:pre; padding:2px 15px 0px 0px; } |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 215 | div.pre { font-family:monospace; font-size:12px; white-space:pre; } |
| 216 | div.diff_info { font-family:monospace; color:#000099; background-color:#edece6; font-style:italic; } |
Kay Sievers | 8ab1da2 | 2005-08-07 20:22:53 +0200 | [diff] [blame] | 217 | div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; padding:12px 8px; } |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 218 | a.rss_logo { float:right; padding:3px 0px; width:35px; line-height:10px; |
| 219 | border:1px solid; border-color:#fcc7a5 #7d3302 #3e1a01 #ff954e; |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 220 | color:#ffffff; background-color:#ff6600; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 221 | font-weight:bold; font-family:sans-serif; font-size:10px; |
| 222 | text-align:center; text-decoration:none; |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 223 | } |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 224 | a.rss_logo:hover { background-color:#ee5500; } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 225 | </style> |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 226 | </head> |
| 227 | <body> |
| 228 | EOF |
Kay Sievers | ff7669a | 2005-08-07 20:13:02 +0200 | [diff] [blame] | 229 | print "<div class=\"page_header\">\n" . |
Kay Sievers | 8ab1da2 | 2005-08-07 20:22:53 +0200 | [diff] [blame] | 230 | "<a href=\"http://kernel.org/pub/software/scm/git/docs/\">" . |
Kay Sievers | 022be3d | 2005-08-07 20:06:09 +0200 | [diff] [blame] | 231 | "<img src=\"$my_uri?a=git-logo.png\" width=\"72\" height=\"27\" alt=\"git\" style=\"float:right; border-width:0px;\"/></a>"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 232 | print $cgi->a({-href => $home_link}, "projects") . " / "; |
| 233 | if (defined $project) { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 234 | print $cgi->a({-href => "$my_uri?p=$project;a=summary"}, escapeHTML($project)); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 235 | if (defined $action) { |
| 236 | print " / $action"; |
| 237 | } |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 238 | } |
| 239 | print "</div>\n"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 240 | } |
| 241 | |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 242 | sub git_footer_html { |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 243 | print "<div class=\"page_footer\">\n"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 244 | if (defined $project) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 245 | my $descr = git_read_description($project); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 246 | if (defined $descr) { |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 247 | print "<div class=\"page_footer_text\">" . escapeHTML($descr) . "</div>\n"; |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 248 | } |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 249 | print $cgi->a({-href => "$my_uri?p=$project;a=rss", -class => "rss_logo"}, "RSS") . "\n"; |
Kay Sievers | ff7669a | 2005-08-07 20:13:02 +0200 | [diff] [blame] | 250 | } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 251 | print "</div>\n" . |
| 252 | "</body>\n" . |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 253 | "</html>"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 254 | } |
| 255 | |
Kay Sievers | 061cc7c | 2005-08-07 20:15:57 +0200 | [diff] [blame] | 256 | sub die_error { |
| 257 | my $status = shift || "403 Forbidden"; |
Kay Sievers | a59d4af | 2005-08-07 20:15:44 +0200 | [diff] [blame] | 258 | my $error = shift || "Malformed query, file missing or permission denied"; |
Kay Sievers | 664f4cc | 2005-08-07 20:17:19 +0200 | [diff] [blame] | 259 | |
Kay Sievers | a59d4af | 2005-08-07 20:15:44 +0200 | [diff] [blame] | 260 | git_header_html($status); |
| 261 | print "<div class=\"page_body\">\n" . |
| 262 | "<br/><br/>\n"; |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 263 | print "$status - $error\n"; |
Kay Sievers | a59d4af | 2005-08-07 20:15:44 +0200 | [diff] [blame] | 264 | print "<br/></div>\n"; |
| 265 | git_footer_html(); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 266 | exit; |
Kay Sievers | a59d4af | 2005-08-07 20:15:44 +0200 | [diff] [blame] | 267 | } |
| 268 | |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 269 | sub git_get_type { |
| 270 | my $hash = shift; |
| 271 | |
| 272 | open my $fd, "-|", "$gitbin/git-cat-file -t $hash" || return; |
| 273 | my $type = <$fd>; |
| 274 | close $fd; |
| 275 | chomp $type; |
| 276 | return $type; |
| 277 | } |
| 278 | |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 279 | sub git_read_hash { |
Kay Sievers | 54b0a43 | 2005-08-07 20:08:03 +0200 | [diff] [blame] | 280 | my $path = shift; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 281 | |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 282 | open my $fd, "$projectroot/$path" || return undef; |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 283 | my $head = <$fd>; |
| 284 | close $fd; |
| 285 | chomp $head; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 286 | if ($head =~ m/^[0-9a-fA-F]{40}$/) { |
| 287 | return $head; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 288 | } |
| 289 | } |
| 290 | |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 291 | sub git_read_description { |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 292 | my $path = shift; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 293 | |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 294 | open my $fd, "$projectroot/$path/description" || return undef; |
| 295 | my $descr = <$fd>; |
| 296 | close $fd; |
| 297 | chomp $descr; |
| 298 | return $descr; |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 299 | } |
| 300 | |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 301 | sub git_read_tag { |
| 302 | my $tag_id = shift; |
| 303 | my %tag; |
| 304 | |
| 305 | open my $fd, "-|", "$gitbin/git-cat-file tag $tag_id" || return; |
| 306 | while (my $line = <$fd>) { |
| 307 | chomp $line; |
| 308 | if ($line =~ m/^object ([0-9a-fA-F]{40})$/) { |
| 309 | $tag{'object'} = $1; |
| 310 | } elsif ($line =~ m/^type (.*)$/) { |
| 311 | $tag{'type'} = $1; |
| 312 | } elsif ($line =~ m/^tag (.*)$/) { |
| 313 | $tag{'name'} = $1; |
| 314 | } |
| 315 | } |
| 316 | close $fd || return; |
| 317 | if (!defined $tag{'name'}) { |
| 318 | return |
| 319 | }; |
| 320 | return %tag |
| 321 | } |
| 322 | |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 323 | sub git_read_commit { |
Kay Sievers | 703ac71 | 2005-08-07 20:03:14 +0200 | [diff] [blame] | 324 | my $commit = shift; |
| 325 | my %co; |
| 326 | my @parents; |
| 327 | |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 328 | open my $fd, "-|", "$gitbin/git-cat-file commit $commit" || return; |
Kay Sievers | 703ac71 | 2005-08-07 20:03:14 +0200 | [diff] [blame] | 329 | while (my $line = <$fd>) { |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 330 | last if $line eq "\n"; |
| 331 | chomp $line; |
Kay Sievers | 703ac71 | 2005-08-07 20:03:14 +0200 | [diff] [blame] | 332 | if ($line =~ m/^tree (.*)$/) { |
| 333 | $co{'tree'} = $1; |
| 334 | } elsif ($line =~ m/^parent (.*)$/) { |
| 335 | push @parents, $1; |
Kay Sievers | 022be3d | 2005-08-07 20:06:09 +0200 | [diff] [blame] | 336 | } elsif ($line =~ m/^author (.*) ([0-9]+) (.*)$/) { |
Kay Sievers | 3f71453 | 2005-08-07 20:03:52 +0200 | [diff] [blame] | 337 | $co{'author'} = $1; |
Kay Sievers | 185f09e | 2005-08-07 20:13:11 +0200 | [diff] [blame] | 338 | $co{'author_epoch'} = $2; |
| 339 | $co{'author_tz'} = $3; |
Kay Sievers | 991910a | 2005-08-07 20:09:33 +0200 | [diff] [blame] | 340 | $co{'author_name'} = $co{'author'}; |
| 341 | $co{'author_name'} =~ s/ <.*//; |
Kay Sievers | 86eed32 | 2005-08-07 20:08:29 +0200 | [diff] [blame] | 342 | } elsif ($line =~ m/^committer (.*) ([0-9]+) (.*)$/) { |
| 343 | $co{'committer'} = $1; |
Kay Sievers | 185f09e | 2005-08-07 20:13:11 +0200 | [diff] [blame] | 344 | $co{'committer_epoch'} = $2; |
| 345 | $co{'committer_tz'} = $3; |
Kay Sievers | 991910a | 2005-08-07 20:09:33 +0200 | [diff] [blame] | 346 | $co{'committer_name'} = $co{'committer'}; |
| 347 | $co{'committer_name'} =~ s/ <.*//; |
Kay Sievers | 703ac71 | 2005-08-07 20:03:14 +0200 | [diff] [blame] | 348 | } |
| 349 | } |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 350 | if (!defined $co{'tree'}) { |
| 351 | close $fd; |
| 352 | return undef |
| 353 | }; |
Kay Sievers | 3f71453 | 2005-08-07 20:03:52 +0200 | [diff] [blame] | 354 | $co{'parents'} = \@parents; |
Kay Sievers | 3e02929 | 2005-08-07 20:05:15 +0200 | [diff] [blame] | 355 | $co{'parent'} = $parents[0]; |
Kay Sievers | 3f71453 | 2005-08-07 20:03:52 +0200 | [diff] [blame] | 356 | my (@comment) = map { chomp; $_ } <$fd>; |
| 357 | $co{'comment'} = \@comment; |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 358 | $comment[0] =~ m/^(.{0,60}[^ ]*)/; |
| 359 | $co{'title'} = $1; |
| 360 | if ($comment[0] ne $co{'title'}) { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 361 | $co{'title'} .= " ..."; |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 362 | } |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 363 | close $fd || return; |
Kay Sievers | 2ae100d | 2005-08-07 20:17:00 +0200 | [diff] [blame] | 364 | |
| 365 | my $age = time - $co{'committer_epoch'}; |
| 366 | $co{'age'} = $age; |
| 367 | if ($age > 60*60*24*365*2) { |
| 368 | $co{'age_string'} = (int $age/60/60/24/365); |
| 369 | $co{'age_string'} .= " years ago"; |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 370 | } elsif ($age > 60*60*24*(365/12)*2) { |
| 371 | $co{'age_string'} = int $age/60/60/24/(365/12); |
Kay Sievers | 2ae100d | 2005-08-07 20:17:00 +0200 | [diff] [blame] | 372 | $co{'age_string'} .= " months ago"; |
| 373 | } elsif ($age > 60*60*24*7*2) { |
| 374 | $co{'age_string'} = int $age/60/60/24/7; |
| 375 | $co{'age_string'} .= " weeks ago"; |
| 376 | } elsif ($age > 60*60*24*2) { |
| 377 | $co{'age_string'} = int $age/60/60/24; |
| 378 | $co{'age_string'} .= " days ago"; |
| 379 | } elsif ($age > 60*60*2) { |
| 380 | $co{'age_string'} = int $age/60/60; |
| 381 | $co{'age_string'} .= " hours ago"; |
| 382 | } elsif ($age > 60*2) { |
| 383 | $co{'age_string'} = int $age/60; |
| 384 | $co{'age_string'} .= " minutes ago"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 385 | } elsif ($age > 2) { |
| 386 | $co{'age_string'} = int $age; |
| 387 | $co{'age_string'} .= " seconds ago"; |
| 388 | } else { |
| 389 | $co{'age_string'} .= " right now"; |
Kay Sievers | 2ae100d | 2005-08-07 20:17:00 +0200 | [diff] [blame] | 390 | } |
Kay Sievers | 703ac71 | 2005-08-07 20:03:14 +0200 | [diff] [blame] | 391 | return %co; |
| 392 | } |
| 393 | |
Kay Sievers | 8ed23e1 | 2005-08-07 20:05:44 +0200 | [diff] [blame] | 394 | sub git_diff_html { |
Kay Sievers | 8ed23e1 | 2005-08-07 20:05:44 +0200 | [diff] [blame] | 395 | my $from = shift; |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 396 | my $from_name = shift; |
Kay Sievers | 8ed23e1 | 2005-08-07 20:05:44 +0200 | [diff] [blame] | 397 | my $to = shift; |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 398 | my $to_name = shift; |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 399 | |
Kay Sievers | 8ed23e1 | 2005-08-07 20:05:44 +0200 | [diff] [blame] | 400 | my $from_tmp = "/dev/null"; |
| 401 | my $to_tmp = "/dev/null"; |
Kay Sievers | 8ed23e1 | 2005-08-07 20:05:44 +0200 | [diff] [blame] | 402 | my $pid = $$; |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 403 | |
Kay Sievers | ff7669a | 2005-08-07 20:13:02 +0200 | [diff] [blame] | 404 | # create tmp from-file |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 405 | if (defined $from) { |
Kay Sievers | 8ed23e1 | 2005-08-07 20:05:44 +0200 | [diff] [blame] | 406 | $from_tmp = "$gittmp/gitweb_" . $$ . "_from"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 407 | open my $fd2, "> $from_tmp"; |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 408 | open my $fd, "-|", "$gitbin/git-cat-file blob $from"; |
Kay Sievers | 8ed23e1 | 2005-08-07 20:05:44 +0200 | [diff] [blame] | 409 | my @file = <$fd>; |
| 410 | print $fd2 @file; |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 411 | close $fd2; |
| 412 | close $fd; |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 413 | } |
| 414 | |
Kay Sievers | b531daf | 2005-08-07 19:55:05 +0200 | [diff] [blame] | 415 | # create tmp to-file |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 416 | if (defined $to) { |
Kay Sievers | 8ed23e1 | 2005-08-07 20:05:44 +0200 | [diff] [blame] | 417 | $to_tmp = "$gittmp/gitweb_" . $$ . "_to"; |
| 418 | open my $fd2, "> $to_tmp"; |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 419 | open my $fd, "-|", "$gitbin/git-cat-file blob $to"; |
Kay Sievers | 8ed23e1 | 2005-08-07 20:05:44 +0200 | [diff] [blame] | 420 | my @file = <$fd>; |
| 421 | print $fd2 @file; |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 422 | close $fd2; |
| 423 | close $fd; |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 424 | } |
| 425 | |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 426 | open my $fd, "-|", "/usr/bin/diff -u -p -L $from_name -L $to_name $from_tmp $to_tmp"; |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 427 | while (my $line = <$fd>) { |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 428 | chomp($line); |
| 429 | my $char = substr($line, 0, 1); |
| 430 | my $color = ""; |
| 431 | if ($char eq '+') { |
| 432 | $color = " style=\"color:#008800;\""; |
| 433 | } elsif ($char eq '-') { |
| 434 | $color = " style=\"color:#cc0000;\""; |
| 435 | } elsif ($char eq '@') { |
| 436 | $color = " style=\"color:#990099;\""; |
| 437 | } elsif ($char eq '\\') { |
| 438 | # skip errors |
| 439 | next; |
| 440 | } |
| 441 | print "<div class=\"pre\"$color>" . escapeHTML($line) . "</div>\n"; |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 442 | } |
| 443 | close $fd; |
Kay Sievers | 8ed23e1 | 2005-08-07 20:05:44 +0200 | [diff] [blame] | 444 | |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 445 | if (defined $from) { |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 446 | unlink($from_tmp); |
Kay Sievers | 8ed23e1 | 2005-08-07 20:05:44 +0200 | [diff] [blame] | 447 | } |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 448 | if (defined $to) { |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 449 | unlink($to_tmp); |
Kay Sievers | 8ed23e1 | 2005-08-07 20:05:44 +0200 | [diff] [blame] | 450 | } |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 451 | } |
| 452 | |
Kay Sievers | d767d59 | 2005-08-07 20:05:55 +0200 | [diff] [blame] | 453 | sub mode_str { |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 454 | my $mode = oct shift; |
| 455 | |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 456 | if (S_ISDIR($mode & S_IFMT)) { |
| 457 | return 'drwxr-xr-x'; |
| 458 | } elsif (S_ISLNK($mode)) { |
| 459 | return 'lrwxrwxrwx'; |
| 460 | } elsif (S_ISREG($mode)) { |
Kay Sievers | 991910a | 2005-08-07 20:09:33 +0200 | [diff] [blame] | 461 | # git cares only about the executable bit |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 462 | if ($mode & S_IXUSR) { |
| 463 | return '-rwxr-xr-x'; |
Kay Sievers | 54b0a43 | 2005-08-07 20:08:03 +0200 | [diff] [blame] | 464 | } else { |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 465 | return '-rw-r--r--'; |
Kay Sievers | 54b0a43 | 2005-08-07 20:08:03 +0200 | [diff] [blame] | 466 | }; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 467 | } else { |
| 468 | return '----------'; |
Kay Sievers | d767d59 | 2005-08-07 20:05:55 +0200 | [diff] [blame] | 469 | } |
Kay Sievers | d767d59 | 2005-08-07 20:05:55 +0200 | [diff] [blame] | 470 | } |
| 471 | |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 472 | sub file_type { |
| 473 | my $mode = oct shift; |
| 474 | |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 475 | if (S_ISDIR($mode & S_IFMT)) { |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 476 | return "directory"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 477 | } elsif (S_ISLNK($mode)) { |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 478 | return "symlink"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 479 | } elsif (S_ISREG($mode)) { |
| 480 | return "file"; |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 481 | } else { |
| 482 | return "unknown"; |
| 483 | } |
| 484 | } |
| 485 | |
Kay Sievers | 86eed32 | 2005-08-07 20:08:29 +0200 | [diff] [blame] | 486 | sub date_str { |
Kay Sievers | 991910a | 2005-08-07 20:09:33 +0200 | [diff] [blame] | 487 | my $epoch = shift; |
| 488 | my $tz = shift || "-0000"; |
Kay Sievers | 86eed32 | 2005-08-07 20:08:29 +0200 | [diff] [blame] | 489 | |
Kay Sievers | 991910a | 2005-08-07 20:09:33 +0200 | [diff] [blame] | 490 | my %date; |
Kay Sievers | 86eed32 | 2005-08-07 20:08:29 +0200 | [diff] [blame] | 491 | my @months = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); |
| 492 | my @days = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"); |
Kay Sievers | 991910a | 2005-08-07 20:09:33 +0200 | [diff] [blame] | 493 | my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($epoch); |
| 494 | $date{'hour'} = $hour; |
Kay Sievers | ff7669a | 2005-08-07 20:13:02 +0200 | [diff] [blame] | 495 | $date{'minute'} = $min; |
| 496 | $date{'mday'} = $mday; |
| 497 | $date{'day'} = $days[$wday]; |
| 498 | $date{'month'} = $months[$mon]; |
Kay Sievers | 991910a | 2005-08-07 20:09:33 +0200 | [diff] [blame] | 499 | $date{'rfc2822'} = sprintf "%s, %d %s %4d %02d:%02d:%02d +0000", $days[$wday], $mday, $months[$mon], 1900+$year, $hour ,$min, $sec; |
| 500 | $date{'mday-time'} = sprintf "%d %s %02d:%02d", $mday, $months[$mon], $hour ,$min; |
| 501 | |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 502 | $tz =~ m/^([+\-][0-9][0-9])([0-9][0-9])$/; |
| 503 | my $local = $epoch + ((int $1 + ($2/60)) * 3600); |
Kay Sievers | 991910a | 2005-08-07 20:09:33 +0200 | [diff] [blame] | 504 | ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($local); |
Kay Sievers | 185f09e | 2005-08-07 20:13:11 +0200 | [diff] [blame] | 505 | $date{'hour_local'} = $hour; |
| 506 | $date{'minute_local'} = $min; |
| 507 | $date{'tz_local'} = $tz; |
Kay Sievers | 991910a | 2005-08-07 20:09:33 +0200 | [diff] [blame] | 508 | return %date; |
Kay Sievers | 86eed32 | 2005-08-07 20:08:29 +0200 | [diff] [blame] | 509 | } |
| 510 | |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 511 | # git-logo (cached in browser for one day) |
Kay Sievers | eb28240 | 2005-08-07 20:21:34 +0200 | [diff] [blame] | 512 | sub git_logo { |
Kay Sievers | 022be3d | 2005-08-07 20:06:09 +0200 | [diff] [blame] | 513 | print $cgi->header(-type => 'image/png', -expires => '+1d'); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 514 | # cat git-logo.png | hexdump -e '16/1 " %02x" "\n"' | sed 's/ /\\x/g' |
| 515 | print "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52" . |
| 516 | "\x00\x00\x00\x48\x00\x00\x00\x1b\x04\x03\x00\x00\x00\x2d\xd9\xd4" . |
| 517 | "\x2d\x00\x00\x00\x18\x50\x4c\x54\x45\xff\xff\xff\x60\x60\x5d\xb0" . |
| 518 | "\xaf\xaa\x00\x80\x00\xce\xcd\xc7\xc0\x00\x00\xe8\xe8\xe6\xf7\xf7" . |
| 519 | "\xf6\x95\x0c\xa7\x47\x00\x00\x00\x73\x49\x44\x41\x54\x28\xcf\x63" . |
| 520 | "\x48\x67\x20\x04\x4a\x5c\x18\x0a\x08\x2a\x62\x53\x61\x20\x02\x08" . |
| 521 | "\x0d\x69\x45\xac\xa1\xa1\x01\x30\x0c\x93\x60\x36\x26\x52\x91\xb1" . |
| 522 | "\x01\x11\xd6\xe1\x55\x64\x6c\x6c\xcc\x6c\x6c\x0c\xa2\x0c\x70\x2a" . |
| 523 | "\x62\x06\x2a\xc1\x62\x1d\xb3\x01\x02\x53\xa4\x08\xe8\x00\x03\x18" . |
| 524 | "\x26\x56\x11\xd4\xe1\x20\x97\x1b\xe0\xb4\x0e\x35\x24\x71\x29\x82" . |
| 525 | "\x99\x30\xb8\x93\x0a\x11\xb9\x45\x88\xc1\x8d\xa0\xa2\x44\x21\x06" . |
| 526 | "\x27\x41\x82\x40\x85\xc1\x45\x89\x20\x70\x01\x00\xa4\x3d\x21\xc5" . |
| 527 | "\x12\x1c\x9a\xfe\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82"; |
Kay Sievers | 022be3d | 2005-08-07 20:06:09 +0200 | [diff] [blame] | 528 | } |
| 529 | |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 530 | sub get_file_owner { |
| 531 | my $path = shift; |
| 532 | |
| 533 | my ($dev, $ino, $mode, $nlink, $st_uid, $st_gid, $rdev, $size) = stat($path); |
| 534 | my ($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) = getpwuid($st_uid); |
| 535 | if (!defined $gcos) { |
| 536 | return undef; |
| 537 | } |
| 538 | my $owner = $gcos; |
| 539 | $owner =~ s/[,;].*$//; |
| 540 | return $owner; |
| 541 | } |
| 542 | |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 543 | sub git_project_list { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 544 | my @list; |
| 545 | |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 546 | if (-d $projects_list) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 547 | # search in directory |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 548 | my $dir = $projects_list; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 549 | opendir my $dh, $dir || return undef; |
| 550 | while (my $dir = readdir($dh)) { |
| 551 | if (-e "$projectroot/$dir/HEAD") { |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 552 | my $pr = { |
| 553 | path => $dir, |
| 554 | }; |
| 555 | push @list, $pr |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 556 | } |
| 557 | } |
| 558 | closedir($dh); |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 559 | } elsif (-f $projects_list) { |
| 560 | # read from file: |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 561 | # 'git/git.git:Linus Torvalds' |
| 562 | # 'linux/hotplug/udev.git' |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 563 | open my $fd , $projects_list || return undef; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 564 | while (my $line = <$fd>) { |
| 565 | chomp $line; |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 566 | my ($path, $owner) = split ':', $line; |
| 567 | if (!defined $path) { |
| 568 | next; |
| 569 | } |
| 570 | if (-e "$projectroot/$path/HEAD") { |
| 571 | my $pr = { |
| 572 | path => $path, |
| 573 | owner => $owner, |
| 574 | }; |
| 575 | push @list, $pr |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 576 | } |
| 577 | } |
| 578 | close $fd; |
| 579 | } |
| 580 | |
| 581 | if (!@list) { |
| 582 | die_error(undef, "No project found."); |
| 583 | } |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 584 | @list = sort {$a->{'path'} cmp $b->{'path'}} @list; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 585 | |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 586 | git_header_html(); |
Kay Sievers | 8ab1da2 | 2005-08-07 20:22:53 +0200 | [diff] [blame] | 587 | if (-f $home_text) { |
| 588 | print "<div class=\"index_include\">\n"; |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 589 | open (my $fd, $home_text); |
Kay Sievers | 8ab1da2 | 2005-08-07 20:22:53 +0200 | [diff] [blame] | 590 | print <$fd>; |
| 591 | close $fd; |
| 592 | print "</div>\n"; |
| 593 | } |
| 594 | print "<div class=\"page_body\"><br/>\n" . |
| 595 | "<table cellspacing=\"0\">\n" . |
| 596 | "<tr>\n" . |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 597 | "<th>Project</th>\n" . |
| 598 | "<th>Description</th>\n" . |
| 599 | "<th>Owner</th>\n" . |
| 600 | "<th>last change</th>\n" . |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 601 | "<th></th>\n" . |
Kay Sievers | eb28240 | 2005-08-07 20:21:34 +0200 | [diff] [blame] | 602 | "</tr>\n"; |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 603 | foreach my $pr (@list) { |
| 604 | my %proj = %$pr; |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 605 | my $head = git_read_hash("$proj{'path'}/HEAD"); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 606 | if (!defined $head) { |
| 607 | next; |
| 608 | } |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 609 | $ENV{'GIT_OBJECT_DIRECTORY'} = "$projectroot/$proj{'path'}/objects"; |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 610 | $ENV{'SHA1_FILE_DIRECTORY'} = "$projectroot/$proj{'path'}/objects"; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 611 | my %co = git_read_commit($head); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 612 | if (!%co) { |
| 613 | next; |
| 614 | } |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 615 | my $descr = git_read_description($proj{'path'}) || ""; |
| 616 | # get directory owner if not already specified |
| 617 | if (!defined $proj{'owner'}) { |
| 618 | $proj{'owner'} = get_file_owner("$projectroot/$proj{'path'}") || ""; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 619 | } |
| 620 | print "<tr>\n" . |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 621 | "<td>" . $cgi->a({-href => "$my_uri?p=" . $proj{'path'} . ";a=summary"}, escapeHTML($proj{'path'})) . "</td>\n" . |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 622 | "<td>$descr</td>\n" . |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 623 | "<td><i>$proj{'owner'}</i></td>\n"; |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 624 | my $colored_age; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 625 | if ($co{'age'} < 60*60*2) { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 626 | $colored_age = "<span style =\"color: #009900;\"><b><i>$co{'age_string'}</i></b></span>"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 627 | } elsif ($co{'age'} < 60*60*24*2) { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 628 | $colored_age = "<span style =\"color: #009900;\"><i>$co{'age_string'}</i></span>"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 629 | } else { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 630 | $colored_age = "<i>$co{'age_string'}</i>"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 631 | } |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 632 | print "<td>$colored_age</td>\n" . |
| 633 | "<td class=\"link\">" . |
| 634 | $cgi->a({-href => "$my_uri?p=$proj{'path'};a=summary"}, "summary") . |
| 635 | " | " . $cgi->a({-href => "$my_uri?p=$proj{'path'};a=log"}, "log") . |
| 636 | " | " . $cgi->a({-href => "$my_uri?p=$proj{'path'};a=tree"}, "tree") . |
| 637 | "</td>\n"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 638 | } |
| 639 | print "</table>\n" . |
| 640 | "<br/>\n" . |
| 641 | "</div>\n"; |
| 642 | git_footer_html(); |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 643 | } |
| 644 | |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 645 | sub git_read_tags { |
| 646 | my @taglist; |
| 647 | |
| 648 | opendir my $dh, "$projectroot/$project/refs/tags"; |
| 649 | my @tags = grep !m/^\./, readdir $dh; |
| 650 | closedir($dh); |
| 651 | foreach my $tag_file (@tags) { |
| 652 | my $tag_id = git_read_hash("$project/refs/tags/$tag_file"); |
| 653 | my $type = git_get_type($tag_id) || next; |
| 654 | my %tag_item; |
| 655 | my %co; |
| 656 | if ($type eq "tag") { |
| 657 | my %tag = git_read_tag($tag_id); |
| 658 | if ($tag{'type'} eq "commit") { |
| 659 | %co = git_read_commit($tag{'object'}); |
| 660 | } |
| 661 | $tag_item{'type'} = $tag{'type'}; |
| 662 | $tag_item{'name'} = $tag{'name'}; |
| 663 | $tag_item{'id'} = $tag{'object'}; |
| 664 | } elsif ($type eq "commit"){ |
| 665 | %co = git_read_commit($tag_id); |
| 666 | $tag_item{'type'} = "commit"; |
| 667 | $tag_item{'name'} = $tag_file; |
| 668 | $tag_item{'id'} = $tag_id; |
| 669 | } |
| 670 | $tag_item{'epoch'} = $co{'author_epoch'} || 0; |
| 671 | $tag_item{'age'} = $co{'age_string'} || "unknown"; |
| 672 | |
| 673 | push @taglist, \%tag_item; |
| 674 | } |
| 675 | # sort tags by age |
| 676 | @taglist = sort {$b->{'epoch'} <=> $a->{'epoch'}} @taglist; |
| 677 | return \@taglist; |
| 678 | } |
| 679 | |
| 680 | sub git_summary { |
| 681 | my $descr = git_read_description($project) || "none"; |
| 682 | my $head = git_read_hash("$project/HEAD"); |
| 683 | $ENV{'GIT_OBJECT_DIRECTORY'} = "$projectroot/$project/objects"; |
| 684 | $ENV{'SHA1_FILE_DIRECTORY'} = "$projectroot/$project/objects"; |
| 685 | my %co = git_read_commit($head); |
| 686 | my %cd = date_str($co{'committer_epoch'}, $co{'committer_tz'}); |
| 687 | |
| 688 | my $owner; |
| 689 | if (-f $projects_list) { |
| 690 | open (my $fd , $projects_list); |
| 691 | while (my $line = <$fd>) { |
| 692 | chomp $line; |
| 693 | my ($pr, $ow) = split ':', $line; |
| 694 | if ($pr eq $project) { |
| 695 | $owner = $ow; |
| 696 | last; |
| 697 | } |
| 698 | } |
| 699 | close $fd; |
| 700 | } |
| 701 | if (!defined $owner) { |
| 702 | $owner = get_file_owner("$projectroot/$project"); |
| 703 | } |
| 704 | |
| 705 | git_header_html(); |
| 706 | print "<div class=\"page_nav\">\n" . |
| 707 | $cgi->a({-href => "$my_uri?p=$project;a=log"}, "log") . |
| 708 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree;hb=$head"}, "latest tree") . |
| 709 | "<br/><br/>\n" . |
| 710 | "</div>\n"; |
| 711 | print "<div class=\"title\">project</div>\n"; |
| 712 | print "<div class=\"page_body\">\n" . |
| 713 | "<table cellspacing=\"0\">\n" . |
| 714 | "<tr><td>description</td><td>" . escapeHTML($descr) . "</td></tr>\n" . |
| 715 | "<tr><td>owner</td><td>$owner</td></tr>\n" . |
| 716 | "<tr><td>last change</td><td>$cd{'rfc2822'}</td></tr>\n" . |
| 717 | "</table>\n" . |
| 718 | "</div><br/>\n"; |
| 719 | open my $fd, "-|", "$gitbin/git-rev-list --max-count=11 " . git_read_hash("$project/HEAD") || die_error(undef, "Open failed."); |
| 720 | my (@revlist) = map { chomp; $_ } <$fd>; |
| 721 | close $fd; |
| 722 | print "<div>\n" . |
| 723 | $cgi->a({-href => "$my_uri?p=$project;a=log", -class => "title"}, "recent commits") . |
| 724 | "</div>\n"; |
| 725 | my $i = 10; |
| 726 | foreach my $commit (@revlist) { |
| 727 | my %co = git_read_commit($commit); |
| 728 | my %ad = date_str($co{'author_epoch'}); |
| 729 | print "<div class=\"list\">\n" . |
| 730 | $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit"}, |
| 731 | "<span class=\"log_age\">" . $co{'age_string'} . "</span>" . escapeHTML($co{'title'})) . "\n" . |
| 732 | "</div>\n"; |
| 733 | if (--$i == 0) { |
| 734 | print "<div class=\"list\">" . $cgi->a({-href => "$my_uri?p=$project;a=log"}, "...") . "</div>\n"; |
| 735 | last; |
| 736 | } |
| 737 | } |
| 738 | print "<br/>\n"; |
| 739 | |
| 740 | my $taglist = git_read_tags(); |
| 741 | if (defined @$taglist) { |
| 742 | print "<div>\n" . |
| 743 | $cgi->a({-href => "$my_uri?p=$project;a=tags", -class => "title"}, "recent tags") . |
| 744 | "</div>\n"; |
| 745 | my $i = 10; |
| 746 | foreach my $entry (@$taglist) { |
| 747 | my %tag = %$entry; |
| 748 | print "<div class=\"list\">\n" . |
| 749 | $cgi->a({-href => "$my_uri?p=$project;a=$tag{'type'};h=$tag{'id'}"}, |
| 750 | "<span class=\"log_age\">$tag{'age'}</span>" . escapeHTML($tag{'name'})) . "\n" . |
| 751 | "</div>\n"; |
| 752 | if (--$i == 0) { |
| 753 | print "<div class=\"list\">" . $cgi->a({-href => "$my_uri?p=$project;a=tags"}, "...") . "</div>\n"; |
| 754 | last; |
| 755 | } |
| 756 | } |
| 757 | } |
| 758 | print "<br/>\n"; |
| 759 | git_footer_html(); |
| 760 | } |
| 761 | |
| 762 | sub git_tags { |
| 763 | my $head = git_read_hash("$project/HEAD"); |
| 764 | git_header_html(); |
| 765 | print "<div class=\"page_nav\">\n" . |
| 766 | $cgi->a({-href => "$my_uri?p=$project;a=log"}, "log") . |
| 767 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$head"}, "commit") . |
| 768 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree"}, "tree") . |
| 769 | "<br/><br/>\n" . |
| 770 | "</div>\n"; |
| 771 | my $taglist = git_read_tags(); |
| 772 | print "<div>\n" . |
| 773 | $cgi->a({-href => "$my_uri?p=$project;a=summary", -class => "title"}, "tags") . |
| 774 | "</div>\n"; |
| 775 | if (defined @$taglist) { |
| 776 | foreach my $entry (@$taglist) { |
| 777 | my %tag = %$entry; |
| 778 | print "<div class=\"list\">\n" . |
| 779 | $cgi->a({-href => "$my_uri?p=$project;a=$tag{'type'};h=$tag{'id'}"}, |
| 780 | "<span class=\"log_age\">$tag{'age'}</span>" . escapeHTML($tag{'name'})) . "\n" . |
| 781 | "</div>\n"; |
| 782 | } |
| 783 | } |
| 784 | print "<br/>\n"; |
| 785 | git_footer_html(); |
| 786 | } |
| 787 | |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 788 | sub git_get_hash_by_path { |
| 789 | my $base = shift; |
| 790 | my $path = shift; |
| 791 | |
| 792 | my $tree = $base; |
| 793 | my @parts = split '/', $path; |
| 794 | while (my $part = shift @parts) { |
| 795 | open my $fd, "-|", "$gitbin/git-ls-tree $tree" || die_error(undef, "Open git-ls-tree failed."); |
| 796 | my (@entries) = map { chomp; $_ } <$fd>; |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 797 | close $fd || return undef; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 798 | foreach my $line (@entries) { |
| 799 | #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c' |
| 800 | $line =~ m/^([0-9]+)\t(.*)\t(.*)\t(.*)$/; |
| 801 | my $t_mode = $1; |
| 802 | my $t_type = $2; |
| 803 | my $t_hash = $3; |
| 804 | my $t_name = $4; |
| 805 | if ($t_name eq $part) { |
| 806 | if (!(@parts)) { |
| 807 | return $t_hash; |
| 808 | } |
| 809 | if ($t_type eq "tree") { |
| 810 | $tree = $t_hash; |
| 811 | } |
| 812 | last; |
| 813 | } |
| 814 | } |
| 815 | } |
| 816 | } |
| 817 | |
| 818 | sub git_blob { |
| 819 | if (!defined $hash && defined $file_name) { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 820 | my $base = $hash_base || git_read_hash("$project/HEAD"); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 821 | $hash = git_get_hash_by_path($base, $file_name, "blob"); |
| 822 | } |
| 823 | open my $fd, "-|", "$gitbin/git-cat-file blob $hash" || die_error(undef, "Open failed."); |
| 824 | my $base = $file_name || ""; |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 825 | git_header_html(); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 826 | if (defined $hash_base && (my %co = git_read_commit($hash_base))) { |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 827 | print "<div class=\"page_nav\">\n" . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 828 | $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash_base"}, "commit") . |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 829 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$hash_base"}, "commitdiff") . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 830 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree;h=" . $co{'tree'} . ";hb=$hash_base"}, "tree"); |
| 831 | if (defined $file_name) { |
| 832 | print " | " . $cgi->a({-href => "$my_uri?p=$project;a=history;h=$hash_base;f=$file_name"}, "history"); |
| 833 | } |
| 834 | print "<br/><br/>\n" . |
| 835 | "</div>\n"; |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 836 | print "<div>" . |
| 837 | $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash_base", -class => "title"}, escapeHTML($co{'title'})) . |
| 838 | "</div>\n"; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 839 | } else { |
| 840 | print "<div class=\"page_nav\">\n" . |
| 841 | "<br/><br/></div>\n" . |
| 842 | "<div class=\"title\">$hash</div>\n"; |
| 843 | } |
| 844 | if (defined $file_name) { |
| 845 | print "<div class=\"page_path\">/$file_name</div>\n"; |
| 846 | } |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 847 | print "<div class=\"page_body\">\n"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 848 | my $nr; |
| 849 | while (my $line = <$fd>) { |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 850 | chomp $line; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 851 | $nr++; |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 852 | print "<div class=\"pre\">"; |
| 853 | printf "<span style=\"color:#999999;\">%4i</span>", $nr; |
| 854 | print " " .escapeHTML($line) . "</div>\n"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 855 | } |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 856 | close $fd || print "Reading blob failed.\n"; |
Kay Sievers | fbb592a | 2005-08-07 20:12:11 +0200 | [diff] [blame] | 857 | print "</div>"; |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 858 | git_footer_html(); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 859 | } |
| 860 | |
| 861 | sub git_tree { |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 862 | if (!defined $hash) { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 863 | $hash = git_read_hash("$project/HEAD"); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 864 | if (defined $file_name) { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 865 | my $base = $hash_base || git_read_hash("$project/HEAD"); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 866 | $hash = git_get_hash_by_path($base, $file_name, "tree"); |
| 867 | } |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 868 | } |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 869 | open my $fd, "-|", "$gitbin/git-ls-tree $hash" || die_error(undef, "Open git-ls-tree failed."); |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 870 | my (@entries) = map { chomp; $_ } <$fd>; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 871 | close $fd || die_error(undef, "Reading tree failed."); |
Kay Sievers | d63577d | 2005-08-07 20:18:13 +0200 | [diff] [blame] | 872 | |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 873 | git_header_html(); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 874 | my $base_key = ""; |
| 875 | my $file_key = ""; |
| 876 | my $base = ""; |
| 877 | if (defined $hash_base && (my %co = git_read_commit($hash_base))) { |
| 878 | $base_key = ";hb=$hash_base"; |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 879 | print "<div class=\"page_nav\">\n" . |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 880 | $cgi->a({-href => "$my_uri?p=$project;a=log"}, "log") . |
| 881 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash_base"}, "commit") . |
| 882 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$hash_base"}, "commitdiff") . |
| 883 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree;h=$co{'tree'};hb=$hash_base"}, "tree") . |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 884 | "<br/><br/>\n" . |
| 885 | "</div>\n"; |
Kay Sievers | d63577d | 2005-08-07 20:18:13 +0200 | [diff] [blame] | 886 | print "<div>\n" . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 887 | $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash_base", -class => "title"}, escapeHTML($co{'title'})) . "\n" . |
Kay Sievers | d63577d | 2005-08-07 20:18:13 +0200 | [diff] [blame] | 888 | "</div>\n"; |
| 889 | } else { |
| 890 | print "<div class=\"page_nav\">\n"; |
| 891 | print "<br/><br/></div>\n"; |
| 892 | print "<div class=\"title\">$hash</div>\n"; |
| 893 | } |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 894 | if (defined $file_name) { |
| 895 | $base = "$file_name/"; |
| 896 | print "<div class=\"page_path\">/$file_name</div>\n"; |
| 897 | } else { |
| 898 | print "<div class=\"page_path\">/</div>\n"; |
| 899 | } |
Kay Sievers | fbb592a | 2005-08-07 20:12:11 +0200 | [diff] [blame] | 900 | print "<div class=\"page_body\">\n"; |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 901 | print "<table cellspacing=\"0\">\n"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 902 | foreach my $line (@entries) { |
Kay Sievers | c068cff | 2005-08-07 19:56:10 +0200 | [diff] [blame] | 903 | #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c' |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 904 | $line =~ m/^([0-9]+)\t(.*)\t(.*)\t(.*)$/; |
Kay Sievers | d767d59 | 2005-08-07 20:05:55 +0200 | [diff] [blame] | 905 | my $t_mode = $1; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 906 | my $t_type = $2; |
| 907 | my $t_hash = $3; |
| 908 | my $t_name = $4; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 909 | $file_key = ";f=$base$t_name"; |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 910 | print "<tr>\n" . |
| 911 | "<td class=\"pre\">" . mode_str($t_mode) . "</td>\n"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 912 | if ($t_type eq "blob") { |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 913 | print "<td class=\"pre\">$t_name</td>\n"; |
| 914 | print "<td class=\"link\">" . |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 915 | $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$t_hash" . $base_key . $file_key}, "blob") . |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 916 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=history;h=$hash_base" . $file_key}, "history") . |
| 917 | "</td>\n"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 918 | } elsif ($t_type eq "tree") { |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 919 | print "<td class=\"pre\">" . |
| 920 | $cgi->a({-href => "$my_uri?p=$project;a=tree;h=$t_hash" . $base_key . $file_key}, $t_name) . |
| 921 | "</td>\n"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 922 | } |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 923 | print "</tr>\n"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 924 | } |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 925 | print "</table>\n" . |
| 926 | "</div>"; |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 927 | git_footer_html(); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 928 | } |
| 929 | |
| 930 | sub git_rss { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 931 | open my $fd, "-|", "$gitbin/git-rev-list --max-count=20 " . git_read_hash("$project/HEAD") || die_error(undef, "Open failed."); |
Kay Sievers | d51e902 | 2005-08-07 20:16:07 +0200 | [diff] [blame] | 932 | my (@revlist) = map { chomp; $_ } <$fd>; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 933 | close $fd || die_error(undef, "Reading rev-list failed."); |
Kay Sievers | e334d18 | 2005-08-07 20:02:33 +0200 | [diff] [blame] | 934 | |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 935 | print $cgi->header(-type => 'text/xml', -charset => 'utf-8'); |
| 936 | print "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n". |
| 937 | "<rss version=\"0.91\">\n"; |
| 938 | print "<channel>\n"; |
| 939 | print "<title>$project</title>\n". |
| 940 | "<link> " . $my_url . "/$project/log</link>\n". |
| 941 | "<description>$project log</description>\n". |
| 942 | "<language>en</language>\n"; |
Kay Sievers | e334d18 | 2005-08-07 20:02:33 +0200 | [diff] [blame] | 943 | |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 944 | foreach my $commit (@revlist) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 945 | my %co = git_read_commit($commit); |
Kay Sievers | 185f09e | 2005-08-07 20:13:11 +0200 | [diff] [blame] | 946 | my %ad = date_str($co{'author_epoch'}); |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 947 | print "<item>\n" . |
Kay Sievers | eb28240 | 2005-08-07 20:21:34 +0200 | [diff] [blame] | 948 | "\t<title>" . sprintf("%d %s %02d:%02d", $ad{'mday'}, $ad{'month'}, $ad{'hour'}, $ad{'minute'}) . " - " . escapeHTML($co{'title'}) . "</title>\n" . |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 949 | "\t<link> " . $my_url . "?p=$project;a=commit;h=$commit</link>\n" . |
| 950 | "\t<description>"; |
| 951 | my $comment = $co{'comment'}; |
| 952 | foreach my $line (@$comment) { |
| 953 | print escapeHTML($line) . "<br/>\n"; |
Kay Sievers | a7e09a9 | 2005-08-07 20:00:05 +0200 | [diff] [blame] | 954 | } |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 955 | print "\t</description>\n" . |
| 956 | "</item>\n"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 957 | } |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 958 | print "</channel></rss>"; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 959 | } |
| 960 | |
| 961 | sub git_log { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 962 | my $head = git_read_hash("$project/HEAD"); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 963 | my $limit_option = ""; |
| 964 | if (!defined $time_back) { |
| 965 | $limit_option = "--max-count=10"; |
| 966 | } elsif ($time_back > 0) { |
| 967 | my $date = time - $time_back*24*60*60; |
| 968 | $limit_option = "--max-age=$date"; |
| 969 | } |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 970 | open my $fd, "-|", "$gitbin/git-rev-list $limit_option $head" || die_error(undef, "Open failed."); |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 971 | my (@revlist) = map { chomp; $_ } <$fd>; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 972 | close $fd || die_error(undef, "Reading rev-list failed."); |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 973 | |
| 974 | git_header_html(); |
| 975 | print "<div class=\"page_nav\">\n"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 976 | print $cgi->a({-href => "$my_uri?p=$project;a=log"}, "last 10") . " | " . |
| 977 | $cgi->a({-href => "$my_uri?p=$project;a=log;t=1"}, "day") . " | " . |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 978 | $cgi->a({-href => "$my_uri?p=$project;a=log;t=7"}, "week") . " | " . |
| 979 | $cgi->a({-href => "$my_uri?p=$project;a=log;t=31"}, "month") . " | " . |
| 980 | $cgi->a({-href => "$my_uri?p=$project;a=log;t=365"}, "year") . " | " . |
| 981 | $cgi->a({-href => "$my_uri?p=$project;a=log;t=0"}, "all") . "<br/>\n"; |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 982 | print "<br/>\n" . |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 983 | "</div>\n"; |
| 984 | |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 985 | if (!@revlist) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 986 | my %co = git_read_commit($head); |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 987 | print "<div class=\"page_body\"> Last change " . $co{'age_string'} . ".<br/><br/></div>\n"; |
| 988 | } |
| 989 | |
| 990 | foreach my $commit (@revlist) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 991 | my %co = git_read_commit($commit); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 992 | next if !%co; |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 993 | my %ad = date_str($co{'author_epoch'}); |
| 994 | print "<div>\n" . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 995 | $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "title"}, |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 996 | "<span class=\"log_age\">" . $co{'age_string'} . "</span>" . escapeHTML($co{'title'})) . "\n" . |
| 997 | "</div>\n"; |
| 998 | print "<div class=\"title_text\">\n" . |
| 999 | "<div class=\"log_link\">\n" . |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1000 | $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit"}, "commit") . |
| 1001 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$commit"}, "commitdiff") . |
Kay Sievers | eb28240 | 2005-08-07 20:21:34 +0200 | [diff] [blame] | 1002 | "<br/>\n" . |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 1003 | "</div>\n" . |
| 1004 | "<i>" . escapeHTML($co{'author_name'}) . " [" . $ad{'rfc2822'} . "]</i><br/>\n" . |
| 1005 | "</div>\n" . |
| 1006 | "<div class=\"log_body\">\n"; |
| 1007 | my $comment = $co{'comment'}; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1008 | my $empty = 0; |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 1009 | foreach my $line (@$comment) { |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1010 | if ($line =~ m/^(signed[ \-]off[\-]by[ :]|acked[\-]by[ \:]|cc[ :])/i) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1011 | next; |
| 1012 | } |
| 1013 | if ($line eq "") { |
| 1014 | if ($empty) { |
| 1015 | next; |
| 1016 | } |
| 1017 | $empty = 1; |
| 1018 | } else { |
| 1019 | $empty = 0; |
| 1020 | } |
| 1021 | print escapeHTML($line) . "<br/>\n"; |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 1022 | } |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1023 | if (!$empty) { |
| 1024 | print "<br/>\n"; |
| 1025 | } |
| 1026 | print "</div>\n"; |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 1027 | } |
| 1028 | git_footer_html(); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1029 | } |
| 1030 | |
| 1031 | sub git_commit { |
| 1032 | my %co = git_read_commit($hash); |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 1033 | if (!%co) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1034 | die_error(undef, "Unknown commit object."); |
Kay Sievers | d63577d | 2005-08-07 20:18:13 +0200 | [diff] [blame] | 1035 | } |
Kay Sievers | 185f09e | 2005-08-07 20:13:11 +0200 | [diff] [blame] | 1036 | my %ad = date_str($co{'author_epoch'}, $co{'author_tz'}); |
| 1037 | my %cd = date_str($co{'committer_epoch'}, $co{'committer_tz'}); |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 1038 | |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 1039 | my @difftree; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1040 | if (defined $co{'parent'}) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1041 | open my $fd, "-|", "$gitbin/git-diff-tree -r " . $co{'parent'} . " $hash" || die_error(undef, "Open failed."); |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 1042 | @difftree = map { chomp; $_ } <$fd>; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1043 | close $fd || die_error(undef, "Reading diff-tree failed."); |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 1044 | } else { |
| 1045 | # fake git-diff-tree output for initial revision |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1046 | open my $fd, "-|", "$gitbin/git-ls-tree -r $hash" || die_error(undef, "Open failed."); |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 1047 | @difftree = map { chomp; "+" . $_ } <$fd>; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1048 | close $fd || die_error(undef, "Reading ls-tree failed."); |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 1049 | } |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 1050 | git_header_html(); |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1051 | print "<div class=\"page_nav\">\n" . |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 1052 | $cgi->a({-href => "$my_uri?p=$project;a=log"}, "log") . |
| 1053 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash"}, "commit"); |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1054 | if (defined $co{'parent'}) { |
| 1055 | print " | " . $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$hash"}, "commitdiff"); |
| 1056 | } |
| 1057 | print " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree;h=" . $co{'tree'} . ";hb=$hash"}, "tree") . "\n" . |
Kay Sievers | ff7669a | 2005-08-07 20:13:02 +0200 | [diff] [blame] | 1058 | "<br/><br/></div>\n"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1059 | if (defined $co{'parent'}) { |
| 1060 | print "<div>\n" . |
| 1061 | $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$hash", -class => "title"}, escapeHTML($co{'title'})) . "\n" . |
| 1062 | "</div>\n"; |
| 1063 | } else { |
| 1064 | print "<div>\n" . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1065 | $cgi->a({-href => "$my_uri?p=$project;a=tree;h=" . $co{'tree'} . ";hb=$hash", -class => "title"}, escapeHTML($co{'title'})) . "\n" . |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1066 | "</div>\n"; |
| 1067 | } |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 1068 | print "<div class=\"title_text\">\n" . |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1069 | "<table cellspacing=\"0\">\n"; |
| 1070 | print "<tr><td>author</td><td>" . escapeHTML($co{'author'}) . "</td></tr>\n". |
| 1071 | "<tr><td></td><td> " . $ad{'rfc2822'}; |
Kay Sievers | 927dcec | 2005-08-07 20:18:44 +0200 | [diff] [blame] | 1072 | if ($ad{'hour_local'} < 6) { |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1073 | printf(" (<span style=\"color: #cc0000;\">%02d:%02d</span> %s)", $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'}); |
| 1074 | } else { |
| 1075 | printf(" (%02d:%02d %s)", $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'}); |
Kay Sievers | 927dcec | 2005-08-07 20:18:44 +0200 | [diff] [blame] | 1076 | } |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1077 | print "</td></tr>\n"; |
| 1078 | print "<tr><td>committer</td><td>" . escapeHTML($co{'committer'}) . "</td></tr>\n"; |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1079 | print "<tr><td></td><td> " . $cd{'rfc2822'} . sprintf(" (%02d:%02d %s)", $cd{'hour_local'}, $cd{'minute_local'}, $cd{'tz_local'}) . "</td></tr>\n"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1080 | print "<tr><td>commit</td><td style=\"font-family: monospace;\">$hash</td></tr>\n"; |
| 1081 | print "<tr><td>tree</td><td style=\"font-family: monospace;\">" . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1082 | $cgi->a({-href => "$my_uri?p=$project;a=tree;h=" . $co{'tree'} . ";hb=" . $hash}, $co{'tree'}) . "</td></tr>\n"; |
Kay Sievers | 3e02929 | 2005-08-07 20:05:15 +0200 | [diff] [blame] | 1083 | my $parents = $co{'parents'}; |
| 1084 | foreach my $par (@$parents) { |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1085 | print "<tr><td>parent</td><td style=\"font-family: monospace;\">" . |
| 1086 | $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$par"}, $par) . "</td></tr>\n"; |
Kay Sievers | 3e02929 | 2005-08-07 20:05:15 +0200 | [diff] [blame] | 1087 | } |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1088 | print "</table>". |
| 1089 | "</div>\n"; |
Kay Sievers | fbb592a | 2005-08-07 20:12:11 +0200 | [diff] [blame] | 1090 | print "<div class=\"page_body\">\n"; |
Kay Sievers | 3e02929 | 2005-08-07 20:05:15 +0200 | [diff] [blame] | 1091 | my $comment = $co{'comment'}; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1092 | my $empty = 0; |
| 1093 | my $signed = 0; |
Kay Sievers | 3e02929 | 2005-08-07 20:05:15 +0200 | [diff] [blame] | 1094 | foreach my $line (@$comment) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1095 | # print only one empty line |
| 1096 | if ($line eq "") { |
| 1097 | if ($empty || $signed) { |
| 1098 | next; |
| 1099 | } |
| 1100 | $empty = 1; |
| 1101 | } else { |
| 1102 | $empty = 0; |
| 1103 | } |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1104 | if ($line =~ m/^(signed[ \-]off[\-]by[ :]|acked[\-]by[ \:]|cc[ :])/i) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1105 | $signed = 1; |
Kay Sievers | 927dcec | 2005-08-07 20:18:44 +0200 | [diff] [blame] | 1106 | print "<span style=\"color: #888888\">" . escapeHTML($line) . "</span><br/>\n"; |
Kay Sievers | 3e02929 | 2005-08-07 20:05:15 +0200 | [diff] [blame] | 1107 | } else { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1108 | $signed = 0; |
Kay Sievers | 3e02929 | 2005-08-07 20:05:15 +0200 | [diff] [blame] | 1109 | print escapeHTML($line) . "<br/>\n"; |
| 1110 | } |
| 1111 | } |
Kay Sievers | 927dcec | 2005-08-07 20:18:44 +0200 | [diff] [blame] | 1112 | print "</div>\n"; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1113 | print "<div class=\"list_head\">\n"; |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 1114 | if ($#difftree > 10) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1115 | print(($#difftree + 1) . " files changed:\n"); |
Kay Sievers | 6191f8e | 2005-08-07 20:19:56 +0200 | [diff] [blame] | 1116 | } |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1117 | print "</div>\n"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 1118 | foreach my $line (@difftree) { |
Kay Sievers | c068cff | 2005-08-07 19:56:10 +0200 | [diff] [blame] | 1119 | # '*100644->100644 blob 9f91a116d91926df3ba936a80f020a6ab1084d2b->bb90a0c3a91eb52020d0db0e8b4f94d30e02d596 net/ipv4/route.c' |
| 1120 | # '+100644 blob 4a83ab6cd565d21ab0385bac6643826b83c2fcd4 arch/arm/lib/bitops.h' |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 1121 | # '*100664->100644 blob b1a8e3dd5556b61dd771d32307c6ee5d7150fa43->b1a8e3dd5556b61dd771d32307c6ee5d7150fa43 show-files.c' |
| 1122 | # '*100664->100644 blob d08e895238bac36d8220586fdc28c27e1a7a76d3->d08e895238bac36d8220586fdc28c27e1a7a76d3 update-cache.c' |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 1123 | $line =~ m/^(.)(.*)\t(.*)\t(.*)\t(.*)$/; |
| 1124 | my $op = $1; |
| 1125 | my $mode = $2; |
| 1126 | my $type = $3; |
| 1127 | my $id = $4; |
| 1128 | my $file = $5; |
| 1129 | if ($type eq "blob") { |
| 1130 | if ($op eq "+") { |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1131 | my $mode_chng = ""; |
| 1132 | if (S_ISREG(oct $mode)) { |
| 1133 | $mode_chng = sprintf(" with mode: %04o", (oct $mode) & 0777); |
| 1134 | } |
Kay Sievers | 927dcec | 2005-08-07 20:18:44 +0200 | [diff] [blame] | 1135 | print "<div class=\"list\">\n" . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1136 | $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$id;hb=$hash;f=$file"}, |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1137 | escapeHTML($file) . " <span style=\"color: #008000;\">[new " . file_type($mode) . $mode_chng . "]</span>") . "\n" . |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1138 | "</div>\n"; |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 1139 | print "<div class=\"list_link\">\n" . |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1140 | $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$id;hb=$hash;f=$file"}, "blob") . "\n" . |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 1141 | "</div>\n"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 1142 | } elsif ($op eq "-") { |
Kay Sievers | 927dcec | 2005-08-07 20:18:44 +0200 | [diff] [blame] | 1143 | print "<div class=\"list\">\n" . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1144 | $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$id;hb=$hash;f=$file"}, |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 1145 | escapeHTML($file) . " <span style=\"color: #c00000;\">[deleted " . file_type($mode) . "]</span>") . "\n" . |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 1146 | "</div>"; |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 1147 | print "<div class=\"list_link\">\n" . |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1148 | $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$id;hb=$hash;f=$file"}, "blob") . " | " . |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1149 | $cgi->a({-href => "$my_uri?p=$project;a=history;h=$hash;f=$file"}, "history") . "\n" . |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 1150 | "</div>\n"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 1151 | } elsif ($op eq "*") { |
| 1152 | $id =~ m/([0-9a-fA-F]+)->([0-9a-fA-F]+)/; |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 1153 | my $from_id = $1; |
| 1154 | my $to_id = $2; |
| 1155 | $mode =~ m/^([0-7]{6})->([0-7]{6})$/; |
| 1156 | my $from_mode = $1; |
| 1157 | my $to_mode = $2; |
Kay Sievers | d63577d | 2005-08-07 20:18:13 +0200 | [diff] [blame] | 1158 | my $mode_chnge = ""; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1159 | if ($from_mode != $to_mode) { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 1160 | $mode_chnge = " <span style=\"color: #777777;\">[changed"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1161 | if (((oct $from_mode) & S_IFMT) != ((oct $to_mode) & S_IFMT)) { |
| 1162 | $mode_chnge .= " from " . file_type($from_mode) . " to " . file_type($to_mode); |
| 1163 | } |
| 1164 | if (((oct $from_mode) & 0777) != ((oct $to_mode) & 0777)) { |
| 1165 | if (S_ISREG($from_mode) && S_ISREG($to_mode)) { |
| 1166 | $mode_chnge .= sprintf(" mode: %04o->%04o", (oct $from_mode) & 0777, (oct $to_mode) & 0777); |
| 1167 | } elsif (S_ISREG($to_mode)) { |
| 1168 | $mode_chnge .= sprintf(" mode: %04o", (oct $to_mode) & 0777); |
| 1169 | } |
| 1170 | } |
| 1171 | $mode_chnge .= "]</span>\n"; |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 1172 | } |
Kay Sievers | 2bb7c6d | 2005-08-07 20:19:45 +0200 | [diff] [blame] | 1173 | print "<div class=\"list\">\n"; |
| 1174 | if ($to_id ne $from_id) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1175 | print $cgi->a({-href => "$my_uri?p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file"}, |
Kay Sievers | 2bb7c6d | 2005-08-07 20:19:45 +0200 | [diff] [blame] | 1176 | escapeHTML($file) . $mode_chnge) . "\n" . |
| 1177 | "</div>\n"; |
| 1178 | } else { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1179 | print $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$to_id;hb=$hash;f=$file"}, |
Kay Sievers | 2bb7c6d | 2005-08-07 20:19:45 +0200 | [diff] [blame] | 1180 | escapeHTML($file) . $mode_chnge) . "\n" . |
| 1181 | "</div>\n"; |
| 1182 | } |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 1183 | print "<div class=\"list_link\">\n"; |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 1184 | if ($to_id ne $from_id) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1185 | print $cgi->a({-href => "$my_uri?p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file"}, "diff") . " | "; |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 1186 | } |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1187 | print $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$to_id;hb=$hash;f=$file"}, "blob") . " | " . |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1188 | $cgi->a({-href => "$my_uri?p=$project;a=history;h=$hash;f=$file"}, "history") . "\n" . |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 1189 | "</div>\n"; |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 1190 | } |
| 1191 | } |
| 1192 | } |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 1193 | git_footer_html(); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1194 | } |
| 1195 | |
| 1196 | sub git_blobdiff { |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1197 | mkdir($gittmp, 0700); |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 1198 | git_header_html(); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1199 | if (defined $hash_base && (my %co = git_read_commit($hash_base))) { |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1200 | print "<div class=\"page_nav\">\n" . |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 1201 | $cgi->a({-href => "$my_uri?p=$project;a=log"}, "log") . |
| 1202 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash_base"}, "commit") . |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1203 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$hash_base"}, "commitdiff") . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1204 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree;h=" . $co{'tree'} . ";hb=$hash_base"}, "tree"); |
| 1205 | if (defined $file_name) { |
| 1206 | print " | " . $cgi->a({-href => "$my_uri?p=$project;a=history;h=$hash_base;f=$file_name"}, "history"); |
| 1207 | } |
| 1208 | print "<br/><br/>\n" . |
| 1209 | "</div>\n"; |
| 1210 | print "<div>\n" . |
| 1211 | $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash_base", -class => "title"}, escapeHTML($co{'title'})) . "\n" . |
| 1212 | "</div>\n"; |
| 1213 | } else { |
| 1214 | print "<div class=\"page_nav\">\n" . |
| 1215 | "<br/><br/></div>\n" . |
| 1216 | "<div class=\"title\">$hash vs $hash_parent</div>\n"; |
| 1217 | } |
| 1218 | if (defined $file_name) { |
| 1219 | print "<div class=\"page_path\">\n" . |
| 1220 | "/$file_name\n" . |
| 1221 | "</div>\n"; |
| 1222 | } |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 1223 | print "<div class=\"page_body\">\n" . |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1224 | "<div class=\"diff_info\">blob:" . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1225 | $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$hash_parent;hb=$hash_base;f=$file_name"}, $hash_parent) . |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 1226 | " -> blob:" . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1227 | $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name"}, $hash) . |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1228 | "</div>\n"; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1229 | git_diff_html($hash_parent, $file_name || $hash_parent, $hash, $file_name || $hash); |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1230 | print "</div>"; |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 1231 | git_footer_html(); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1232 | } |
| 1233 | |
| 1234 | sub git_commitdiff { |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1235 | mkdir($gittmp, 0700); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1236 | my %co = git_read_commit($hash); |
Kay Sievers | 034df39 | 2005-08-07 20:20:07 +0200 | [diff] [blame] | 1237 | if (!%co) { |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1238 | die_error(undef, "Unknown commit object."); |
Kay Sievers | d63577d | 2005-08-07 20:18:13 +0200 | [diff] [blame] | 1239 | } |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1240 | open my $fd, "-|", "$gitbin/git-diff-tree -r " . $co{'parent'} . " $hash" || die_error(undef, "Open failed."); |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 1241 | my (@difftree) = map { chomp; $_ } <$fd>; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1242 | close $fd || die_error(undef, "Reading diff-tree failed."); |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 1243 | |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 1244 | git_header_html(); |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1245 | print "<div class=\"page_nav\">\n" . |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 1246 | $cgi->a({-href => "$my_uri?p=$project;a=log"}, "log") . |
| 1247 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash"}, "commit") . |
| 1248 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$hash"}, "commitdiff") . |
| 1249 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree;h=" . $co{'tree'} . ";hb=$hash"}, "tree") . |
Kay Sievers | ff7669a | 2005-08-07 20:13:02 +0200 | [diff] [blame] | 1250 | "<br/><br/></div>\n"; |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 1251 | print "<div>\n" . |
Kay Sievers | 927dcec | 2005-08-07 20:18:44 +0200 | [diff] [blame] | 1252 | $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash", -class => "title"}, escapeHTML($co{'title'})) . "\n" . |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 1253 | "</div>\n"; |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1254 | print "<div class=\"page_body\">\n"; |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 1255 | foreach my $line (@difftree) { |
Kay Sievers | c068cff | 2005-08-07 19:56:10 +0200 | [diff] [blame] | 1256 | # '*100644->100644 blob 8e5f9bbdf4de94a1bc4b4da8cb06677ce0a57716->8da3a306d0c0c070d87048d14a033df02f40a154 Makefile' |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 1257 | $line =~ m/^(.)(.*)\t(.*)\t(.*)\t(.*)$/; |
| 1258 | my $op = $1; |
| 1259 | my $mode = $2; |
| 1260 | my $type = $3; |
| 1261 | my $id = $4; |
| 1262 | my $file = $5; |
| 1263 | if ($type eq "blob") { |
| 1264 | if ($op eq "+") { |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1265 | print "<div class=\"diff_info\">" . file_type($mode) . ":" . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1266 | $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$id;hb=$hash;f=$file"}, $id) . "(new)" . |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1267 | "</div>\n"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1268 | git_diff_html(undef, "/dev/null", $id, "b/$file"); |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 1269 | } elsif ($op eq "-") { |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1270 | print "<div class=\"diff_info\">" . file_type($mode) . ":" . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1271 | $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$id;hb=$hash;f=$file"}, $id) . "(deleted)" . |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1272 | "</div>\n"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1273 | git_diff_html($id, "a/$file", undef, "/dev/null"); |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 1274 | } elsif ($op eq "*") { |
| 1275 | $id =~ m/([0-9a-fA-F]+)->([0-9a-fA-F]+)/; |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 1276 | my $from_id = $1; |
| 1277 | my $to_id = $2; |
| 1278 | $mode =~ m/([0-7]+)->([0-7]+)/; |
| 1279 | my $from_mode = $1; |
| 1280 | my $to_mode = $2; |
| 1281 | if ($from_id ne $to_id) { |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1282 | print "<div class=\"diff_info\">" . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1283 | file_type($from_mode) . ":" . $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$from_id;hb=$hash;f=$file"}, $from_id) . |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 1284 | " -> " . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1285 | file_type($to_mode) . ":" . $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$to_id;hb=$hash;f=$file"}, $to_id); |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1286 | print "</div>\n"; |
Kay Sievers | 2735983 | 2005-08-07 20:20:20 +0200 | [diff] [blame] | 1287 | git_diff_html($from_id, "a/$file", $to_id, "b/$file"); |
Kay Sievers | 9cd3d98 | 2005-08-07 20:17:42 +0200 | [diff] [blame] | 1288 | } |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 1289 | } |
| 1290 | } |
Kay Sievers | 4c02e3c | 2005-08-07 19:52:52 +0200 | [diff] [blame] | 1291 | } |
Kay Sievers | c07ad4b | 2005-08-07 20:22:44 +0200 | [diff] [blame] | 1292 | print "<br/>\n" . |
| 1293 | "</div>"; |
Kay Sievers | 12a88f2 | 2005-08-07 20:02:47 +0200 | [diff] [blame] | 1294 | git_footer_html(); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1295 | } |
| 1296 | |
| 1297 | sub git_history { |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1298 | if (!defined $hash) { |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 1299 | $hash = git_read_hash("$project/HEAD"); |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1300 | } |
| 1301 | my %co = git_read_commit($hash); |
| 1302 | if (!%co) { |
| 1303 | die_error(undef, "Unknown commit object."); |
Kay Sievers | 2ae100d | 2005-08-07 20:17:00 +0200 | [diff] [blame] | 1304 | } |
Kay Sievers | d51e902 | 2005-08-07 20:16:07 +0200 | [diff] [blame] | 1305 | git_header_html(); |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1306 | print "<div class=\"page_nav\">\n" . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1307 | $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash"}, "commit") . " | " . |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1308 | $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$hash"}, "commitdiff") . " | " . |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1309 | $cgi->a({-href => "$my_uri?p=$project;a=tree;h=" . $co{'tree'} . ";hb=$hash"}, "tree") . |
| 1310 | "<br/><br/>\n" . |
Kay Sievers | 820e4f6 | 2005-08-07 20:17:50 +0200 | [diff] [blame] | 1311 | "</div>\n"; |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1312 | print "<div>\n" . |
| 1313 | $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash", -class => "title"}, escapeHTML($co{'title'})) . "\n" . |
| 1314 | "</div>\n"; |
| 1315 | print "<div class=\"page_path\">\n" . |
| 1316 | "/$file_name<br/>\n"; |
| 1317 | print "</div>\n"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1318 | open my $fd, "-|", "$gitbin/git-rev-list $hash | $gitbin/git-diff-tree -r --stdin $file_name"; |
| 1319 | my $commit; |
| 1320 | while (my $line = <$fd>) { |
| 1321 | if ($line =~ m/^([0-9a-fA-F]{40}) /){ |
| 1322 | $commit = $1; |
| 1323 | next; |
Kay Sievers | d51e902 | 2005-08-07 20:16:07 +0200 | [diff] [blame] | 1324 | } |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1325 | if ($line =~ m/^(.)(.*)\t(.*)\t(.*)\t(.*)$/ && (defined $commit)) { |
| 1326 | my $type = $3; |
| 1327 | my $file = $5; |
| 1328 | if ($file ne $file_name || $type ne "blob") { |
| 1329 | next; |
| 1330 | } |
Kay Sievers | 09bd789 | 2005-08-07 20:21:23 +0200 | [diff] [blame] | 1331 | my %co = git_read_commit($commit); |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1332 | if (!%co) { |
| 1333 | next; |
| 1334 | } |
Kay Sievers | 927dcec | 2005-08-07 20:18:44 +0200 | [diff] [blame] | 1335 | print "<div class=\"list\">\n" . |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1336 | $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit"}, |
Kay Sievers | 1207151 | 2005-08-07 20:18:01 +0200 | [diff] [blame] | 1337 | "<span class=\"log_age\">" . $co{'age_string'} . "</span>" . escapeHTML($co{'title'})) . "\n" . |
Kay Sievers | 334538f | 2005-08-07 20:18:30 +0200 | [diff] [blame] | 1338 | "</div>\n"; |
Kay Sievers | ede5e10 | 2005-08-07 20:23:12 +0200 | [diff] [blame^] | 1339 | print "<div class=\"list_link\">\n" . |
Kay Sievers | eb28240 | 2005-08-07 20:21:34 +0200 | [diff] [blame] | 1340 | $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit"}, "commit") . |
| 1341 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree;h=" . $co{'tree'} . ";hb=$commit"}, "tree") . |
Kay Sievers | 42f7eb9 | 2005-08-07 20:21:46 +0200 | [diff] [blame] | 1342 | " | " . $cgi->a({-href => "$my_uri?p=$project;a=blob;hb=$commit;f=" . $file}, "blob"); |
| 1343 | my $blob = git_get_hash_by_path($hash, $file_name); |
| 1344 | my $blob_parent = git_get_hash_by_path($commit, $file_name); |
| 1345 | if (defined $blob && defined $blob_parent && $blob ne $blob_parent) { |
| 1346 | print " | " . $cgi->a({-href => "$my_uri?p=$project;a=blobdiff;h=$blob;hp=$blob_parent;hb=$commit;f=" . $file}, "diff"); |
| 1347 | } |
| 1348 | print "<br/>\n" . |
Kay Sievers | 820e4f6 | 2005-08-07 20:17:50 +0200 | [diff] [blame] | 1349 | "</div>\n"; |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1350 | undef $commit; |
Kay Sievers | 2ae100d | 2005-08-07 20:17:00 +0200 | [diff] [blame] | 1351 | } |
Kay Sievers | d51e902 | 2005-08-07 20:16:07 +0200 | [diff] [blame] | 1352 | } |
Kay Sievers | b87d78d | 2005-08-07 20:21:04 +0200 | [diff] [blame] | 1353 | close $fd; |
Kay Sievers | d51e902 | 2005-08-07 20:16:07 +0200 | [diff] [blame] | 1354 | git_footer_html(); |
Kay Sievers | 161332a | 2005-08-07 19:49:46 +0200 | [diff] [blame] | 1355 | } |