git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 0/3] optionally send server-options when using v2
@ 2018-04-23 22:46 Brandon Williams
  2018-04-23 22:46 ` [PATCH 1/3] serve: introduce the server-option capability Brandon Williams
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Brandon Williams @ 2018-04-23 22:46 UTC (permalink / raw)
  To: git, bmwill; +Cc: Brandon Williams

Building on top of protocol version 2 this series adds the ability to
optionally send server specific options when using protocol v2. This
resembles the "push-options" feature except server options are sent as
capability lines during a command request allowing for all current and
future commands to benefit from sending arbitrary server options (and
not requiring that sending server specific options be re-implemented for
each and every command that may want to make use of them in the future).

These options can be provided by the user via the command line by giving
"-o <option>" or "--server-option=<option>" to either ls-remote or
fetch.

Command request example:

	command=fetch
	server-option=hello
	server-option=world
	0001
	want A
	want B
	have X
	have Y
	0000

These options are only transmitted to the remote end when communicating
using protocol version 2.

Brandon Williams (3):
  serve: introduce the server-option capability
  ls-remote: send server options when using protocol v2
  fetch: send server options when using protocol v2

 Documentation/fetch-options.txt         |  8 +++++++
 Documentation/git-ls-remote.txt         |  8 +++++++
 Documentation/technical/protocol-v2.txt | 10 ++++++++
 builtin/fetch.c                         |  5 ++++
 builtin/ls-remote.c                     |  4 ++++
 connect.c                               |  9 ++++++-
 fetch-pack.c                            |  7 ++++++
 fetch-pack.h                            |  1 +
 remote.h                                |  4 +++-
 serve.c                                 |  1 +
 t/t5701-git-serve.sh                    | 21 ++++++++++++++++
 t/t5702-protocol-v2.sh                  | 32 +++++++++++++++++++++++++
 transport.c                             |  3 ++-
 transport.h                             |  6 +++++
 14 files changed, 116 insertions(+), 3 deletions(-)

-- 
2.17.0.484.g0c8726318c-goog


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] serve: introduce the server-option capability
  2018-04-23 22:46 [PATCH 0/3] optionally send server-options when using v2 Brandon Williams
@ 2018-04-23 22:46 ` Brandon Williams
  2018-04-23 22:46 ` [PATCH 2/3] ls-remote: send server options when using protocol v2 Brandon Williams
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Brandon Williams @ 2018-04-23 22:46 UTC (permalink / raw)
  To: git, bmwill; +Cc: Brandon Williams

Introduce the "server-option" capability to protocol version 2.  This
enables future clients the ability to send server specific options in
command requests when using protocol version 2.

Signed-off-by: Brandon Williams <bmwill@google.com>
---
 Documentation/technical/protocol-v2.txt | 10 ++++++++++
 serve.c                                 |  1 +
 t/t5701-git-serve.sh                    | 21 +++++++++++++++++++++
 3 files changed, 32 insertions(+)

diff --git a/Documentation/technical/protocol-v2.txt b/Documentation/technical/protocol-v2.txt
index 136179d7d..d7b6f38e0 100644
--- a/Documentation/technical/protocol-v2.txt
+++ b/Documentation/technical/protocol-v2.txt
@@ -393,3 +393,13 @@ header.
 		1 - pack data
 		2 - progress messages
 		3 - fatal error message just before stream aborts
+
+ server-option
+~~~~~~~~~~~~~~~
+
+If advertised, indicates that any number of server specific options can be
+included in a request.  This is done by sending each option as a
+"server-option=<option>" capability line in the capability-list section of
+a request.
+
+The provided options must not contain a NUL or LF character.
diff --git a/serve.c b/serve.c
index a5a7b2f7d..bda085f09 100644
--- a/serve.c
+++ b/serve.c
@@ -56,6 +56,7 @@ static struct protocol_capability capabilities[] = {
 	{ "agent", agent_advertise, NULL },
 	{ "ls-refs", always_advertise, ls_refs },
 	{ "fetch", upload_pack_advertise, upload_pack_v2 },
+	{ "server-option", always_advertise, NULL },
 };
 
 static void advertise_capabilities(void)
diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh
index 72d7bc562..011a5796d 100755
--- a/t/t5701-git-serve.sh
+++ b/t/t5701-git-serve.sh
@@ -10,6 +10,7 @@ test_expect_success 'test capability advertisement' '
 	agent=git/$(git version | cut -d" " -f3)
 	ls-refs
 	fetch=shallow
+	server-option
 	0000
 	EOF
 
@@ -173,4 +174,24 @@ test_expect_success 'symrefs parameter' '
 	test_cmp actual expect
 '
 
+test_expect_success 'sending server-options' '
+	test-pkt-line pack >in <<-EOF &&
+	command=ls-refs
+	server-option=hello
+	server-option=world
+	0001
+	ref-prefix HEAD
+	0000
+	EOF
+
+	cat >expect <<-EOF &&
+	$(git rev-parse HEAD) HEAD
+	0000
+	EOF
+
+	git serve --stateless-rpc <in >out &&
+	test-pkt-line unpack <out >actual &&
+	test_cmp actual expect
+'
+
 test_done
-- 
2.17.0.484.g0c8726318c-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] ls-remote: send server options when using protocol v2
  2018-04-23 22:46 [PATCH 0/3] optionally send server-options when using v2 Brandon Williams
  2018-04-23 22:46 ` [PATCH 1/3] serve: introduce the server-option capability Brandon Williams
