329
'ctags' => {
330
'override' => 0,
331
'default' => [0]},
332
+
333
+ # The maximum number of patches in a patchset generated in patch
334
+ # view. Set this to 0 or undef to disable patch view, or to a
335
+ # negative number to remove any limit.
336
+
337
+ # To disable system wide have in $GITWEB_CONFIG
338
+ # $feature{'patches'}{'default'} = [0];
339
+ # To have project specific config enable override in $GITWEB_CONFIG
340
+ # $feature{'patches'}{'override'} = 1;
341
+ # and in project config gitweb.patches = 0|n;
342
+ # where n is the maximum number of patches allowed in a patchset.
343
+ 'patches' => {
344
+ 'sub' => \&feature_patches,
345
+ 'override' => 0,
346
+ 'default' => [16]},
347
);
348
349
sub gitweb_get_feature {
425
return ($_[0]);
426
}
427
428
+sub feature_patches {
429
+ my @val = (git_get_project_config('patches', '--int'));
430
+
431
+ if (@val) {
432
+ return @val;
433
+ }
434
+
435
+ return ($_[0]);
436
+}
437
+
438
# checking HEAD file with -e is fragile if the repository was
439
# initialized long time ago (i.e. symlink HEAD) and was pack-ref'ed
440
# and then pruned.
528
"heads" => \&git_heads,
529
"history" => \&git_history,
530
"log" => \&git_log,
531
+ "patch" => \&git_patch,
532
"rss" => \&git_rss,
533
"atom" => \&git_atom,
534
"search" => \&git_search,
5412
5413
sub git_commitdiff {
5414
my $format = shift || 'html';
5415
+
5416
+ my $patch_max;
5417
+ if ($format eq 'patch') {
5418
+ ($patch_max) = gitweb_get_feature('patches');
5419
+ die_error(403, "Patch view not allowed") unless $patch_max;
5420
+ }
5421
+
5422
$hash ||= $hash_base || "HEAD";
5423
my %co = parse_commit($hash)
5424
or die_error(404, "Unknown commit object");
5516
open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts,
5517
'-p', $hash_parent_param, $hash, "--"
5518
or die_error(500, "Open git-diff-tree failed");
5486
-
5519
+ } elsif ($format eq 'patch') {
5520
+ # For commit ranges, we limit the output to the number of
5521
+ # patches specified in the 'patches' feature.
5522
+ # For single commits, we limit the output to a single patch,
5523
+ # diverging from the git-format-patch default.
5524
+ my @commit_spec = ();
5525
+ if ($hash_parent) {
5526
+ if ($patch_max > 0) {
5527
+ push @commit_spec, "-$patch_max";
5528
+ }
5529
+ push @commit_spec, '-n', "$hash_parent..$hash";
5530
+ } else {
5531
+ push @commit_spec, '-1', '--root', $hash;
5532
+ }
5533
+ open $fd, "-|", git_cmd(), "format-patch", '--encoding=utf8',
5534
+ '--stdout', @commit_spec
5535
+ or die_error(500, "Open git-format-patch failed");
5536
} else {
5537
die_error(400, "Unknown commitdiff format");
5538
}
5581
print to_utf8($line) . "\n";
5582
}
5583
print "---\n\n";
5584
+ } elsif ($format eq 'patch') {
5585
+ my $filename = basename($project) . "-$hash.patch";
5586
+
5587
+ print $cgi->header(
5588
+ -type => 'text/plain',
5589
+ -charset => 'utf-8',
5590
+ -expires => $expires,
5591
+ -content_disposition => 'inline; filename="' . "$filename" . '"');
5592
}
5593
5594
# write patch
5610
print <$fd>;
5611
close $fd
5612
or print "Reading git-diff-tree failed\n";
5613
+ } elsif ($format eq 'patch') {
5614
+ local $/ = undef;
5615
+ print <$fd>;
5616
+ close $fd
5617
+ or print "Reading git-format-patch failed\n";
5618
}
5619
}
5620
5622
git_commitdiff('plain');
5623
}
5624
5625
+# format-patch-style patches
5626
+sub git_patch {
5627
+ git_commitdiff('patch');
5628
+}
5629
+
5630
sub git_history {
5631
if (!defined $hash_base) {
5632
$hash_base = git_get_head_hash($project);