1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-04 22:56:34 +02:00

Merge branch 'ab/serve-cleanup'

Code clean-up around "git serve".

* ab/serve-cleanup:
  upload-pack: document and rename --advertise-refs
  serve.[ch]: remove "serve_options", split up --advertise-refs code
  {upload,receive}-pack tests: add --advertise-refs tests
  serve.c: move version line to advertise_capabilities()
  serve: move transfer.advertiseSID check into session_id_advertise()
  serve.[ch]: don't pass "struct strvec *keys" to commands
  serve: use designated initializers
  transport: use designated initializers
  transport: rename "fetch" in transport_vtable to "fetch_refs"
  serve: mark has_capability() as static
This commit is contained in:
Junio C Hamano 2021-09-20 15:20:43 -07:00
commit 5331af2352
20 changed files with 298 additions and 128 deletions

View File

@ -41,6 +41,11 @@ OPTIONS
<directory>:: <directory>::
The repository to sync into. The repository to sync into.
--http-backend-info-refs::
Used by linkgit:git-http-backend[1] to serve up
`$GIT_URL/info/refs?service=git-receive-pack` requests. See
`--http-backend-info-refs` in linkgit:git-upload-pack[1].
PRE-RECEIVE HOOK PRE-RECEIVE HOOK
---------------- ----------------
Before any ref is updated, if $GIT_DIR/hooks/pre-receive file exists Before any ref is updated, if $GIT_DIR/hooks/pre-receive file exists

View File

@ -36,10 +36,14 @@ OPTIONS
This fits with the HTTP POST request processing model where This fits with the HTTP POST request processing model where
a program may read the request, write a response, and must exit. a program may read the request, write a response, and must exit.
--advertise-refs:: --http-backend-info-refs::
Only the initial ref advertisement is output, and the program exits Used by linkgit:git-http-backend[1] to serve up
immediately. This fits with the HTTP GET request model, where `$GIT_URL/info/refs?service=git-upload-pack` requests. See
no request content is received but a response must be produced. "Smart Clients" in link:technical/http-protocol.html[the HTTP
transfer protocols] documentation and "HTTP Transport" in
link:technical/protocol-v2.html[the Git Wire Protocol, Version
2] documentation. Also understood by
linkgit:git-receive-pack[1].
<directory>:: <directory>::
The repository to sync from. The repository to sync from.

View File

@ -225,6 +225,9 @@ The client may send Extra Parameters (see
Documentation/technical/pack-protocol.txt) as a colon-separated string Documentation/technical/pack-protocol.txt) as a colon-separated string
in the Git-Protocol HTTP header. in the Git-Protocol HTTP header.
Uses the `--http-backend-info-refs` option to
linkgit:git-upload-pack[1].
Dumb Server Response Dumb Server Response
^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
Dumb servers MUST respond with the dumb server reply format. Dumb servers MUST respond with the dumb server reply format.

View File

@ -81,6 +81,9 @@ A v2 server would reply:
Subsequent requests are then made directly to the service Subsequent requests are then made directly to the service
`$GIT_URL/git-upload-pack`. (This works the same for git-receive-pack). `$GIT_URL/git-upload-pack`. (This works the same for git-receive-pack).
Uses the `--http-backend-info-refs` option to
linkgit:git-upload-pack[1].
Capability Advertisement Capability Advertisement
------------------------ ------------------------

View File

@ -2474,7 +2474,8 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
struct option options[] = { struct option options[] = {
OPT__QUIET(&quiet, N_("quiet")), OPT__QUIET(&quiet, N_("quiet")),
OPT_HIDDEN_BOOL(0, "stateless-rpc", &stateless_rpc, NULL), OPT_HIDDEN_BOOL(0, "stateless-rpc", &stateless_rpc, NULL),
OPT_HIDDEN_BOOL(0, "advertise-refs", &advertise_refs, NULL), OPT_HIDDEN_BOOL(0, "http-backend-info-refs", &advertise_refs, NULL),
OPT_ALIAS(0, "advertise-refs", "http-backend-info-refs"),
OPT_HIDDEN_BOOL(0, "reject-thin-pack-for-testing", &reject_thin, NULL), OPT_HIDDEN_BOOL(0, "reject-thin-pack-for-testing", &reject_thin, NULL),
OPT_END() OPT_END()
}; };