@ 2018-04-23 22:46 ` Brandon Williams
  2018-04-23 22:46 ` [PATCH 3/3] fetch: " Brandon Williams
  2018-04-23 22:47 ` [PATCH 0/3] optionally send server-options when using v2 Brandon Williams
  3 siblings, 0 replies; 5+ messages in thread
From: Brandon Williams @ 2018-04-23 22:46 UTC (permalink / raw)
  To: git, bmwill; +Cc: Brandon Williams

Teach ls-remote to optionally accept server options by specifying them
on the cmdline via '-o' or '--server-option'.  These server options are
sent to the remote end when querying for the remote end's refs using
protocol version 2.

If communicating using a protocol other than v2 the provided options are
ignored and not sent to the remote end.

Signed-off-by: Brandon Williams <bmwill@google.com>
---
 Documentation/git-ls-remote.txt |  8 ++++++++
 builtin/ls-remote.c             |  4 ++++
 connect.c                       |  9 ++++++++-
 remote.h                        |  4 +++-
 t/t5702-protocol-v2.sh          | 16 ++++++++++++++++
 transport.c                     |  2 +-
 transport.h                     |  6 ++++++
 7 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-ls-remote.txt b/Documentation/git-ls-remote.txt
index 5f2628c8f..e5defb1b2 100644
--- a/Documentation/git-ls-remote.txt
+++ b/Documentation/git-ls-remote.txt
@@ -60,6 +60,14 @@ OPTIONS
 	upload-pack only shows the symref HEAD, so it will be the only
 	one shown by ls-remote.
 
+-o <option>::
+--server-option=<option>::
+	Transmit the given string to the server when communicating using
+	protocol version 2.  The given string must not contain a NUL or LF
+	character.
+	When multiple `--server-option=<option>` are given, they are all
+	sent to the other side in the order listed on the command line.
+
 <repository>::
 	The "remote" repository to query.  This parameter can be
 	either a URL or the name of a remote (see the GIT URLS and
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index 380c18027..3150bfb92 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -45,6 +45,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 	const char *uploadpack = NULL;
 	const char **pattern = NULL;
 	struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
+	struct string_list server_options = STRING_LIST_INIT_DUP;
 
 	struct remote *remote;
 	struct transport *transport;
@@ -67,6 +68,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 			      2, PARSE_OPT_NOCOMPLETE),
 		OPT_BOOL(0, "symref", &show_symref_target,
 			 N_("show underlying ref in addition to the object pointed by it")),
+		OPT_STRING_LIST('o', "server-option", &server_options, N_("server-specific"), N_("option to transmit")),
 		OPT_END()
 	};
 
@@ -107,6 +109,8 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 	transport = transport_get(remote, NULL);
 	if (uploadpack != NULL)
 		transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
+	if (server_options.nr)
+		transport->server_options = &server_options;
 
 	ref = transport_get_remote_refs(transport, &ref_prefixes);
 	if (transport_disconnect(transport))
diff --git a/connect.c b/connect.c
index 54971166a..3000768c7 100644
--- a/connect.c
+++ b/connect.c
@@ -408,7 +408,8 @@ static int process_ref_v2(const char *line, struct ref ***list)
 
 struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
 			     struct ref **list, int for_push,
-			     const struct argv_array *ref_prefixes)
+			     const struct argv_array *ref_prefixes,
+			     const struct string_list *server_options)
 {
 	int i;
 	*list = NULL;
@@ -419,6 +420,12 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
 	if (server_supports_v2("agent", 0))
 		packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized());
 
+	if (server_options && server_options->nr &&
+	    server_supports_v2("server-option", 1))
+		for (i = 0; i < server_options->nr; i++)
+			packet_write_fmt(fd_out, "server-option=%s",
+					 server_options->items[i].string);
+
 	packet_delim(fd_out);
 	/* When pushing we don't want to request the peeled tags */
 	if (!for_push)
diff --git a/remote.h b/remote.h
index 2b3180f94..93dd97e25 100644
--- a/remote.h
+++ b/remote.h
@@ -153,6 +153,7 @@ void free_refs(struct ref *ref);
 struct oid_array;
 struct packet_reader;
 struct argv_array;
+struct string_list;
 extern struct ref **get_remote_heads(struct packet_reader *reader,
 				     struct ref **list, unsigned int flags,
 				     struct oid_array *extra_have,
@@ -161,7 +162,8 @@ extern struct ref **get_remote_heads(struct packet_reader *reader,
 /* Used for protocol v2 in order to retrieve refs from a remote */
 extern struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
 				    struct ref **list, int for_push,
-				    const struct argv_array *ref_prefixes);
+				    const struct argv_array *ref_prefixes,
+				    const struct string_list *server_options);
 
 int resolve_remote_symref(struct ref *ref, struct ref *list);
 int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid);
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index 56f7c3c32..71ef1aee1 100755
--- a/t/t5702-protocol-v2.sh
+++ b/t/t5702-protocol-v2.sh
@@ -154,6 +154,22 @@ test_expect_success 'ref advertisment is filtered with ls-remote using protocol
 	test_cmp actual expect
 '
 
+test_expect_success 'server-options are sent when using ls-remote' '
+	test_when_finished "rm -f log" &&
+
+	GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+		ls-remote -o hello -o world "file://$(pwd)/file_parent" master >actual &&
+
+	cat >expect <<-EOF &&
+	$(git -C file_parent rev-parse refs/heads/master)$(printf "\t")refs/heads/master
+	EOF
+
+	test_cmp actual expect &&
+	grep "server-option=hello" log &&
+	grep "server-option=world" log
+'
+
+
 test_expect_success 'clone with file:// using protocol v2' '
 	test_when_finished "rm -f log" &&
 
diff --git a/transport.c b/transport.c
index 4d8beaaab..42fd468f3 100644
--- a/transport.c
+++ b/transport.c
@@ -218,7 +218,7 @@ static struct ref *get_refs_via_connect(struct transport *transport, int for_pus
 	switch (data->version) {
 	case protocol_v2:
 		get_remote_refs(data->fd[1], &reader, &refs, for_push,
-				ref_prefixes);
+				ref_prefixes, transport->server_options);
 		break;
 	case protocol_v1:
 	case protocol_v0:
diff --git a/transport.h b/transport.h
index e783cfa07..73a7be3c8 100644
--- a/transport.h
+++ b/transport.h
@@ -71,6 +71,12 @@ struct transport {
 	 */
 	const struct string_list *push_options;
 
+	/*
+	 * These strings will be passed to the remote side on each command
+	 * request, if both sides support the server-option capability.
+	 */
+	const struct string_list *server_options;
+
 	char *pack_lockfile;
 	signed verbose : 3;
 	/**
-- 
2.17.0.484.g0c8726318c-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] fetch: send server options when using protocol v2
  2018-04-23 22:46 [PATCH 0/3] optionally send server-options when using v2 Brandon Williams
  2018-04-23 22:46 ` [PATCH 1/3] serve: introduce the server-option capability Brandon Williams
  2018-04-23 22:46 ` [PATCH 2/3] ls-remote: send server options when using protocol v2 Brandon Williams
@ 2018-04-23 22:46 ` Brandon Williams
  2018-04-23 22:47 ` [PATCH 0/3] optionally send server-options when using v2 Brandon Williams
  3 siblings, 0 replies; 5+ messages in thread
From: Brandon Williams @ 2018-04-23 22:46 UTC (permalink / raw)
  To: git, bmwill; +Cc: Brandon Williams

Teach fetch to optionally accept server options by specifying them on
the cmdline via '-o' or '--server-option'.  These server options are
sent to the remote end when performing a fetch communicating using
protocol version 2.

If communicating using a protocol other than v2 the provided options are
ignored and not sent to the remote end.

Signed-off-by: Brandon Williams <bmwill@google.com>
---
 Documentation/fetch-options.txt |  8 ++++++++
 builtin/fetch.c                 |  5 +++++
 fetch-pack.c                    |  7 +++++++
 fetch-pack.h                    |  1 +
 t/t5702-protocol-v2.sh          | 16 ++++++++++++++++
 transport.c                     |  1 +
 6 files changed, 38 insertions(+)

diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 8631e365f..97d3217df 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -188,6 +188,14 @@ endif::git-pull[]
 	is specified. This flag forces progress status even if the
 	standard error stream is not directed to a terminal.
 
+-o <option>::
+--server-option=<option>::
+	Transmit the given string to the server when communicating using
+	protocol version 2.  The given string must not contain a NUL or LF
+	character.
+	When multiple `--server-option=<option>` are given, they are all
+	sent to the other side in the order listed on the command line.
+
 -4::
 --ipv4::
 	Use IPv4 addresses only, ignoring IPv6 addresses.
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 7ee83ac0f..5a6f6b2dc 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -62,6 +62,7 @@ static int shown_url = 0;
 static int refmap_alloc, refmap_nr;
 static const char **refmap_array;
 static struct list_objects_filter_options filter_options;
+static struct string_list server_options = STRING_LIST_INIT_DUP;
 
 static int git_fetch_config(const char *k, const char *v, void *cb)
 {
@@ -170,6 +171,7 @@ static struct option builtin_fetch_options[] = {
 		 N_("accept refs that update .git/shallow")),
 	{ OPTION_CALLBACK, 0, "refmap", NULL, N_("refmap"),
 	  N_("specify fetch refmap"), PARSE_OPT_NONEG, parse_refmap_arg },
+	OPT_STRING_LIST('o', "server-option", &server_options, N_("server-specific"), N_("option to transmit")),
 	OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"),
 			TRANSPORT_FAMILY_IPV4),
 	OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
@@ -1417,6 +1419,9 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, int pru
 		}
 	}
 
+	if (server_options.nr)
+		gtransport->server_options = &server_options;
+
 	sigchain_push_common(unlock_pack_on_signal);
 	atexit(unlock_pack);
 	refspec = parse_fetch_refspec(ref_nr, refs);
diff --git a/fetch-pack.c b/fetch-pack.c
index 216d1368b..199eb8a1d 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -1174,6 +1174,13 @@ static int send_fetch_request(int fd_out, const struct fetch_pack_args *args,
 		packet_buf_write(&req_buf, "command=fetch");
 	if (server_supports_v2("agent", 0))
 		packet_buf_write(&req_buf, "agent=%s", git_user_agent_sanitized());
+	if (args->server_options && args->server_options->nr &&
+	    server_supports_v2("server-option", 1)) {
+		int i;
+		for (i = 0; i < args->server_options->nr; i++)
+			packet_write_fmt(fd_out, "server-option=%s",
+					 args->server_options->items[i].string);
+	}
 
 	packet_buf_delim(&req_buf);
 	if (args->use_thin_pack)
diff --git a/fetch-pack.h b/fetch-pack.h
index 667024a76..f4ba851c6 100644
--- a/fetch-pack.h
+++ b/fetch-pack.h
@@ -15,6 +15,7 @@ struct fetch_pack_args {
 	const char *deepen_since;
 	const struct string_list *deepen_not;
 	struct list_objects_filter_options filter_options;
+	const struct string_list *server_options;
 	unsigned deepen_relative:1;
 	unsigned quiet:1;
 	unsigned keep_pack:1;
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index 71ef1aee1..dbfd0691c 100755
--- a/t/t5702-protocol-v2.sh
+++ b/t/t5702-protocol-v2.sh
@@ -217,6 +217,22 @@ test_expect_success 'ref advertisment is filtered during fetch using protocol v2
 	! grep "refs/tags/three" log
 '
 
+test_expect_success 'server-options are sent when fetching' '
+	test_when_finished "rm -f log" &&
+
+	test_commit -C file_parent four &&
+
+	GIT_TRACE_PACKET="$(pwd)/log" git -C file_child -c protocol.version=2 \
+		fetch -o hello -o world origin master &&
+
+	git -C file_child log -1 --format=%s origin/master >actual &&
+	git -C file_parent log -1 --format=%s >expect &&
+	test_cmp expect actual &&
+
+	grep "server-option=hello" log &&
+	grep "server-option=world" log
+'
+
 # Test protocol v2 with 'http://' transport
 #
 . "$TEST_DIRECTORY"/lib-httpd.sh
diff --git a/transport.c b/transport.c
index 42fd468f3..b088bcd49 100644
--- a/transport.c
+++ b/transport.c
@@ -266,6 +266,7 @@ static int fetch_refs_via_pack(struct transport *transport,
 	args.no_dependents = data->options.no_dependents;
 	args.filter_options = data->options.filter_options;
 	args.stateless_rpc = transport->stateless_rpc;
+	args.server_options = transport->server_options;
 
 	if (!data->got_remote_heads)
 		refs_tmp = get_refs_via_connect(transport, 0, NULL);
-- 
2.17.0.484.g0c8726318c-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/3] optionally send server-options when using v2
  2018-04-23 22:46 [PATCH 0/3] optionally send server-options when using v2 Brandon Williams
                   ` (2 preceding siblings ...)
  2018-04-23 22:46 ` [PATCH 3/3] fetch: " Brandon Williams
@ 2018-04-23 22:47 ` Brandon Williams
  3 siblings, 0 replies; 5+ messages in thread
