git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[RFCv2 1/2] gitweb: add patch view

From
Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
Date
Dec 3, 2008, 10:07 UTC
Message-ID
<1228298862-28191-2-git-send-email-giuseppe.bilotta@gmail.com>
In-Reply-To
<1228298862-28191-1-git-send-email-giuseppe.bilotta@gmail.com>
The manually-built email format in commitdiff_plain output is not
appropriate for feeding git-am, because of two limitations:
 * when a range of commits is specified, commitdiff_plain publishes a
   single patch with the message from the first commit, instead of a
   patchset,
 * in either case, the patch summary is replicated both as email subject
   and as first line of the email itself, resulting in a doubled summary
   if the output is fed to git-am.

We thus create a new view that can be fed to git-am directly by exposing the output of git format-patch directly. This allows patch exchange and submission via gitweb. A hard limit (configurable, defaults to 100) is imposed on the number of commits which will be included in a patchset, to prevent DoS attacks on the server.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---
 Makefile           |    2 ++
 gitweb/gitweb.perl |   30 +++++++++++++++++++++++++++++-
 2 files changed, 31 insertions(+), 1 deletions(-)
diff --git a/Makefile b/Makefile
index 5a69a41..dbf414c 100644
--- a/Makefile
+++ b/Makefile
@@ -220,6 +220,7 @@ GITWEB_LOGO = git-logo.png
 GITWEB_FAVICON = git-favicon.png
 GITWEB_SITE_HEADER =
 GITWEB_SITE_FOOTER =
+GITWEB_PATCH_MAX = 100
 
 export prefix bindir sharedir htmldir sysconfdir
 
@@ -1210,6 +1211,7 @@ gitweb/gitweb.cgi: gitweb/gitweb.perl
 	    -e 's|++GITWEB_FAVICON++|$(GITWEB_FAVICON)|g' \
 	    -e 's|++GITWEB_SITE_HEADER++|$(GITWEB_SITE_HEADER)|g' \
 	    -e 's|++GITWEB_SITE_FOOTER++|$(GITWEB_SITE_FOOTER)|g' \
+	    -e 's|++GITWEB_PATCH_MAX++|$(GITWEB_PATCH_MAX)|g' \
 	    $< >$@+ && \
 	chmod +x $@+ && \
 	mv $@+ $@
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 2738643..10cbe93 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -87,6 +87,9 @@ our $projects_list = "++GITWEB_LIST++";
 # the width (in characters) of the projects list "Description" column
 our $projects_list_description_width = 25;
 
+# the maximum number of patches allowed in patch view
+our $patch_max = "++GITWEB_PATCH_MAX++";
+
 # default order of projects list
 # valid values are none, project, descr, owner, and age
 our $default_projects_order = "project";
@@ -503,6 +506,7 @@ our %actions = (
 	"heads" => \&git_heads,
 	"history" => \&git_history,
 	"log" => \&git_log,
+	"patch" => \&git_patch,
 	"rss" => \&git_rss,
 	"atom" => \&git_atom,
 	"search" => \&git_search,
@@ -5483,7 +5487,12 @@ 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') {
+		open $fd, "-|", git_cmd(), "format-patch", '--encoding=utf8',
+			'--stdout', "-$patch_max",
+			$hash_parent ? ('-n', "$hash_parent..$hash") :
+			('--root', '-1', $hash)
+			or die_error(500, "Open git-format-patch failed");
 	} else {
 		die_error(400, "Unknown commitdiff format");
 	}
@@ -5532,6 +5541,15 @@ 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" . '"');
+		# TODO add X-Git-Tag/X-Git-Url headers in a sensible way
 	}
 
 	# write patch
@@ -5553,6 +5571,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 +5583,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);
-- 
1.5.6.5
Previous: Giuseppe BilottaNext: Giuseppe Bilotta
Message 2 of 9 in “[RFCv2 0/2] gitweb: patch view”
  1. Giuseppe BilottaDec 3, 2008
  2. 1/2 gitweb: add patch viewGiuseppe Bilotta, Dec 3, 2008
  3. 2/2 gitweb: links to patch action in commitdiff and shortlog viewGiuseppe Bilotta, Dec 3, 2008
  4. Junio C HamanoDec 3, 2008
  5. Giuseppe BilottaDec 3, 2008
  6. Jakub NarebskiDec 3, 2008
  7. Giuseppe BilottaDec 3, 2008
  8. Jakub NarebskiDec 3, 2008
  9. Giuseppe BilottaDec 3, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.