View File

@ -16,16 +16,18 @@ int cmd_upload_pack(int argc, const char **argv, const char *prefix)
{ {
const char *dir; const char *dir;
int strict = 0; int strict = 0;
struct upload_pack_options opts = { 0 }; int advertise_refs = 0;
struct serve_options serve_opts = SERVE_OPTIONS_INIT; int stateless_rpc = 0;
int timeout = 0;
struct option options[] = { struct option options[] = {
OPT_BOOL(0, "stateless-rpc", &opts.stateless_rpc, OPT_BOOL(0, "stateless-rpc", &stateless_rpc,
N_("quit after a single request/response exchange")), N_("quit after a single request/response exchange")),
OPT_BOOL(0, "advertise-refs", &opts.advertise_refs, OPT_HIDDEN_BOOL(0, "http-backend-info-refs", &advertise_refs,
N_("exit immediately after initial ref advertisement")), N_("serve up the info/refs for git-http-backend")),
OPT_ALIAS(0, "advertise-refs", "http-backend-info-refs"),
OPT_BOOL(0, "strict", &strict, OPT_BOOL(0, "strict", &strict,
N_("do not try <directory>/.git/ if <directory> is no Git directory")), N_("do not try <directory>/.git/ if <directory> is no Git directory")),
OPT_INTEGER(0, "timeout", &opts.timeout, OPT_INTEGER(0, "timeout", &timeout,
N_("interrupt transfer after <n> seconds of inactivity")), N_("interrupt transfer after <n> seconds of inactivity")),
OPT_END() OPT_END()
}; };
@ -38,9 +40,6 @@ int cmd_upload_pack(int argc, const char **argv, const char *prefix)
if (argc != 1) if (argc != 1)
usage_with_options(upload_pack_usage, options); usage_with_options(upload_pack_usage, options);
if (opts.timeout)
opts.daemon_mode = 1;
setup_path(); setup_path();
dir = argv[0]; dir = argv[0];
@ -50,21 +49,22 @@ int cmd_upload_pack(int argc, const char **argv, const char *prefix)
switch (determine_protocol_version_server()) { switch (determine_protocol_version_server()) {
case protocol_v2: case protocol_v2:
serve_opts.advertise_capabilities = opts.advertise_refs; if (advertise_refs)
serve_opts.stateless_rpc = opts.stateless_rpc; protocol_v2_advertise_capabilities();
serve(&serve_opts); else
protocol_v2_serve_loop(stateless_rpc);
break; break;
case protocol_v1: case protocol_v1:
/* /*
* v1 is just the original protocol with a version string, * v1 is just the original protocol with a version string,
* so just fall through after writing the version string. * so just fall through after writing the version string.
*/ */
if (opts.advertise_refs || !opts.stateless_rpc) if (advertise_refs || !stateless_rpc)
packet_write_fmt(1, "version 1\n"); packet_write_fmt(1, "version 1\n");
/* fallthrough */ /* fallthrough */
case protocol_v0: case protocol_v0:
upload_pack(&opts); upload_pack(advertise_refs, stateless_rpc, timeout);
break; break;
case protocol_unknown_version: case protocol_unknown_version:
BUG("unknown protocol version"); BUG("unknown protocol version");

View File

@ -534,7 +534,7 @@ static void get_info_refs(struct strbuf *hdr, char *arg)
if (service_name) { if (service_name) {
const char *argv[] = {NULL /* service name */, const char *argv[] = {NULL /* service name */,
"--stateless-rpc", "--advertise-refs", "--http-backend-info-refs",
".", NULL}; ".", NULL};
struct rpc_service *svc = select_service(hdr, service_name); struct rpc_service *svc = select_service(hdr, service_name);

View File

@ -139,8 +139,7 @@ static int ls_refs_config(const char *var, const char *value, void *data)
return parse_hide_refs_config(var, value, "uploadpack"); return parse_hide_refs_config(var, value, "uploadpack");
} }
int ls_refs(struct repository *r, struct strvec *keys, int ls_refs(struct repository *r, struct packet_reader *request)
struct packet_reader *request)
{ {
struct ls_refs_data data; struct ls_refs_data data;

View File

@ -2,10 +2,8 @@
#define LS_REFS_H #define LS_REFS_H
struct repository; struct repository;
struct strvec;
struct packet_reader; struct packet_reader;
int ls_refs(struct repository *r, struct strvec *keys, int ls_refs(struct repository *r, struct packet_reader *request);
struct packet_reader *request);
int ls_refs_advertise(struct repository *r, struct strbuf *value); int ls_refs_advertise(struct repository *r, struct strbuf *value);
#endif /* LS_REFS_H */ #endif /* LS_REFS_H */

View File

@ -75,8 +75,7 @@ static void send_info(struct repository *r, struct packet_writer *writer,
strbuf_release(&send_buffer); strbuf_release(&send_buffer);
} }
int cap_object_info(struct repository *r, struct strvec *keys, int cap_object_info(struct repository *r, struct packet_reader *request)
struct packet_reader *request)
{ {
struct requested_info info; struct requested_info info;
struct packet_writer writer; struct packet_writer writer;

View File

@ -2,9 +2,7 @@
#define PROTOCOL_CAPS_H #define PROTOCOL_CAPS_H
struct repository; struct repository;
struct strvec;
struct packet_reader; struct packet_reader;
int cap_object_info(struct repository *r, struct strvec *keys, int cap_object_info(struct repository *r, struct packet_reader *request);
struct packet_reader *request);
#endif /* PROTOCOL_CAPS_H */ #endif /* PROTOCOL_CAPS_H */

82
serve.c
View File

@ -9,7 +9,7 @@
#include "serve.h" #include "serve.h"
#include "upload-pack.h" #include "upload-pack.h"
static int advertise_sid; static int advertise_sid = -1;
static int always_advertise(struct repository *r, static int always_advertise(struct repository *r,
struct strbuf *value) struct strbuf *value)
@ -35,6 +35,9 @@ static int object_format_advertise(struct repository *r,
static int session_id_advertise(struct repository *r, struct strbuf *value) static int session_id_advertise(struct repository *r, struct strbuf *value)
{ {
if (advertise_sid == -1 &&
git_config_get_bool("transfer.advertisesid", &advertise_sid))
advertise_sid = 0;
if (!advertise_sid) if (!advertise_sid)
return 0; return 0;
if (value) if (value)
@ -60,34 +63,58 @@ struct protocol_capability {
/* /*
* Function called when a client requests the capability as a command. * Function called when a client requests the capability as a command.
* The function will be provided the capabilities requested via 'keys' * Will be provided a struct packet_reader 'request' which it should
* as well as a struct packet_reader 'request' which the command should
* use to read the command specific part of the request. Every command * use to read the command specific part of the request. Every command
* MUST read until a flush packet is seen before sending a response. * MUST read until a flush packet is seen before sending a response.
* *
* This field should be NULL for capabilities which are not commands. * This field should be NULL for capabilities which are not commands.
*/ */
int (*command)(struct repository *r, int (*command)(struct repository *r, struct packet_reader *request);
struct strvec *keys,
struct packet_reader *request);
}; };
static struct protocol_capability capabilities[] = { static struct protocol_capability capabilities[] = {
{ "agent", agent_advertise, NULL }, {
{ "ls-refs", ls_refs_advertise, ls_refs }, .name = "agent",
{ "fetch", upload_pack_advertise, upload_pack_v2 }, .advertise = agent_advertise,
{ "server-option", always_advertise, NULL }, },
{ "object-format", object_format_advertise, NULL }, {
{ "session-id", session_id_advertise, NULL }, .name = "ls-refs",
{ "object-info", always_advertise, cap_object_info }, .advertise = ls_refs_advertise,
.command = ls_refs,
},
{
.name = "fetch",
.advertise = upload_pack_advertise,
.command = upload_pack_v2,
},
{
.name = "server-option",
.advertise = always_advertise,
},
{
.name = "object-format",
.advertise = object_format_advertise,
},
{
.name = "session-id",
.advertise = session_id_advertise,
},
{
.name = "object-info",
.advertise = always_advertise,
.command = cap_object_info,
},
}; };
static void advertise_capabilities(void) void protocol_v2_advertise_capabilities(void)
{ {
struct strbuf capability = STRBUF_INIT; struct strbuf capability = STRBUF_INIT;
struct strbuf value = STRBUF_INIT; struct strbuf value = STRBUF_INIT;
int i; int i;
/* serve by default supports v2 */
packet_write_fmt(1, "version 2\n");
for (i = 0; i < ARRAY_SIZE(capabilities); i++) { for (i = 0; i < ARRAY_SIZE(capabilities); i++) {
struct protocol_capability *c = &capabilities[i]; struct protocol_capability *c = &capabilities[i];
@ -156,8 +183,8 @@ static int is_command(const char *key, struct protocol_capability **command)
return 0; return 0;
} }
int has_capability(const struct strvec *keys, const char *capability, static int has_capability(const struct strvec *keys, const char *capability,
const char **value) const char **value)
{ {
int i; int i;
for (i = 0; i < keys->nr; i++) { for (i = 0; i < keys->nr; i++) {
@ -270,35 +297,22 @@ static int process_request(void)
if (has_capability(&keys, "session-id", &client_sid)) if (has_capability(&keys, "session-id", &client_sid))
trace2_data_string("transfer", NULL, "client-sid", client_sid); trace2_data_string("transfer", NULL, "client-sid", client_sid);
command->command(the_repository, &keys, &reader); command->command(the_repository, &reader);
strvec_clear(&keys); strvec_clear(&keys);
return 0; return 0;
} }
/* Main serve loop for protocol version 2 */ void protocol_v2_serve_loop(int stateless_rpc)
void serve(struct serve_options *options)
{ {
git_config_get_bool("transfer.advertisesid", &advertise_sid); if (!stateless_rpc)
protocol_v2_advertise_capabilities();
if (options->advertise_capabilities || !options->stateless_rpc) {
/* serve by default supports v2 */
packet_write_fmt(1, "version 2\n");
advertise_capabilities();
/*
* If only the list of capabilities was requested exit
* immediately after advertising capabilities
*/
if (options->advertise_capabilities)
return;
}
/* /*
* If stateless-rpc was requested then exit after * If stateless-rpc was requested then exit after
* a single request/response exchange * a single request/response exchange
*/ */
if (options->stateless_rpc) { if (stateless_rpc) {
process_request(); process_request();
} else { } else {
for (;;) for (;;)

12
serve.h
View File

@ -1,15 +1,7 @@
#ifndef SERVE_H #ifndef SERVE_H
#define SERVE_H #define SERVE_H
struct strvec; void protocol_v2_advertise_capabilities(void);
int has_capability(const struct strvec *keys, const char *capability, void protocol_v2_serve_loop(int stateless_rpc);
const char **value);
struct serve_options {
unsigned advertise_capabilities;
unsigned stateless_rpc;
};
#define SERVE_OPTIONS_INIT { 0 }
void serve(struct serve_options *options);
#endif /* SERVE_H */ #endif /* SERVE_H */

View File

@ -10,12 +10,12 @@ static char const * const serve_usage[] = {
int cmd__serve_v2(int argc, const char **argv) int cmd__serve_v2(int argc, const char **argv)
{ {
struct serve_options opts = SERVE_OPTIONS_INIT; int stateless_rpc = 0;
int advertise_capabilities = 0;
struct option options[] = { struct option options[] = {
OPT_BOOL(0, "stateless-rpc", &opts.stateless_rpc, OPT_BOOL(0, "stateless-rpc", &stateless_rpc,
N_("quit after a single request/response exchange")), N_("quit after a single request/response exchange")),
OPT_BOOL(0, "advertise-capabilities", &opts.advertise_capabilities, OPT_BOOL(0, "advertise-capabilities", &advertise_capabilities,
N_("exit immediately after advertising capabilities")), N_("exit immediately after advertising capabilities")),
OPT_END() OPT_END()
}; };
@ -25,7 +25,11 @@ int cmd__serve_v2(int argc, const char **argv)
argc = parse_options(argc, argv, prefix, options, serve_usage, argc = parse_options(argc, argv, prefix, options, serve_usage,
PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_DASHDASH |
PARSE_OPT_KEEP_UNKNOWN); PARSE_OPT_KEEP_UNKNOWN);
serve(&opts);
if (advertise_capabilities)
protocol_v2_advertise_capabilities();
else
protocol_v2_serve_loop(stateless_rpc);
return 0; return 0;
} }

161
t/t5555-http-smart-common.sh Executable file
View File

@ -0,0 +1,161 @@
#!/bin/sh
test_description='test functionality common to smart fetch & push'
. ./test-lib.sh
test_expect_success 'setup' '
test_commit --no-tag initial
'
test_expect_success 'git upload-pack --http-backend-info-refs and --advertise-refs are aliased' '
git upload-pack --http-backend-info-refs . >expected 2>err.expected &&
git upload-pack --advertise-refs . >actual 2>err.actual &&
test_cmp err.expected err.actual &&
test_cmp expected actual
'
test_expect_success 'git receive-pack --http-backend-info-refs and --advertise-refs are aliased' '
git receive-pack --http-backend-info-refs . >expected 2>err.expected &&
git receive-pack --advertise-refs . >actual 2>err.actual &&
test_cmp err.expected err.actual &&
test_cmp expected actual
'
test_expect_success 'git upload-pack --advertise-refs' '
cat >expect <<-EOF &&
$(git rev-parse HEAD) HEAD
$(git rev-parse HEAD) $(git symbolic-ref HEAD)
0000
EOF
# We only care about GIT_PROTOCOL, not GIT_TEST_PROTOCOL_VERSION
sane_unset GIT_PROTOCOL &&
GIT_TEST_PROTOCOL_VERSION=2 \
git upload-pack --advertise-refs . >out 2>err &&
test-tool pkt-line unpack <out >actual &&
test_must_be_empty err &&
test_cmp actual expect &&
# The --advertise-refs alias works
git upload-pack --advertise-refs . >out 2>err &&
test-tool pkt-line unpack <out >actual &&
test_must_be_empty err &&
test_cmp actual expect
'
test_expect_success 'git upload-pack --advertise-refs: v0' '
# With no specified protocol
cat >expect <<-EOF &&
$(git rev-parse HEAD) HEAD
$(git rev-parse HEAD) $(git symbolic-ref HEAD)
0000
EOF
git upload-pack --advertise-refs . >out 2>err &&
test-tool pkt-line unpack <out >actual &&
test_must_be_empty err &&
test_cmp actual expect &&
# With explicit v0
GIT_PROTOCOL=version=0 \
git upload-pack --advertise-refs . >out 2>err &&
test-tool pkt-line unpack <out >actual 2>err &&
test_must_be_empty err &&
test_cmp actual expect
'
test_expect_success 'git receive-pack --advertise-refs: v0' '
# With no specified protocol
cat >expect <<-EOF &&
$(git rev-parse HEAD) $(git symbolic-ref HEAD)
0000
EOF
git receive-pack --advertise-refs . >out 2>err &&
test-tool pkt-line unpack <out >actual &&
test_must_be_empty err &&
test_cmp actual expect &&
# With explicit v0
GIT_PROTOCOL=version=0 \
git receive-pack --advertise-refs . >out 2>err &&
test-tool pkt-line unpack <out >actual 2>err &&
test_must_be_empty err &&
test_cmp actual expect
'
test_expect_success 'git upload-pack --advertise-refs: v1' '
# With no specified protocol
cat >expect <<-EOF &&
version 1
$(git rev-parse HEAD) HEAD
$(git rev-parse HEAD) $(git symbolic-ref HEAD)
0000
EOF
GIT_PROTOCOL=version=1 \
git upload-pack --advertise-refs . >out &&
test-tool pkt-line unpack <out >actual 2>err &&
test_must_be_empty err &&
test_cmp actual expect
'
test_expect_success 'git receive-pack --advertise-refs: v1' '
# With no specified protocol
cat >expect <<-EOF &&
version 1
$(git rev-parse HEAD) $(git symbolic-ref HEAD)
0000
EOF
GIT_PROTOCOL=version=1 \
git receive-pack --advertise-refs . >out &&
test-tool pkt-line unpack <out >actual 2>err &&
test_must_be_empty err &&
test_cmp actual expect
'
test_expect_success 'git upload-pack --advertise-refs: v2' '
cat >expect <<-EOF &&
version 2
agent=FAKE
ls-refs=unborn
fetch=shallow wait-for-done
server-option
object-format=$(test_oid algo)
object-info
0000
EOF
GIT_PROTOCOL=version=2 \
GIT_USER_AGENT=FAKE \
git upload-pack --advertise-refs . >out 2>err &&
test-tool pkt-line unpack <out >actual &&
test_must_be_empty err &&
test_cmp actual expect
'
test_expect_success 'git receive-pack --advertise-refs: v2' '
# There is no v2 yet for receive-pack, implicit v0
cat >expect <<-EOF &&
$(git rev-parse HEAD) $(git symbolic-ref HEAD)
0000
EOF
GIT_PROTOCOL=version=2 \
git receive-pack --advertise-refs . >out 2>err &&
test-tool pkt-line unpack <out >actual &&
test_must_be_empty err &&
test_cmp actual expect
'
test_done

View File

@ -671,8 +671,8 @@ static int connect_helper(struct transport *transport, const char *name,
static struct ref *get_refs_list_using_list(struct transport *transport, static struct ref *get_refs_list_using_list(struct transport *transport,
int for_push); int for_push);
static int fetch(struct transport *transport, static int fetch_refs(struct transport *transport,
int nr_heads, struct ref **to_fetch) int nr_heads, struct ref **to_fetch)
{ {
struct helper_data *data = transport->data; struct helper_data *data = transport->data;
int i, count; int i, count;
@ -681,7 +681,7 @@ static int fetch(struct transport *transport,
if (process_connect(transport, 0)) { if (process_connect(transport, 0)) {
do_take_over(transport); do_take_over(transport);
return transport->vtable->fetch(transport, nr_heads, to_fetch); return transport->vtable->fetch_refs(transport, nr_heads, to_fetch);
} }
/* /*
@ -1261,12 +1261,12 @@ static struct ref *get_refs_list_using_list(struct transport *transport,
} }
static struct transport_vtable vtable = { static struct transport_vtable vtable = {
set_helper_option, .set_option = set_helper_option,
get_refs_list, .get_refs_list = get_refs_list,
fetch, .fetch_refs = fetch_refs,
push_refs, .push_refs = push_refs,
connect_helper, .connect = connect_helper,
release_helper .disconnect = release_helper
}; };
int transport_helper_init(struct transport *transport, const char *name) int transport_helper_init(struct transport *transport, const char *name)

View File

@ -34,7 +34,7 @@ struct transport_vtable {
* get_refs_list(), it should set the old_sha1 fields in the * get_refs_list(), it should set the old_sha1 fields in the
* provided refs now. * provided refs now.
**/ **/
int (*fetch)(struct transport *transport, int refs_nr, struct ref **refs); int (*fetch_refs)(struct transport *transport, int refs_nr, struct ref **refs);
/** /**
* Push the objects and refs. Send the necessary objects, and * Push the objects and refs. Send the necessary objects, and

View File

@ -887,12 +887,10 @@ static int disconnect_git(struct transport *transport)
} }
static struct transport_vtable taken_over_vtable = { static struct transport_vtable taken_over_vtable = {
NULL, .get_refs_list = get_refs_via_connect,
get_refs_via_connect, .fetch_refs = fetch_refs_via_pack,
fetch_refs_via_pack, .push_refs = git_transport_push,
git_transport_push, .disconnect = disconnect_git
NULL,
disconnect_git
}; };
void transport_take_over(struct transport *transport, void transport_take_over(struct transport *transport,
@ -1036,21 +1034,17 @@ void transport_check_allowed(const char *type)
} }
static struct transport_vtable bundle_vtable = { static struct transport_vtable bundle_vtable = {
NULL, .get_refs_list = get_refs_from_bundle,
get_refs_from_bundle, .fetch_refs = fetch_refs_from_bundle,
fetch_refs_from_bundle, .disconnect = close_bundle
NULL,
NULL,
close_bundle
}; };
static struct transport_vtable builtin_smart_vtable = { static struct transport_vtable builtin_smart_vtable = {
NULL, .get_refs_list = get_refs_via_connect,
get_refs_via_connect, .fetch_refs = fetch_refs_via_pack,
fetch_refs_via_pack, .push_refs = git_transport_push,
git_transport_push, .connect = connect_git,
connect_git, .disconnect = disconnect_git
disconnect_git
}; };
struct transport *transport_get(struct remote *remote, const char *url) struct transport *transport_get(struct remote *remote, const char *url)
@ -1457,7 +1451,7 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs)
heads[nr_heads++] = rm; heads[nr_heads++] = rm;
} }
rc = transport->vtable->fetch(transport, nr_heads, heads); rc = transport->vtable->fetch_refs(transport, nr_heads, heads);
free(heads); free(heads);
return rc; return rc;

View File

@ -1214,7 +1214,7 @@ static int send_ref(const char *refname, const struct object_id *oid,
" allow-tip-sha1-in-want" : "", " allow-tip-sha1-in-want" : "",
(data->allow_uor & ALLOW_REACHABLE_SHA1) ? (data->allow_uor & ALLOW_REACHABLE_SHA1) ?
" allow-reachable-sha1-in-want" : "", " allow-reachable-sha1-in-want" : "",
data->stateless_rpc ? " no-done" : "", data->no_done ? " no-done" : "",
symref_info.buf, symref_info.buf,
data->allow_filter ? " filter" : "", data->allow_filter ? " filter" : "",
session_id.buf, session_id.buf,
@ -1329,7 +1329,8 @@ static int upload_pack_config(const char *var, const char *value, void *cb_data)
return parse_hide_refs_config(var, value, "uploadpack"); return parse_hide_refs_config(var, value, "uploadpack");
} }
void upload_pack(struct upload_pack_options *options) void upload_pack(const int advertise_refs, const int stateless_rpc,
const int timeout)
{ {
struct packet_reader reader; struct packet_reader reader;
struct upload_pack_data data; struct upload_pack_data data;
@ -1338,14 +1339,17 @@ void upload_pack(struct upload_pack_options *options)
git_config(upload_pack_config, &data); git_config(upload_pack_config, &data);
data.stateless_rpc = options->stateless_rpc; data.stateless_rpc = stateless_rpc;
data.daemon_mode = options->daemon_mode; data.timeout = timeout;
data.timeout = options->timeout; if (data.timeout)
data.daemon_mode = 1;
head_ref_namespaced(find_symref, &data.symref); head_ref_namespaced(find_symref, &data.symref);
if (options->advertise_refs || !data.stateless_rpc) { if (advertise_refs || !data.stateless_rpc) {
reset_timeout(data.timeout); reset_timeout(data.timeout);
if (advertise_refs)
data.no_done = 1;
head_ref_namespaced(send_ref, &data); head_ref_namespaced(send_ref, &data);
for_each_namespaced_ref(send_ref, &data); for_each_namespaced_ref(send_ref, &data);
/* /*
@ -1360,7 +1364,7 @@ void upload_pack(struct upload_pack_options *options)
for_each_namespaced_ref(check_ref, NULL); for_each_namespaced_ref(check_ref, NULL);
} }
if (!options->advertise_refs) { if (!advertise_refs) {
packet_reader_init(&reader, 0, NULL, 0, packet_reader_init(&reader, 0, NULL, 0,
PACKET_READ_CHOMP_NEWLINE | PACKET_READ_CHOMP_NEWLINE |
PACKET_READ_DIE_ON_ERR_PACKET); PACKET_READ_DIE_ON_ERR_PACKET);
@ -1664,8 +1668,7 @@ enum fetch_state {
FETCH_DONE, FETCH_DONE,
}; };
int upload_pack_v2(struct repository *r, struct strvec *keys, int upload_pack_v2(struct repository *r, struct packet_reader *request)
struct packet_reader *request)
{ {
enum fetch_state state = FETCH_PROCESS_ARGS; enum fetch_state state = FETCH_PROCESS_ARGS;
struct upload_pack_data data; struct upload_pack_data data;

View File

@ -1,20 +1,12 @@
#ifndef UPLOAD_PACK_H #ifndef UPLOAD_PACK_H
#define UPLOAD_PACK_H #define UPLOAD_PACK_H
struct upload_pack_options { void upload_pack(const int advertise_refs, const int stateless_rpc,
int stateless_rpc; const int timeout);
int advertise_refs;
unsigned int timeout;
int daemon_mode;
};
void upload_pack(struct upload_pack_options *options);
struct repository; struct repository;
struct strvec;
struct packet_reader; struct packet_reader;
int upload_pack_v2(struct repository *r, struct strvec *keys, int upload_pack_v2(struct repository *r, struct packet_reader *request);
struct packet_reader *request);
struct strbuf; struct strbuf;
int upload_pack_advertise(struct repository *r, int upload_pack_advertise(struct repository *r,