diff --git a/gitweb.cgi b/gitweb.cgi --- a/gitweb.cgi +++ b/gitweb.cgi @@ -178,6 +178,9 @@ if ($action eq "summary") { } elsif ($action eq "shortlog") { git_shortlog(); exit; +} elsif ($action eq "snapshot") { + git_snapshot(); + exit; } else { undef $action; die_error(undef, "Unknown action."); @@ -286,10 +289,10 @@ EOF sub git_page_nav { my ($current, $suppress, $head, $treehead, $treebase, $extra) = @_; $extra = '' if !defined $extra; - my @navs = qw(summary shortlog log commit commitdiff tree); + my @navs = qw(summary shortlog log commit commitdiff tree snapshot); my %arg = map { $_, ''} @navs; if (defined $head) { - for (qw(shortlog log commit commitdiff)) { + for (qw(shortlog log commit commitdiff snapshot)) { $arg{$_} = ";h=$head"; } } @@ -1943,3 +1946,77 @@ sub git_shortlog { print ""; git_footer_html(); } + +sub git_snapshot { + if (!defined $hash) { + $hash = git_read_hash("$project/HEAD"); + } + my %co = git_read_commit($hash); + if (!%co) { + die_error(undef, "Unknown commit object."); + } + my $st = $cgi->param('st'); + if (defined $st) { + return git_serve_snapshot($st); + } + + git_header_html(); + git_page_nav('snapshot', '', $hash, $co{'tree'}, $hash); + print "
\n" . + $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$hash", -class => "title"}, escapeHTML($co{'title'})) . "\n" . + "
\n"; + print "\n" . + "\n" . + "\n" . + "\n" . + "\n"; + my %types = ( + 'Bzipped tar archive' => 'tar.bz2', + 'Gzipped tar archive' => 'tar.gz', + ); + my $alternate = 0; + for my $type (sort keys %types) { + if ($alternate) { + print "\n"; + } else { + print "\n"; + } + $alternate ^= 1; + print ""; + $cgi->param("a", "snapshot"); + print ""; + print "\n"; + } + print "
Type
$type" . + $cgi->startform(-method => "get", -action => "$my_uri") . + $cgi->hidden(-name => "p") . "\n" . + $cgi->hidden(-name => "a") . "\n" . + $cgi->hidden(-name => "h") . "\n" . + $cgi->hidden(-name => "st", + -value => $types{$type}) . "\n" . + $cgi->submit(-label => 'Download') . "\n" . + $cgi->end_form() . "\n" . + "
\n"; + git_footer_html(); + return; +} + +sub git_serve_snapshot { + my ($st) = @_; + my %info = ( + 'tar.bz2' => [ 'application/x-bzip2', 'bzip2' ], + 'tar.gz' => [ 'application/x-gzip', 'gzip' ], + ); + if (!exists $info{$st}) { + die_error(undef, "Unknown snapshot type."); + } + my ($type, $zip) = @{$info{$st}}; + print $cgi->header(-type => $type, + -attachment => "$project-$hash.$st"); + open my $fd, "-|", "$gitbin/git-tar-tree $hash '$project-$hash' | $zip" + or return; + undef $/; + print <$fd>; + $/ = "\n"; + close $fd; +}