{"thread":{"id":"968","subject":"gitweb and tar snapshots","startedAt":"2005-06-18T11:31:21Z","lastAt":"2005-06-18T11:31:21Z","messageCount":1,"participants":["Sven Verdoolaege"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"5016","messageId":"20050618113121.GA13122@pc117b.liacs.nl","threadId":"968","inReplyTo":null,"subject":"gitweb and tar snapshots","fromName":"Sven Verdoolaege","fromEmail":"skimo@liacs.nl","sentAt":"2005-06-18T11:31:21Z","receivedAt":"2005-06-18T11:31:21Z","isPatch":false,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"Attached two patches.\n\nThe first factors out the generation of the navigation bar.\nThe second, which depends on the first, adds \"snapshot\" to\nthe navigation bar.\n\nThe patches are against (a slightly modified) version 222.\n\nskimo\n\n\ndiff --git a/gitweb.cgi b/gitweb.cgi\n--- a/gitweb.cgi\n+++ b/gitweb.cgi\n@@ -283,6 +283,27 @@ EOF\n \tprint \"</div>\\n\";\n }\n \n+sub git_page_nav {\n+\tmy ($current, $suppress, $head, $treehead, $treebase, $extra) = @_;\n+\t$extra = '' if !defined $extra;\n+\tmy @navs = qw(summary shortlog log commit commitdiff tree);\n+\tmy %arg = map { $_, ''} @navs;\n+\tif (defined $head) {\n+\t\tfor (qw(shortlog log commit commitdiff)) {\n+\t\t\t$arg{$_} = \";h=$head\";\n+\t\t}\n+\t}\n+\t$arg{tree} .= \";h=$treehead\" if defined $treehead;\n+\t$arg{tree} .= \";hb=$treebase\" if defined $treebase;\n+\n+\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n+\t\t(join \" | \", map { $_ eq $current ? $_ :\n+\t\t\t$cgi->a({-href => \"$my_uri?p=$project;a=$_$arg{$_}\"}, \"$_\") }\n+\t\t\tgrep { $_ ne $suppress } @navs) .\n+\t      \"<br/>$extra<br/>\\n\" .\n+\t      \"</div>\\n\";\n+}\n+\n sub git_footer_html {\n \tprint \"<div class=\\\"page_footer\\\">\\n\";\n \tif (defined $project) {\n@@ -816,15 +837,7 @@ sub git_summary {\n \t}\n \n \tgit_header_html();\n-\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n-\t      \"summary\".\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=shortlog\"}, \"shortlog\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=log\"}, \"log\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$head\"}, \"commit\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commitdiff;h=$head\"}, \"commitdiff\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=tree\"}, \"tree\") .\n-\t      \"<br/><br/>\\n\" .\n-\t      \"</div>\\n\";\n+\tgit_page_nav('summary', '', $head);\n \tprint \"<div class=\\\"title\\\">&nbsp;</div>\\n\";\n \tprint \"<table cellspacing=\\\"0\\\">\\n\" .\n \t      \"<tr><td>description</td><td>\" . escapeHTML($descr) . \"</td></tr>\\n\" .\n@@ -949,15 +962,7 @@ sub git_summary {\n sub git_tags {\n \tmy $head = git_read_hash(\"$project/HEAD\");\n \tgit_header_html();\n-\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n-\t      $cgi->a({-href => \"$my_uri?p=$project;a=summary\"}, \"summary\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=shortlog\"}, \"shortlog\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=log\"}, \"log\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$head\"}, \"commit\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commitdiff;h=$head\"}, \"commitdiff\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=tree;hb=$head\"}, \"tree\") . \"<br/>\\n\" .\n-\t      \"<br/>\\n\" .\n-\t      \"</div>\\n\";\n+\tgit_page_nav('', '', $head, undef, $head);\n \tmy $taglist = git_read_refs(\"refs/tags\");\n \tprint \"<div>\\n\" .\n \t      $cgi->a({-href => \"$my_uri?p=$project;a=summary\", -class => \"title\"}, \"&nbsp;\") .\n@@ -995,15 +1000,7 @@ sub git_tags {\n sub git_branches {\n \tmy $head = git_read_hash(\"$project/HEAD\");\n \tgit_header_html();\n-\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n-\t      $cgi->a({-href => \"$my_uri?p=$project;a=summary\"}, \"summary\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=shortlog\"}, \"shortlog\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=log\"}, \"log\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$head\"}, \"commit\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commitdiff;h=$head\"}, \"commitdiff\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=tree;hb=$head\"}, \"tree\") . \"<br/>\\n\" .\n-\t      \"<br/>\\n\" .\n-\t      \"</div>\\n\";\n+\tgit_page_nav('', '', $head, undef, $head);\n \tmy $taglist = git_read_refs(\"refs/heads\");\n \tprint \"<div>\\n\" .\n \t      $cgi->a({-href => \"$my_uri?p=$project;a=summary\", -class => \"title\"}, \"&nbsp;\") .\n@@ -1073,15 +1070,9 @@ sub git_blob {\n \tmy $base = $file_name || \"\";\n \tgit_header_html();\n \tif (defined $hash_base && (my %co = git_read_commit($hash_base))) {\n-\t\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n-\t\t      $cgi->a({-href => \"$my_uri?p=$project;a=summary\"}, \"summary\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=shortlog\"}, \"shortlog\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=log\"}, \"log\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash_base\"}, \"commit\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commitdiff;h=$hash_base\"}, \"commitdiff\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=tree;h=$co{'tree'};hb=$hash_base\"}, \"tree\") . \"<br/>\\n\";\n-\t\tprint $cgi->a({-href => \"$my_uri?p=$project;a=blob_plain;h=$hash\"}, \"plain\") . \"<br/>\\n\" .\n-\t\t      \"</div>\\n\";\n+\t\tgit_page_nav('', '', $hash_base, $co{'tree'}, $hash_base,\n+\t\t\t$cgi->a({-href => \"$my_uri?p=$project;a=blob_plain;h=$hash\"}, \"plain\")\n+\t\t);\n \t\tprint \"<div>\" .\n \t\t      $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash_base\", -class => \"title\"}, escapeHTML($co{'title'})) .\n \t\t      \"</div>\\n\";\n@@ -1141,15 +1132,7 @@ sub git_tree {\n \tmy $base = \"\";\n \tif (defined $hash_base && (my %co = git_read_commit($hash_base))) {\n \t\t$base_key = \";hb=$hash_base\";\n-\t\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n-\t\t      $cgi->a({-href => \"$my_uri?p=$project;a=summary\"}, \"summary\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=shortlog;h=$hash_base\"}, \"shortlog\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=log;h=$hash_base\"}, \"log\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash_base\"}, \"commit\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commitdiff;h=$hash_base\"}, \"commitdiff\") .\n-\t\t      \" | tree\" .\n-\t\t      \"<br/><br/>\\n\" .\n-\t\t      \"</div>\\n\";\n+\t\tgit_page_nav('tree', '', $hash_base);\n \t\tprint \"<div>\\n\" .\n \t\t      $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash_base\", -class => \"title\"}, escapeHTML($co{'title'})) . \"\\n\" .\n \t\t      \"</div>\\n\";\n@@ -1286,38 +1269,30 @@ sub git_log {\n \t\t$page = 0;\n \t}\n \tgit_header_html();\n-\tprint \"<div class=\\\"page_nav\\\">\\n\";\n-\tprint $cgi->a({-href => \"$my_uri?p=$project;a=summary\"}, \"summary\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=shortlog;h=$hash\"}, \"shortlog\") .\n-\t      \" | log\" .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash\"}, \"commit\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commitdiff;h=$hash\"}, \"commitdiff\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=tree;h=$hash;hb=$hash\"}, \"tree\") . \"<br/>\\n\";\n-\n+\tmy $extra = '';\n \tmy $limit = sprintf(\"--max-count=%i\", (100 * ($page+1)));\n \topen my $fd, \"-|\", \"$gitbin/git-rev-list $limit $hash\" or die_error(undef, \"Open failed.\");\n \tmy (@revlist) = map { chomp; $_ } <$fd>;\n \tclose $fd;\n \n \tif ($hash ne $head || $page) {\n-\t\tprint $cgi->a({-href => \"$my_uri?p=$project;a=log\"}, \"HEAD\");\n+\t\t$extra .= $cgi->a({-href => \"$my_uri?p=$project;a=log\"}, \"HEAD\");\n \t} else {\n-\t\tprint \"HEAD\";\n+\t\t$extra .= \"HEAD\";\n \t}\n \tif ($page > 0) {\n-\t\tprint \" &sdot; \" .\n+\t\t$extra .= \" &sdot; \" .\n \t\t$cgi->a({-href => \"$my_uri?p=$project;a=log;h=$hash;pg=\" . ($page-1), -accesskey => \"p\", -title => \"Alt-p\"}, \"prev\");\n \t} else {\n-\t\tprint \" &sdot; prev\";\n+\t\t$extra .= \" &sdot; prev\";\n \t}\n \tif ($#revlist >= (100 * ($page+1)-1)) {\n-\t\tprint \" &sdot; \" .\n+\t\t$extra .= \" &sdot; \" .\n \t\t$cgi->a({-href => \"$my_uri?p=$project;a=log;h=$hash;pg=\" . ($page+1), -accesskey => \"n\", -title => \"Alt-n\"}, \"next\");\n \t} else {\n-\t\tprint \" &sdot; next\";\n+\t\t$extra .= \" &sdot; next\";\n \t}\n-\tprint \"<br/>\\n\" .\n-\t      \"</div>\\n\";\n+\tgit_page_nav('log', '', $hash, $hash, $hash, $extra);\n \tif (!@revlist) {\n \t\tprint \"<div>\\n\" .\n \t\t      $cgi->a({-href => \"$my_uri?p=$project;a=summary\", -class => \"title\"}, \"&nbsp;\") .\n@@ -1384,16 +1359,8 @@ sub git_commit {\n \t@difftree = map { chomp; $_ } <$fd>;\n \tclose $fd or die_error(undef, \"Reading diff-tree failed.\");\n \tgit_header_html();\n-\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n-\t      $cgi->a({-href => \"$my_uri?p=$project;a=summary\"}, \"summary\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=shortlog;h=$hash\"}, \"shortlog\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=log;h=$hash\"}, \"log\") .\n-\t      \" | commit\";\n-\tif (defined $co{'parent'}) {\n-\t\tprint \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commitdiff;h=$hash\"}, \"commitdiff\");\n-\t}\n-\tprint \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=tree;h=$co{'tree'};hb=$hash\"}, \"tree\") . \"\\n\" .\n-\t      \"<br/><br/></div>\\n\";\n+\tgit_page_nav('commit', defined $co{'parent'} ? '' : 'commitdiff',\n+\t\t$hash, $co{'tree'}, $hash);\n \tif (defined $co{'parent'}) {\n \t\tprint \"<div>\\n\" .\n \t\t      $cgi->a({-href => \"$my_uri?p=$project;a=commitdiff;h=$hash\", -class => \"title\"}, escapeHTML($co{'title'})) . \"\\n\" .\n@@ -1563,16 +1530,9 @@ sub git_blobdiff {\n \tmkdir($git_temp, 0700);\n \tgit_header_html();\n \tif (defined $hash_base && (my %co = git_read_commit($hash_base))) {\n-\t\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n-\t\t      $cgi->a({-href => \"$my_uri?p=$project;a=summary\"}, \"summary\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=shortlog\"}, \"shortlog\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=log\"}, \"log\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash_base\"}, \"commit\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commitdiff;h=$hash_base\"}, \"commitdiff\") .\n-\t\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=tree;h=$co{'tree'};hb=$hash_base\"}, \"tree\") .\n-\t\t      \"<br/>\\n\";\n-\t\tprint $cgi->a({-href => \"$my_uri?p=$project;a=blobdiff_plain;h=$hash;hp=$hash_parent\"}, \"plain\") .\n-\t\t      \"</div>\\n\";\n+\t\tgit_page_nav('', '', $hash_base, $co{'tree'}, $hash_base,\n+\t\t\t$cgi->a({-href => \"$my_uri?p=$project;a=blobdiff_plain;h=$hash;hp=$hash_parent\"}, \"plain\")\n+\t\t);\n \t\tprint \"<div>\\n\" .\n \t\t      $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash_base\", -class => \"title\"}, escapeHTML($co{'title'})) . \"\\n\" .\n \t\t      \"</div>\\n\";\n@@ -1615,15 +1575,9 @@ sub git_commitdiff {\n \tclose $fd or die_error(undef, \"Reading diff-tree failed.\");\n \n \tgit_header_html();\n-\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n-\t      $cgi->a({-href => \"$my_uri?p=$project;a=summary\"}, \"summary\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=shortlog;h=$hash\"}, \"shortlog\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=log;h=$hash\"}, \"log\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash\"}, \"commit\") .\n-\t      \" | commitdiff\" .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=tree;h=$co{'tree'};hb=$hash\"}, \"tree\") . \"<br/>\\n\";\n-\tprint $cgi->a({-href => \"$my_uri?p=$project;a=commitdiff_plain;h=$hash;hp=$hash_parent\"}, \"plain\") . \"\\n\" .\n-\t      \"</div>\\n\";\n+\tgit_page_nav('commitdiff', '', $hash, $co{'tree'}, $hash,\n+\t\t$cgi->a({-href => \"$my_uri?p=$project;a=commitdiff_plain;h=$hash;hp=$hash_parent\"}, \"plain\")\n+\t);\n \tprint \"<div>\\n\" .\n \t      $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash\", -class => \"title\"}, escapeHTML($co{'title'})) . \"\\n\" .\n \t      \"</div>\\n\";\n@@ -1731,15 +1685,7 @@ sub git_history {\n \t\tdie_error(undef, \"Unknown commit object.\");\n \t}\n \tgit_header_html();\n-\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n-\t      $cgi->a({-href => \"$my_uri?p=$project;a=summary\"}, \"summary\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=shortlog\"}, \"shortlog\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=log\"}, \"log\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash\"}, \"commit\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commitdiff;h=$hash\"}, \"commitdiff\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=tree;h=$co{'tree'};hb=$hash\"}, \"tree\") .\n-\t      \"<br/><br/>\\n\" .\n-\t      \"</div>\\n\";\n+\tgit_page_nav('', '', $hash, $co{'tree'}, $hash);\n \tprint \"<div>\\n\" .\n \t      $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash\", -class => \"title\"}, escapeHTML($co{'title'})) . \"\\n\" .\n \t      \"</div>\\n\";\n@@ -1815,15 +1761,7 @@ sub git_search {\n \t\t$pickaxe_search = 1;\n \t}\n \tgit_header_html();\n-\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n-\t      $cgi->a({-href => \"$my_uri?p=$project;a=summary;h=$hash\"}, \"summary\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=shortlog\"}, \"shortlog\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=log;h=$hash\"}, \"log\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash\"}, \"commit\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commitdiff;h=$hash\"}, \"commitdiff\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=tree;h=$co{'tree'};hb=$hash\"}, \"tree\") .\n-\t      \"<br/><br/>\\n\" .\n-\t      \"</div>\\n\";\n+\tgit_page_nav('', '', $hash, $co{'tree'}, $hash);\n \n \tprint \"<div>\\n\" .\n \t      $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash\", -class => \"title\"}, escapeHTML($co{'title'})) . \"\\n\" .\n@@ -1944,13 +1882,7 @@ sub git_shortlog {\n \t\t$page = 0;\n \t}\n \tgit_header_html();\n-\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n-\t      $cgi->a({-href => \"$my_uri?p=$project;a=summary\"}, \"summary\") .\n-\t      \" | shortlog\" .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=log;h=$hash\"}, \"log\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash\"}, \"commit\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=commitdiff;h=$hash\"}, \"commitdiff\") .\n-\t      \" | \" . $cgi->a({-href => \"$my_uri?p=$project;a=tree;h=$hash;hb=$hash\"}, \"tree\") . \"<br/>\\n\";\n+\tgit_page_nav('shortlog', '', $hash, $hash, $hash);\n \n \tmy $limit = sprintf(\"--max-count=%i\", (100 * ($page+1)));\n \topen my $fd, \"-|\", \"$gitbin/git-rev-list $limit $hash\" or die_error(undef, \"Open failed.\");\n\n\ndiff --git a/gitweb.cgi b/gitweb.cgi\n--- a/gitweb.cgi\n+++ b/gitweb.cgi\n@@ -178,6 +178,9 @@ if ($action eq \"summary\") {\n } elsif ($action eq \"shortlog\") {\n \tgit_shortlog();\n \texit;\n+} elsif ($action eq \"snapshot\") {\n+\tgit_snapshot();\n+\texit;\n } else {\n \tundef $action;\n \tdie_error(undef, \"Unknown action.\");\n@@ -286,10 +289,10 @@ EOF\n sub git_page_nav {\n \tmy ($current, $suppress, $head, $treehead, $treebase, $extra) = @_;\n \t$extra = '' if !defined $extra;\n-\tmy @navs = qw(summary shortlog log commit commitdiff tree);\n+\tmy @navs = qw(summary shortlog log commit commitdiff tree snapshot);\n \tmy %arg = map { $_, ''} @navs;\n \tif (defined $head) {\n-\t\tfor (qw(shortlog log commit commitdiff)) {\n+\t\tfor (qw(shortlog log commit commitdiff snapshot)) {\n \t\t\t$arg{$_} = \";h=$head\";\n \t\t}\n \t}\n@@ -1943,3 +1946,77 @@ sub git_shortlog {\n \tprint \"</table\\n>\";\n \tgit_footer_html();\n }\n+\n+sub git_snapshot {\n+\tif (!defined $hash) {\n+\t\t$hash = git_read_hash(\"$project/HEAD\");\n+\t}\n+\tmy %co = git_read_commit($hash);\n+\tif (!%co) {\n+\t\tdie_error(undef, \"Unknown commit object.\");\n+\t}\n+\tmy $st = $cgi->param('st');\n+\tif (defined $st) {\n+\t\treturn git_serve_snapshot($st);\n+\t}\n+\n+\tgit_header_html();\n+\tgit_page_nav('snapshot', '', $hash, $co{'tree'}, $hash);\n+\tprint \"<div>\\n\" .\n+\t      $cgi->a({-href => \"$my_uri?p=$project;a=commit;h=$hash\", -class => \"title\"}, escapeHTML($co{'title'})) . \"\\n\" .\n+\t      \"</div>\\n\";\n+\tprint \"<table cellspacing=\\\"0\\\">\\n\" .\n+\t      \"<tr>\\n\" .\n+\t      \"<th>Type</th>\\n\" .\n+\t      \"<th></th>\\n\" .\n+\t      \"</tr>\\n\";\n+\tmy %types = (\n+\t\t'Bzipped tar archive' => 'tar.bz2',\n+\t\t'Gzipped tar archive' => 'tar.gz',\n+\t);\n+\tmy $alternate = 0;\n+\tfor my $type (sort keys %types) {\n+\t\tif ($alternate) {\n+\t\t\tprint \"<tr class=\\\"dark\\\">\\n\";\n+\t\t} else {\n+\t\t\tprint \"<tr class=\\\"light\\\">\\n\";\n+\t\t}\n+\t\t$alternate ^= 1;\n+\t\tprint \"<td>$type</td>\";\n+\t\t$cgi->param(\"a\", \"snapshot\");\n+\t\tprint \"<td>\" .\n+\t\t      $cgi->startform(-method => \"get\", -action => \"$my_uri\") .\n+\t\t      $cgi->hidden(-name => \"p\") . \"\\n\" .\n+\t\t      $cgi->hidden(-name => \"a\") . \"\\n\" .\n+\t\t      $cgi->hidden(-name => \"h\") . \"\\n\" .\n+\t\t      $cgi->hidden(-name => \"st\", \n+\t\t\t\t   -value => $types{$type}) . \"\\n\" .\n+\t\t      $cgi->submit(-label => 'Download') . \"\\n\" .\n+\t\t      $cgi->end_form() . \"\\n\" .\n+\t\t      \"</td>\";\n+\t        print \"</tr>\\n\";\n+\t}\n+\tprint \"</table>\\n\";\n+\tgit_footer_html();\n+\treturn;\n+}\n+\n+sub git_serve_snapshot {\n+\tmy ($st) = @_;\n+\tmy %info = (\n+\t\t'tar.bz2' => [ 'application/x-bzip2', 'bzip2' ],\n+\t\t'tar.gz' => [ 'application/x-gzip', 'gzip' ],\n+\t);\n+\tif (!exists $info{$st}) {\n+\t\tdie_error(undef, \"Unknown snapshot type.\");\n+\t}\n+\tmy ($type, $zip) = @{$info{$st}};\n+\tprint $cgi->header(-type => $type, \n+\t\t\t   -attachment => \"$project-$hash.$st\");\n+\topen my $fd, \"-|\", \"$gitbin/git-tar-tree $hash '$project-$hash' | $zip\" \n+\t\tor return;\n+\tundef $/;\n+\tprint <$fd>;\n+\t$/ = \"\\n\";\n+\tclose $fd;\n+}\n"}]}