From: Brandon Williams @ 2018-04-23 22:47 UTC (permalink / raw)
  To: git

On 04/23, Brandon Williams wrote:
> Building on top of protocol version 2 this series adds the ability to
> optionally send server specific options when using protocol v2. This
> resembles the "push-options" feature except server options are sent as
> capability lines during a command request allowing for all current and
> future commands to benefit from sending arbitrary server options (and
> not requiring that sending server specific options be re-implemented for
> each and every command that may want to make use of them in the future).
> 
> These options can be provided by the user via the command line by giving
> "-o <option>" or "--server-option=<option>" to either ls-remote or
> fetch.
> 
> Command request example:
> 
> 	command=fetch
> 	server-option=hello
> 	server-option=world
> 	0001
> 	want A
> 	want B
> 	have X
> 	have Y
> 	0000
> 
> These options are only transmitted to the remote end when communicating
> using protocol version 2.

Forgot to mention that this series is based on current upstream master
(fe0a9eaf3) and a merge of origin/bw/protocol-v2.

> 
> Brandon Williams (3):
>   serve: introduce the server-option capability
>   ls-remote: send server options when using protocol v2
>   fetch: send server options when using protocol v2
> 
>  Documentation/fetch-options.txt         |  8 +++++++
>  Documentation/git-ls-remote.txt         |  8 +++++++
>  Documentation/technical/protocol-v2.txt | 10 ++++++++
>  builtin/fetch.c                         |  5 ++++
>  builtin/ls-remote.c                     |  4 ++++
>  connect.c                               |  9 ++++++-
>  fetch-pack.c                            |  7 ++++++
>  fetch-pack.h                            |  1 +
>  remote.h                                |  4 +++-
>  serve.c                                 |  1 +
>  t/t5701-git-serve.sh                    | 21 ++++++++++++++++
>  t/t5702-protocol-v2.sh                  | 32 +++++++++++++++++++++++++
>  transport.c                             |  3 ++-
>  transport.h                             |  6 +++++
>  14 files changed, 116 insertions(+), 3 deletions(-)
> 
> -- 
> 2.17.0.484.g0c8726318c-goog
> 

-- 
Brandon Williams

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-04-23 22:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-23 22:46 [PATCH 0/3] optionally send server-options when using v2 Brandon Williams
2018-04-23 22:46 ` [PATCH 1/3] serve: introduce the server-option capability Brandon Williams
2018-04-23 22:46 ` [PATCH 2/3] ls-remote: send server options when using protocol v2 Brandon Williams
2018-04-23 22:46 ` [PATCH 3/3] fetch: " Brandon Williams
2018-04-23 22:47 ` [PATCH 0/3] optionally send server-options when using v2 Brandon Williams

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).