diff options
| author | Giuseppe Bilotta <giuseppe.bilotta@gmail.com> | 2008-12-18 08:13:16 +0100 | 
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2008-12-21 01:11:22 -0800 | 
| commit | 9872cd6f6c40803db9e784b6287db72e0cb6b5c3 (patch) | |
| tree | 7235d33e3b1473b91d07853a781da8ba09550a7c | |
| parent | 2dd620286e84e4e76226a3511af6d14755b8c809 (diff) | |
| download | git-9872cd6f6c40803db9e784b6287db72e0cb6b5c3.tar.gz | |
gitweb: add patch view
The output of commitdiff_plain is not intended for git-am:
 * when given a range of commits, commitdiff_plain publishes a single
   patch with the message from the first commit, instead of a patchset
 * the hand-built email format replicates the commit summary both as
   email subject and as first line of the email itself, resulting in
   a duplication if the output is used with git-am.
We thus create a new view that can be fed to git-am directly, allowing
patch exchange via gitweb. The new view exposes the output of git
format-patch directly, limiting it to a single patch in the case of a
single commit.
A configurable upper limit defaulting to 16 is imposed on the number of
commits which will be included in a patchset, to prevent DoS attacks on
the server. Setting the limit to 0 will disable the patch view, setting
it to a negative number will remove the limit.
Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
| -rwxr-xr-x | gitweb/gitweb.perl | 69 | 
1 files changed, 68 insertions, 1 deletions
| diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 95988fba4a..9a11be3d94 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -329,6 +329,21 @@ our %feature = (  	'ctags' => {  		'override' => 0,  		'default' => [0]}, + +	# The maximum number of patches in a patchset generated in patch +	# view. Set this to 0 or undef to disable patch view, or to a +	# negative number to remove any limit. + +	# To disable system wide have in $GITWEB_CONFIG +	# $feature{'patches'}{'default'} = [0]; +	# To have project specific config enable override in $GITWEB_CONFIG +	# $feature{'patches'}{'override'} = 1; +	# and in project config gitweb.patches = 0|n; +	# where n is the maximum number of patches allowed in a patchset. +	'patches' => { +		'sub' => \&feature_patches, +		'override' => 0, +		'default' => [16]},  );  sub gitweb_get_feature { @@ -410,6 +425,16 @@ sub feature_pickaxe {  	return ($_[0]);  } +sub feature_patches { +	my @val = (git_get_project_config('patches', '--int')); + +	if (@val) { +		return @val; +	} + +	return ($_[0]); +} +  # checking HEAD file with -e is fragile if the repository was  # initialized long time ago (i.e. symlink HEAD) and was pack-ref'ed  # and then pruned. @@ -503,6 +528,7 @@ our %actions = (  	"heads" => \&git_heads,  	"history" => \&git_history,  	"log" => \&git_log, +	"patch" => \&git_patch,  	"rss" => \&git_rss,  	"atom" => \&git_atom,  	"search" => \&git_search, @@ -5386,6 +5412,13 @@ sub git_blobdiff_plain {  sub git_commitdiff {  	my $format = shift || 'html'; + +	my $patch_max; +	if ($format eq 'patch') { +		($patch_max) = gitweb_get_feature('patches'); +		die_error(403, "Patch view not allowed") unless $patch_max; +	} +  	$hash ||= $hash_base || "HEAD";  	my %co = parse_commit($hash)  	    or die_error(404, "Unknown commit object"); @@ -5483,7 +5516,23 @@ sub git_commitdiff {  		open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,  			'-p', $hash_parent_param, $hash, "--"  			or die_error(500, "Open git-diff-tree failed"); - +	} elsif ($format eq 'patch') { +		# For commit ranges, we limit the output to the number of +		# patches specified in the 'patches' feature. +		# For single commits, we limit the output to a single patch, +		# diverging from the git-format-patch default. +		my @commit_spec = (); +		if ($hash_parent) { +			if ($patch_max > 0) { +				push @commit_spec, "-$patch_max"; +			} +			push @commit_spec, '-n', "$hash_parent..$hash"; +		} else { +			push @commit_spec, '-1', '--root', $hash; +		} +		open $fd, "-|", git_cmd(), "format-patch", '--encoding=utf8', +			'--stdout', @commit_spec +			or die_error(500, "Open git-format-patch failed");  	} else {  		die_error(400, "Unknown commitdiff format");  	} @@ -5532,6 +5581,14 @@ sub git_commitdiff {  			print to_utf8($line) . "\n";  		}  		print "---\n\n"; +	} elsif ($format eq 'patch') { +		my $filename = basename($project) . "-$hash.patch"; + +		print $cgi->header( +			-type => 'text/plain', +			-charset => 'utf-8', +			-expires => $expires, +			-content_disposition => 'inline; filename="' . "$filename" . '"');  	}  	# write patch @@ -5553,6 +5610,11 @@ sub git_commitdiff {  		print <$fd>;  		close $fd  			or print "Reading git-diff-tree failed\n"; +	} elsif ($format eq 'patch') { +		local $/ = undef; +		print <$fd>; +		close $fd +			or print "Reading git-format-patch failed\n";  	}  } @@ -5560,6 +5622,11 @@ sub git_commitdiff_plain {  	git_commitdiff('plain');  } +# format-patch-style patches +sub git_patch { +	git_commitdiff('patch'); +} +  sub git_history {  	if (!defined $hash_base) {  		$hash_base = git_get_head_hash($project); | 
