gitweb/gitweb.perl | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 70 insertions(+), 0 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 653ca3c..13e80e0 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -132,6 +132,17 @@ our %feature = ( # => [content-encoding, suffix, program] 'default' => ['x-gzip', 'gz', 'gzip']}, + # To disable system wide have in $GITWEB_CONFIG + # $feature{'gear-export'}{'default'} = [undef]; + # To have project specific config enable override in $GITWEB_CONFIG + # $feature{'gear-export'}{'override'} = 1; + # and in project config gitweb.gear-export = none|gzip|bzip2; + 'gear-export' => { + 'sub' => \&feature_gear_export, + 'override' => 0, + # => [content-encoding, suffix, gear-option] + 'default' => ['x-gzip', 'gz', '--gzip']}, + # Enable text search, which will list the commits which match author, # committer or commit text to a given string. Enabled by default. 'search' => { @@ -230,6 +241,22 @@ sub feature_snapshot { return ($ctype, $suffix, $command); } +sub feature_gear_export { + my ($ctype, $suffix, $command) = @_; + + my ($val) = git_get_project_config('gear-export'); + + if ($val eq 'gzip') { + return ('x-gzip', 'gz', '--gzip'); + } elsif ($val eq 'bzip2') { + return ('x-bzip2', 'bz2', '--bzip2'); + } elsif ($val eq 'none') { + return (); + } + + return ($ctype, $suffix, $command); +} + sub gitweb_have_snapshot { my ($ctype, $suffix, $command) = gitweb_check_feature('snapshot'); my $have_snapshot = (defined $ctype && defined $suffix); @@ -237,6 +264,13 @@ sub gitweb_have_snapshot { return $have_snapshot; } +sub gitweb_have_gear_export { + my ($ctype, $suffix, $command) = gitweb_check_feature('gear-export'); + my $have_gear_export = (defined $ctype && defined $suffix); + + return $have_gear_export; +} + sub feature_pickaxe { my ($val) = git_get_project_config('pickaxe', '--bool'); @@ -447,6 +481,7 @@ my %actions = ( "tags" => \&git_tags, "tree" => \&git_tree, "snapshot" => \&git_snapshot, + "gear-export" => \&git_gear_export, "object" => \&git_object, # those below don't need $project "opml" => \&git_opml, @@ -2804,6 +2839,8 @@ sub git_tags_body { $from = 0 unless defined $from; $to = $#{$taglist} if (!defined $to || $#{$taglist} < $to); + my $have_gear_export = gitweb_have_gear_export(); + print "\n"; my $alternate = 1; for (my $i = $from; $i <= $to; $i++) { @@ -2850,6 +2887,9 @@ sub git_tags_body { } elsif ($tag{'reftype'} eq "blob") { print " | " . $cgi->a({-href => href(action=>"blob_plain", hash=>$tag{'refid'})}, "raw"); } + if ($have_gear_export) { + print " | " . $cgi->a({-href => href(action=>"gear-export", hash=>$tag{'refid'})}, "gear-export"); + } print "\n" . ""; } @@ -3630,6 +3670,36 @@ sub git_snapshot { } +sub git_gear_export { + my ($ctype, $suffix, $gear_option) = gitweb_check_feature('gear-export'); + my $have_gear_export = (defined $ctype && defined $suffix); + if (!$have_gear_export) { + die_error('403 Permission denied', "Permission denied"); + } + + if (!defined $hash) { + $hash = git_get_head_hash($project); + } + + my $filename = to_utf8(basename($project)) . "-$hash.tar.$suffix"; + + print $cgi->header( + -type => "application/$ctype", + -content_disposition => 'inline; filename="' . "$filename" . '"', + -status => '200 OK'); + + my $name = $project; + $name =~ s/\047/\047\\\047\047/g; + open my $fd, "-|", + "GIT_DIR='$git_dir' gear -t $hash $gear_option -" + or die_error(undef, "Execute gear failed."); + binmode STDOUT, ':raw'; + print <$fd>; + binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi + close $fd; + +} + sub git_log { my $head = git_get_head_hash($project); if (!defined $hash) {