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

[PATCH 2/4] receive-pack: implement advertising and receiving push options

From
Stefan Beller <sbeller@google.com>
Date
Jun 30, 2016, 00:59 UTC
Message-ID
<20160630005951.7408-3-sbeller@google.com>
In-Reply-To
<20160630005951.7408-1-sbeller@google.com>

The pre/post receive hook may be interested in more information from the user. This information can be transmitted when both client and server support the "push-options" capability, which when used is a phase directly after update commands ended by a flush pkt.

Similar to the atomic option, the server capability can be disabled via the `receive.advertisePushOptions` config variable. While documenting this, fix a nit in the `receive.advertiseAtomic` wording.

For now we only accept C strings with no new lines.
Signed-off-by: Stefan Beller <sbeller@google.com>
---
 Documentation/config.txt                          |  7 +++-
 Documentation/technical/pack-protocol.txt         | 10 +++---
 Documentation/technical/protocol-capabilities.txt |  8 +++++
 builtin/receive-pack.c                            | 44 +++++++++++++++++++++++
 4 files changed, 64 insertions(+), 5 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 626243f..3b199f9 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2410,7 +2410,12 @@ rebase.instructionFormat
 
 receive.advertiseAtomic::
 	By default, git-receive-pack will advertise the atomic push
-	capability to its clients. If you don't want to this capability
+	capability to its clients. If you don't want this capability
+	to be advertised, set this variable to false.
+
+receive.advertisePushOptions::
+	By default, git-receive-pack will advertise the push options capability
+	to its clients. If you don't want this capability
 	to be advertised, set this variable to false.
 
 receive.autogc::
diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt
index 8b36343..7a2ed30 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -454,7 +454,8 @@ The reference discovery phase is done nearly the same way as it is in the
 fetching protocol. Each reference obj-id and name on the server is sent
 in packet-line format to the client, followed by a flush-pkt.  The only
 real difference is that the capability listing is different - the only
-possible values are 'report-status', 'delete-refs' and 'ofs-delta'.
+possible values are 'report-status', 'delete-refs', 'ofs-delta' and
+'push-options'.
 
 Reference Update Request and Packfile Transfer
 ----------------------------------------------
@@ -465,9 +466,10 @@ that it wants to update, it sends a line listing the obj-id currently on
 the server, the obj-id the client would like to update it to and the name
 of the reference.
 
-This list is followed by a flush-pkt and then the packfile that should
-contain all the objects that the server will need to complete the new
-references.
+This list is followed by a flush-pkt. Then the push options are transmitted
+one per packet followed by another flush-pkt. After that the packfile that
+should contain all the objects that the server will need to complete the new
+references will be sent.
 
 ----
   update-request    =  *shallow ( command-list | push-cert ) [packfile]
diff --git a/Documentation/technical/protocol-capabilities.txt b/Documentation/technical/protocol-capabilities.txt
index eaab6b4..b71eda9 100644
--- a/Documentation/technical/protocol-capabilities.txt
+++ b/Documentation/technical/protocol-capabilities.txt
@@ -253,6 +253,14 @@ atomic pushes. If the pushing client requests this capability, the server
 will update the refs in one atomic transaction. Either all refs are
 updated or none.
 
+push-options
+------------
+
+If the server sends the 'push-options' capability it is capable to accept
+push options after the update commands have been sent. If the pushing client
+requests this capability, the server will pass the options to the pre and post
+receive hooks that process this push request.
+
 allow-tip-sha1-in-want
 ----------------------
 
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 0da6852..68627ed 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -44,10 +44,12 @@ static struct strbuf fsck_msg_types = STRBUF_INIT;
 static int receive_unpack_limit = -1;
 static int transfer_unpack_limit = -1;
 static int advertise_atomic_push = 1;
+static int advertise_push_options = 1;
 static int unpack_limit = 100;
 static int report_status;
 static int use_sideband;
 static int use_atomic;
+static int use_push_options;
 static int quiet;
 static int prefer_ofs_delta = 1;
 static int auto_update_server_info;
