Merge branch 'bw/protocol-v2'

The beginning of the next-gen transfer protocol.

* bw/protocol-v2: (35 commits)
  remote-curl: don't request v2 when pushing
  remote-curl: implement stateless-connect command
  http: eliminate "# service" line when using protocol v2
  http: don't always add Git-Protocol header
  http: allow providing extra headers for http requests
  remote-curl: store the protocol version the server responded with
  remote-curl: create copy of the service name
  pkt-line: add packet_buf_write_len function
  transport-helper: introduce stateless-connect
  transport-helper: refactor process_connect_service
  transport-helper: remove name parameter
  connect: don't request v2 when pushing
  connect: refactor git_connect to only get the protocol version once
  fetch-pack: support shallow requests
  fetch-pack: perform a fetch using v2
  upload-pack: introduce fetch server command
  push: pass ref prefixes when pushing
  fetch: pass ref prefixes when fetching
  ls-remote: pass ref prefixes when requesting a remote's refs
  transport: convert transport_get_remote_refs to take a list of ref prefixes
  ...
This commit is contained in:
Junio C Hamano
2018-05-08 15:59:15 +09:00
44 changed files with 3326 additions and 376 deletions

View File

@ -12,6 +12,7 @@
#include "argv-array.h"
#include "refs.h"
#include "transport-internal.h"
#include "protocol.h"
static int debug;
@ -26,6 +27,7 @@ struct helper_data {
option : 1,
push : 1,
connect : 1,
stateless_connect : 1,
signed_tags : 1,
check_connectivity : 1,
no_disconnect_req : 1,
@ -49,7 +51,7 @@ static void sendline(struct helper_data *helper, struct strbuf *buffer)
die_errno("Full write to remote helper failed");
}
static int recvline_fh(FILE *helper, struct strbuf *buffer, const char *name)
static int recvline_fh(FILE *helper, struct strbuf *buffer)
{
strbuf_reset(buffer);
if (debug)
@ -67,7 +69,7 @@ static int recvline_fh(FILE *helper, struct strbuf *buffer, const char *name)
static int recvline(struct helper_data *helper, struct strbuf *buffer)
{
return recvline_fh(helper->out, buffer, helper->name);
return recvline_fh(helper->out, buffer);
}
static void write_constant(int fd, const char *str)
@ -188,6 +190,8 @@ static struct child_process *get_helper(struct transport *transport)
refspecs[refspec_nr++] = xstrdup(arg);
} else if (!strcmp(capname, "connect")) {
data->connect = 1;
} else if (!strcmp(capname, "stateless-connect")) {
data->stateless_connect = 1;
} else if (!strcmp(capname, "signed-tags")) {
data->signed_tags = 1;
} else if (skip_prefix(capname, "export-marks ", &arg)) {
@ -545,14 +549,13 @@ static int fetch_with_import(struct transport *transport,
return 0;
}
static int process_connect_service(struct transport *transport,
const char *name, const char *exec)
static int run_connect(struct transport *transport, struct strbuf *cmdbuf)
{
struct helper_data *data = transport->data;
struct strbuf cmdbuf = STRBUF_INIT;
struct child_process *helper;
int r, duped, ret = 0;
int ret = 0;
int duped;
FILE *input;
struct child_process *helper;
helper = get_helper(transport);
@ -568,44 +571,61 @@ static int process_connect_service(struct transport *transport,
input = xfdopen(duped, "r");
setvbuf(input, NULL, _IONBF, 0);
sendline(data, cmdbuf);
if (recvline_fh(input, cmdbuf))
exit(128);
if (!strcmp(cmdbuf->buf, "")) {
data->no_disconnect_req = 1;
if (debug)
fprintf(stderr, "Debug: Smart transport connection "
"ready.\n");
ret = 1;
} else if (!strcmp(cmdbuf->buf, "fallback")) {
if (debug)
fprintf(stderr, "Debug: Falling back to dumb "
"transport.\n");
} else {
die("Unknown response to connect: %s",
cmdbuf->buf);
}
fclose(input);
return ret;
}
static int process_connect_service(struct transport *transport,
const char *name, const char *exec)
{
struct helper_data *data = transport->data;
struct strbuf cmdbuf = STRBUF_INIT;
int ret = 0;
/*
* Handle --upload-pack and friends. This is fire and forget...
* just warn if it fails.
*/
if (strcmp(name, exec)) {
r = set_helper_option(transport, "servpath", exec);
int r = set_helper_option(transport, "servpath", exec);
if (r > 0)
warning("Setting remote service path not supported by protocol.");
else if (r < 0)
warning("Invalid remote service path.");
}
if (data->connect)
if (data->connect) {
strbuf_addf(&cmdbuf, "connect %s\n", name);
else
goto exit;
ret = run_connect(transport, &cmdbuf);
} else if (data->stateless_connect &&
(get_protocol_version_config() == protocol_v2) &&
!strcmp("git-upload-pack", name)) {
strbuf_addf(&cmdbuf, "stateless-connect %s\n", name);
ret = run_connect(transport, &cmdbuf);
if (ret)
transport->stateless_rpc = 1;
}
sendline(data, &cmdbuf);
if (recvline_fh(input, &cmdbuf, name))
exit(128);
if (!strcmp(cmdbuf.buf, "")) {
data->no_disconnect_req = 1;
if (debug)
fprintf(stderr, "Debug: Smart transport connection "
"ready.\n");
ret = 1;
} else if (!strcmp(cmdbuf.buf, "fallback")) {
if (debug)
fprintf(stderr, "Debug: Falling back to dumb "
"transport.\n");
} else
die("Unknown response to connect: %s",
cmdbuf.buf);
exit:
strbuf_release(&cmdbuf);
fclose(input);
return ret;
}
@ -1031,7 +1051,8 @@ static int has_attribute(const char *attrs, const char *attr) {
}
}
static struct ref *get_refs_list(struct transport *transport, int for_push)
static struct ref *get_refs_list(struct transport *transport, int for_push,
const struct argv_array *ref_prefixes)
{
struct helper_data *data = transport->data;
struct child_process *helper;
@ -1044,7 +1065,7 @@ static struct ref *get_refs_list(struct transport *transport, int for_push)
if (process_connect(transport, for_push)) {
do_take_over(transport);
return transport->vtable->get_refs_list(transport, for_push);
return transport->vtable->get_refs_list(transport, for_push, ref_prefixes);
}
if (data->push && for_push)