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

[PATCH v5 14/28] Add stateless RPC options to upload-pack, receive-pack

From
Shawn O. Pearce <spearce@spearce.org>
Date
Oct 31, 2009, 00:47 UTC
Message-ID
<1256950067-27938-16-git-send-email-spearce@spearce.org>
In-Reply-To
<1256950067-27938-1-git-send-email-spearce@spearce.org>

When --stateless-rpc is passed as a command line parameter to upload-pack or receive-pack the programs now assume they may perform only a single read-write cycle with stdin and stdout. This fits with the HTTP POST request processing model where a program may read the request, write a response, and must exit.

When --advertise-refs is passed as a command line parameter only the initial ref advertisement is output, and the program exits immediately. This fits with the HTTP GET request model, where no request content is received but a response must be produced.

HTTP headers and/or environment are not processed here, but instead are assumed to be handled by the program invoking either service backend.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 builtin-receive-pack.c |   26 ++++++++++++++++++++------
 upload-pack.c          |   40 ++++++++++++++++++++++++++++++++++++----
 2 files changed, 56 insertions(+), 10 deletions(-)
diff --git a/builtin-receive-pack.c b/builtin-receive-pack.c
index b771fe9..70ff8c5 100644
--- a/builtin-receive-pack.c
+++ b/builtin-receive-pack.c
@@ -615,6 +615,8 @@ static void add_alternate_refs(void)
 
 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
 {
+	int advertise_refs = 0;
+	int stateless_rpc = 0;
 	int i;
 	char *dir = NULL;
 
@@ -623,7 +625,15 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
 		const char *arg = *argv++;
 
 		if (*arg == '-') {
-			/* Do flag handling here */
+			if (!strcmp(arg, "--advertise-refs")) {
+				advertise_refs = 1;
+				continue;
+			}
+			if (!strcmp(arg, "--stateless-rpc")) {
+				stateless_rpc = 1;
+				continue;
+			}
+
 			usage(receive_pack_usage);
 		}
 		if (dir)
@@ -652,12 +662,16 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
 		" report-status delete-refs ofs-delta " :
 		" report-status delete-refs ";
 
-	add_alternate_refs();
-	write_head_info();
-	clear_extra_refs();
+	if (advertise_refs || !stateless_rpc) {
+		add_alternate_refs();
+		write_head_info();
+		clear_extra_refs();
 
-	/* EOF */
-	packet_flush(1);
+		/* EOF */
+		packet_flush(1);
+	}
+	if (advertise_refs)
+		return 0;
 
 	read_head_info();
 	if (commands) {
diff --git a/upload-pack.c b/upload-pack.c
index f1dc3a3..70badcf 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -39,6 +39,8 @@ static unsigned int timeout;
  */
 static int use_sideband;
 static int debug_fd;
+static int advertise_refs;
+static int stateless_rpc;
 
 static void reset_timeout(void)
 {
@@ -509,6 +511,8 @@ static int get_common_commits(void)
 		if (!len) {
 			if (have_obj.nr == 0 || multi_ack)
 				packet_write(1, "NAK\n");
+			if (stateless_rpc)
+				exit(0);
 			continue;
 		}
 		strip(line, len);
@@ -710,12 +714,32 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
 	return 0;
 }
 
+static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
+{
+	struct object *o = parse_object(sha1);
+	if (!o)
+		die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
+	if (!(o->flags & OUR_REF)) {
+		o->flags |= OUR_REF;
+		nr_our_refs++;
+	}
+	return 0;
+}
+
 static void upload_pack(void)
 {
-	reset_timeout();
-	head_ref(send_ref, NULL);
-	for_each_ref(send_ref, NULL);
-	packet_flush(1);
+	if (advertise_refs || !stateless_rpc) {
+		reset_timeout();
+		head_ref(send_ref, NULL);
+		for_each_ref(send_ref, NULL);
+		packet_flush(1);
+	} else {
+		head_ref(mark_our_ref, NULL);
+		for_each_ref(mark_our_ref, NULL);
+	}
+	if (advertise_refs)
+		return;
+
 	receive_needs();
 	if (want_obj.nr) {
 		get_common_commits();
@@ -737,6 +761,14 @@ int main(int argc, char **argv)
 
 		if (arg[0] != '-')
 			break;
+		if (!strcmp(arg, "--advertise-refs")) {
+			advertise_refs = 1;
+			continue;
+		}
+		if (!strcmp(arg, "--stateless-rpc")) {
+			stateless_rpc = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--strict")) {
 			strict = 1;
 			continue;
-- 
1.6.5.2.181.gd6f41
Previous: Shawn O. PearceNext: Shawn O. Pearce
Message 16 of 31 in “Return of smart HTTP”
  1. 00/28 Return of smart HTTPShawn O. Pearce, Oct 31, 2009
  2. 00/28 interdiff to v4Shawn O. Pearce, Oct 31, 2009
  3. 01/28 http-push: fix check condition on http.c::finish_http_pack_request()Shawn O. Pearce, Oct 31, 2009
  4. 02/28 pkt-line: Add strbuf based functionsShawn O. Pearce, Oct 31, 2009
  5. 03/28 pkt-line: Make packet_read_line easier to debugShawn O. Pearce, Oct 31, 2009
  6. 04/28 fetch-pack: Use a strbuf to compose the want listShawn O. Pearce, Oct 31, 2009
  7. 05/28 Move "get_ack()" back to fetch-packShawn O. Pearce, Oct 31, 2009
  8. 06/28 Add multi_ack_detailed capability to fetch-pack/upload-packShawn O. Pearce, Oct 31, 2009
  9. 07/28 remote-curl: Refactor walker initializationShawn O. Pearce, Oct 31, 2009
  10. 08/28 fetch: Allow transport -v -v -v to set verbosity to 3Shawn O. Pearce, Oct 31, 2009
  11. 09/28 remote-helpers: Fetch more than one ref in a batchShawn O. Pearce, Oct 31, 2009
  12. 10/28 remote-helpers: Support custom transport optionsShawn O. Pearce, Oct 31, 2009
  13. 11/28 Move WebDAV HTTP push under remote-curlShawn O. Pearce, Oct 31, 2009
  14. 12/28 remote-helpers: return successfully if everything up-to-dateShawn O. Pearce, Oct 31, 2009
  15. 13/28 Git-aware CGI to provide dumb HTTP transportShawn O. Pearce, Oct 31, 2009
  16. 14/28 Add stateless RPC options to upload-pack, receive-packShawn O. Pearce, Oct 31, 2009
  17. 15/28 Smart fetch and push over HTTP: server sideShawn O. Pearce, Oct 31, 2009
  18. 16/28 http-backend: add GIT_PROJECT_ROOT environment varShawn O. Pearce, Oct 31, 2009
  19. 17/28 http-backend: reword some documentationShawn O. Pearce, Oct 31, 2009
  20. 18/28 http-backend: use mod_alias instead of mod_rewriteShawn O. Pearce, Oct 31, 2009
  21. 19/28 http-backend: add example for gitweb on same URLShawn O. Pearce, Oct 31, 2009
  22. 20/28 http-backend: more explict LocationMatchShawn O. Pearce, Oct 31, 2009
  23. 21/28 Discover refs via smart HTTP server when availableShawn O. Pearce, Oct 31, 2009
  24. 22/28 Smart push over HTTP: client sideShawn O. Pearce, Oct 31, 2009
  25. 23/28 Smart fetch over HTTP: client sideShawn O. Pearce, Oct 31, 2009
  26. 24/28 Smart HTTP fetch: gzip requestsShawn O. Pearce, Oct 31, 2009
  27. 25/28 t5540-http-push: remove redundant fetchesShawn O. Pearce, Oct 31, 2009
  28. 26/28 set httpd port before sourcing lib-httpdShawn O. Pearce, Oct 31, 2009
  29. 27/28 http tests: use /dumb/ URL prefixShawn O. Pearce, Oct 31, 2009
  30. Tay Ray ChuanNov 1, 2009
  31. 28/28 test smart http fetch and pushShawn O. Pearce, Oct 31, 2009

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.