@@ -193,6 +195,11 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
 		return 0;
 	}
 
+	if (strcmp(var, "receive.advertisepushoptions") == 0) {
+		advertise_push_options = git_config_bool(var, value);
+		return 0;
+	}
+
 	return git_default_config(var, value, cb);
 }
 
@@ -207,6 +214,8 @@ static void show_ref(const char *path, const unsigned char *sha1)
 			      "report-status delete-refs side-band-64k quiet");
 		if (advertise_atomic_push)
 			strbuf_addstr(&cap, " atomic");
+		if (advertise_push_options)
+			strbuf_addstr(&cap, " push-options");
 		if (prefer_ofs_delta)
 			strbuf_addstr(&cap, " ofs-delta");
 		if (push_cert_nonce)
@@ -1448,6 +1457,9 @@ static struct command *read_head_info(struct sha1_array *shallow)
 			if (advertise_atomic_push
 			    && parse_feature_request(feature_list, "atomic"))
 				use_atomic = 1;
+			if (advertise_push_options
+			    && parse_feature_request(feature_list, "push-options"))
+				use_push_options = 1;
 		}
 
 		if (!strcmp(line, "push-cert")) {
@@ -1480,6 +1492,35 @@ static struct command *read_head_info(struct sha1_array *shallow)
 	return commands;
 }
 
+static const char *stream_push_options_to_file()
+{
+	static const char *fname = "push-options-XXXXXX";
+	char *ret = xmallocz(strlen(fname));
+	int fd;
+	memcpy(ret, fname, strlen(fname));
+	fd = mkstemp(ret);
+
+	for (;;) {
+		char *line;
+		int len;
+
+		line = packet_read_line(0, &len);
+
+		if (!line)
+			break;
+
+		if (write_in_full(fd, line, len) < 0 ||
+		    write_in_full(fd, "\n", 1) < 0)
+			goto fail;
+	}
+
+	return ret;
+fail:
+	close(fd);
+	free(ret);
+	return NULL;
+}
+
 static const char *parse_pack_header(struct pack_header *hdr)
 {
 	switch (read_pack_header(0, hdr)) {
@@ -1767,6 +1808,9 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
 		const char *unpack_status = NULL;
 		const char *push_options_file = NULL;
 
+		if (use_push_options)
+			push_options_file = stream_push_options_to_file();
+
 		prepare_shallow_info(&si, &shallow);
 		if (!si.nr_ours && !si.nr_theirs)
 			shallow_update = 0;
-- 
2.9.0.141.gdd65b60
Previous: Stefan BellerNext: Junio C Hamano
Message 2 of 22 in “[RFC PATCHv1 0/4] Push options in C Git”
  1. Stefan BellerJun 30, 2016
  2. 2/4 receive-pack: implement advertising and receiving push optionsStefan Beller, Jun 30, 2016
  3. Junio C HamanoJul 1, 2016
  4. Stefan BellerJul 1, 2016
  5. 4/4 add a test for push optionsStefan Beller, Jun 30, 2016
  6. 1/4 push options: {pre,post}-receive hook learns about push optionsStefan Beller, Jun 30, 2016
  7. Jeff KingJul 1, 2016
  8. Stefan BellerJul 1, 2016
  9. Jeff KingJul 1, 2016
  10. Junio C HamanoJul 1, 2016
  11. Jeff KingJul 1, 2016
  12. Junio C HamanoJul 1, 2016
  13. Stefan BellerJul 1, 2016
  14. Jeff KingJul 1, 2016
  15. Stefan BellerJul 1, 2016
  16. Stefan BellerJul 1, 2016
  17. 3/4 push: accept push optionsStefan Beller, Jun 30, 2016
  18. Jeff KingJul 1, 2016
  19. Stefan BellerJul 1, 2016
  20. Jeff KingJul 1, 2016
  21. Stefan BellerJul 1, 2016
  22. Jeff KingJul 1, 2016

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.