aboutsummaryrefslogtreecommitdiff
path: root/gitweb
diff options
context:
space:
mode:
authorGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2008-12-18 08:13:16 +0100
committerJunio C Hamano <gitster@pobox.com>2008-12-21 01:11:22 -0800
commit9872cd6f6c40803db9e784b6287db72e0cb6b5c3 (patch)
tree7235d33e3b1473b91d07853a781da8ba09550a7c /gitweb
parent2dd620286e84e4e76226a3511af6d14755b8c809 (diff)
downloadgit-9872cd6f6c40803db9e784b6287db72e0cb6b5c3.tar.gz
git-9872cd6f6c40803db9e784b6287db72e0cb6b5c3.tar.xz
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>
Diffstat (limited to 'gitweb')
-rwxr-xr-xgitweb/gitweb.perl69
1 files changed, 68 insertions, 1 deletions
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 95988fba4..9a11be3d9 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);