зеркало из https://github.com/microsoft/git.git
Use packet_reader instead of packet_read_line
By using and sharing a packet_reader while handling a Git pack protocol request, the same reader option is used throughout the code. This makes it easy to set a reader option to the request parsing code. Signed-off-by: Masaya Suzuki <masayasuzuki@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
b21ebb671b
Коммит
01f9ec64c8
|
@ -27,10 +27,10 @@ static int run_remote_archiver(int argc, const char **argv,
|
|||
const char *remote, const char *exec,
|
||||
const char *name_hint)
|
||||
{
|
||||
char *buf;
|
||||
int fd[2], i, rv;
|
||||
struct transport *transport;
|
||||
struct remote *_remote;
|
||||
struct packet_reader reader;
|
||||
|
||||
_remote = remote_get(remote);
|
||||
if (!_remote->url[0])
|
||||
|
@ -53,18 +53,19 @@ static int run_remote_archiver(int argc, const char **argv,
|
|||
packet_write_fmt(fd[1], "argument %s\n", argv[i]);
|
||||
packet_flush(fd[1]);
|
||||
|
||||
buf = packet_read_line(fd[0], NULL);
|
||||
if (!buf)
|
||||
packet_reader_init(&reader, fd[0], NULL, 0, PACKET_READ_CHOMP_NEWLINE);
|
||||
|
||||
if (packet_reader_read(&reader) != PACKET_READ_NORMAL)
|
||||
die(_("git archive: expected ACK/NAK, got a flush packet"));
|
||||
if (strcmp(buf, "ACK")) {
|
||||
if (starts_with(buf, "NACK "))
|
||||
die(_("git archive: NACK %s"), buf + 5);
|
||||
if (starts_with(buf, "ERR "))
|
||||
die(_("remote error: %s"), buf + 4);
|
||||
if (strcmp(reader.line, "ACK")) {
|
||||
if (starts_with(reader.line, "NACK "))
|
||||
die(_("git archive: NACK %s"), reader.line + 5);
|
||||
if (starts_with(reader.line, "ERR "))
|
||||
die(_("remote error: %s"), reader.line + 4);
|
||||
die(_("git archive: protocol error"));
|
||||
}
|
||||
|
||||
if (packet_read_line(fd[0], NULL))
|
||||
if (packet_reader_read(&reader) != PACKET_READ_FLUSH)
|
||||
die(_("git archive: expected a flush"));
|
||||
|
||||
/* Now, start reading from fd[0] and spit it out to stdout */
|
||||
|
|
|
@ -1569,30 +1569,29 @@ static void queue_commands_from_cert(struct command **tail,
|
|||
}
|
||||
}
|
||||
|
||||
static struct command *read_head_info(struct oid_array *shallow)
|
||||
static struct command *read_head_info(struct packet_reader *reader,
|
||||
struct oid_array *shallow)
|
||||
{
|
||||
struct command *commands = NULL;
|
||||
struct command **p = &commands;
|
||||
for (;;) {
|
||||
char *line;
|
||||
int len, linelen;
|
||||
int linelen;
|
||||
|
||||
line = packet_read_line(0, &len);
|
||||
if (!line)
|
||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||
break;
|
||||
|
||||
if (len > 8 && starts_with(line, "shallow ")) {
|
||||
if (reader->pktlen > 8 && starts_with(reader->line, "shallow ")) {
|
||||
struct object_id oid;
|
||||
if (get_oid_hex(line + 8, &oid))
|
||||
if (get_oid_hex(reader->line + 8, &oid))
|
||||
die("protocol error: expected shallow sha, got '%s'",
|
||||
line + 8);
|
||||
reader->line + 8);
|
||||
oid_array_append(shallow, &oid);
|
||||
continue;
|
||||
}
|
||||
|
||||
linelen = strlen(line);
|
||||
if (linelen < len) {
|
||||
const char *feature_list = line + linelen + 1;
|
||||
linelen = strlen(reader->line);
|
||||
if (linelen < reader->pktlen) {
|
||||
const char *feature_list = reader->line + linelen + 1;
|
||||
if (parse_feature_request(feature_list, "report-status"))
|
||||
report_status = 1;
|
||||
if (parse_feature_request(feature_list, "side-band-64k"))
|
||||
|
@ -1607,28 +1606,32 @@ static struct command *read_head_info(struct oid_array *shallow)
|
|||
use_push_options = 1;
|
||||
}
|
||||
|
||||
if (!strcmp(line, "push-cert")) {
|
||||
if (!strcmp(reader->line, "push-cert")) {
|
||||
int true_flush = 0;
|
||||
char certbuf[1024];
|
||||
int saved_options = reader->options;
|
||||
reader->options &= ~PACKET_READ_CHOMP_NEWLINE;
|
||||
|
||||
for (;;) {
|
||||
len = packet_read(0, NULL, NULL,
|
||||
certbuf, sizeof(certbuf), 0);
|
||||
if (!len) {
|
||||
packet_reader_read(reader);
|
||||
if (reader->status == PACKET_READ_FLUSH) {
|
||||
true_flush = 1;
|
||||
break;
|
||||
}
|
||||
if (!strcmp(certbuf, "push-cert-end\n"))
|
||||
if (reader->status != PACKET_READ_NORMAL) {
|
||||
die("protocol error: got an unexpected packet");
|
||||
}
|
||||
if (!strcmp(reader->line, "push-cert-end\n"))
|
||||
break; /* end of cert */
|
||||
strbuf_addstr(&push_cert, certbuf);
|
||||
strbuf_addstr(&push_cert, reader->line);
|
||||
}
|
||||
reader->options = saved_options;
|
||||
|
||||
if (true_flush)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
p = queue_command(p, line, linelen);
|
||||
p = queue_command(p, reader->line, linelen);
|
||||
}
|
||||
|
||||
if (push_cert.len)
|
||||
|
@ -1637,18 +1640,14 @@ static struct command *read_head_info(struct oid_array *shallow)
|
|||
return commands;
|
||||
}
|
||||
|
||||
static void read_push_options(struct string_list *options)
|
||||
static void read_push_options(struct packet_reader *reader,
|
||||
struct string_list *options)
|
||||
{
|
||||
while (1) {
|
||||
char *line;
|
||||
int len;
|
||||
|
||||
line = packet_read_line(0, &len);
|
||||
|
||||
if (!line)
|
||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||
break;
|
||||
|
||||
string_list_append(options, line);
|
||||
string_list_append(options, reader->line);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1924,6 +1923,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
|||
struct oid_array shallow = OID_ARRAY_INIT;
|
||||
struct oid_array ref = OID_ARRAY_INIT;
|
||||
struct shallow_info si;
|
||||
struct packet_reader reader;
|
||||
|
||||
struct option options[] = {
|
||||
OPT__QUIET(&quiet, N_("quiet")),
|
||||
|
@ -1986,12 +1986,14 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
|||
if (advertise_refs)
|
||||
return 0;
|
||||
|
||||
if ((commands = read_head_info(&shallow)) != NULL) {
|
||||
packet_reader_init(&reader, 0, NULL, 0, PACKET_READ_CHOMP_NEWLINE);
|
||||
|
||||
if ((commands = read_head_info(&reader, &shallow)) != NULL) {
|
||||
const char *unpack_status = NULL;
|
||||
struct string_list push_options = STRING_LIST_INIT_DUP;
|
||||
|
||||
if (use_push_options)
|
||||
read_push_options(&push_options);
|
||||
read_push_options(&reader, &push_options);
|
||||
if (!check_cert_push_options(&push_options)) {
|
||||
struct command *cmd;
|
||||
for (cmd = commands; cmd; cmd = cmd->next)
|
||||
|
|
61
fetch-pack.c
61
fetch-pack.c
|
@ -135,38 +135,42 @@ enum ack_type {
|
|||
ACK_ready
|
||||
};
|
||||
|
||||
static void consume_shallow_list(struct fetch_pack_args *args, int fd)
|
||||
static void consume_shallow_list(struct fetch_pack_args *args,
|
||||
struct packet_reader *reader)
|
||||
{
|
||||
if (args->stateless_rpc && args->deepen) {
|
||||
/* If we sent a depth we will get back "duplicate"
|
||||
* shallow and unshallow commands every time there
|
||||
* is a block of have lines exchanged.
|
||||
*/
|
||||
char *line;
|
||||
while ((line = packet_read_line(fd, NULL))) {
|
||||
if (starts_with(line, "shallow "))
|
||||
while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
|
||||
if (starts_with(reader->line, "shallow "))
|
||||
continue;
|
||||
if (starts_with(line, "unshallow "))
|
||||
if (starts_with(reader->line, "unshallow "))
|
||||
continue;
|
||||
die(_("git fetch-pack: expected shallow list"));
|
||||
}
|
||||
if (reader->status != PACKET_READ_FLUSH)
|
||||
die(_("git fetch-pack: expected a flush packet after shallow list"));
|
||||
}
|
||||
}
|
||||
|
||||
static enum ack_type get_ack(int fd, struct object_id *result_oid)
|
||||
static enum ack_type get_ack(struct packet_reader *reader,
|
||||
struct object_id *result_oid)
|
||||
{
|
||||
int len;
|
||||
char *line = packet_read_line(fd, &len);
|
||||
const char *arg;
|
||||
|
||||
if (!line)
|
||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||
die(_("git fetch-pack: expected ACK/NAK, got a flush packet"));
|
||||
if (!strcmp(line, "NAK"))
|
||||
len = reader->pktlen;
|
||||
|
||||
if (!strcmp(reader->line, "NAK"))
|
||||
return NAK;
|
||||
if (skip_prefix(line, "ACK ", &arg)) {
|
||||
if (skip_prefix(reader->line, "ACK ", &arg)) {
|
||||
if (!get_oid_hex(arg, result_oid)) {
|
||||
arg += 40;
|
||||
len -= arg - line;
|
||||
len -= arg - reader->line;
|
||||
if (len < 1)
|
||||
return ACK;
|
||||
if (strstr(arg, "continue"))
|
||||
|
@ -178,9 +182,9 @@ static enum ack_type get_ack(int fd, struct object_id *result_oid)
|
|||
return ACK;
|
||||
}
|
||||
}
|
||||
if (skip_prefix(line, "ERR ", &arg))
|
||||
if (skip_prefix(reader->line, "ERR ", &arg))
|
||||
die(_("remote error: %s"), arg);
|
||||
die(_("git fetch-pack: expected ACK/NAK, got '%s'"), line);
|
||||
die(_("git fetch-pack: expected ACK/NAK, got '%s'"), reader->line);
|
||||
}
|
||||
|
||||
static void send_request(struct fetch_pack_args *args,
|
||||
|
@ -248,10 +252,14 @@ static int find_common(struct fetch_negotiator *negotiator,
|
|||
int got_ready = 0;
|
||||
struct strbuf req_buf = STRBUF_INIT;
|
||||
size_t state_len = 0;
|
||||
struct packet_reader reader;
|
||||
|
||||
if (args->stateless_rpc && multi_ack == 1)
|
||||
die(_("--stateless-rpc requires multi_ack_detailed"));
|
||||
|
||||
packet_reader_init(&reader, fd[0], NULL, 0,
|
||||
PACKET_READ_CHOMP_NEWLINE);
|
||||
|
||||
if (!args->no_dependents) {
|
||||
mark_tips(negotiator, args->negotiation_tips);
|
||||
for_each_cached_alternate(negotiator, insert_one_alternate_object);
|
||||
|
@ -336,31 +344,30 @@ static int find_common(struct fetch_negotiator *negotiator,
|
|||
state_len = req_buf.len;
|
||||
|
||||
if (args->deepen) {
|
||||
char *line;
|
||||
const char *arg;
|
||||
struct object_id oid;
|
||||
|
||||
send_request(args, fd[1], &req_buf);
|
||||
while ((line = packet_read_line(fd[0], NULL))) {
|
||||
if (skip_prefix(line, "shallow ", &arg)) {
|
||||
while (packet_reader_read(&reader) == PACKET_READ_NORMAL) {
|
||||
if (skip_prefix(reader.line, "shallow ", &arg)) {
|
||||
if (get_oid_hex(arg, &oid))
|
||||
die(_("invalid shallow line: %s"), line);
|
||||
die(_("invalid shallow line: %s"), reader.line);
|
||||
register_shallow(the_repository, &oid);
|
||||
continue;
|
||||
}
|
||||
if (skip_prefix(line, "unshallow ", &arg)) {
|
||||
if (skip_prefix(reader.line, "unshallow ", &arg)) {
|
||||
if (get_oid_hex(arg, &oid))
|
||||
die(_("invalid unshallow line: %s"), line);
|
||||
die(_("invalid unshallow line: %s"), reader.line);
|
||||
if (!lookup_object(the_repository, oid.hash))
|
||||
die(_("object not found: %s"), line);
|
||||
die(_("object not found: %s"), reader.line);
|
||||
/* make sure that it is parsed as shallow */
|
||||
if (!parse_object(the_repository, &oid))
|
||||
die(_("error in object: %s"), line);
|
||||
die(_("error in object: %s"), reader.line);
|
||||
if (unregister_shallow(&oid))
|
||||
die(_("no shallow found: %s"), line);
|
||||
die(_("no shallow found: %s"), reader.line);
|
||||
continue;
|
||||
}
|
||||
die(_("expected shallow/unshallow, got %s"), line);
|
||||
die(_("expected shallow/unshallow, got %s"), reader.line);
|
||||
}
|
||||
} else if (!args->stateless_rpc)
|
||||
send_request(args, fd[1], &req_buf);
|
||||
|
@ -397,9 +404,9 @@ static int find_common(struct fetch_negotiator *negotiator,
|
|||
if (!args->stateless_rpc && count == INITIAL_FLUSH)
|
||||
continue;
|
||||
|
||||
consume_shallow_list(args, fd[0]);
|
||||
consume_shallow_list(args, &reader);
|
||||
do {
|
||||
ack = get_ack(fd[0], result_oid);
|
||||
ack = get_ack(&reader, result_oid);
|
||||
if (ack)
|
||||
print_verbose(args, _("got %s %d %s"), "ack",
|
||||
ack, oid_to_hex(result_oid));
|
||||
|
@ -469,9 +476,9 @@ done:
|
|||
strbuf_release(&req_buf);
|
||||
|
||||
if (!got_ready || !no_done)
|
||||
consume_shallow_list(args, fd[0]);
|
||||
consume_shallow_list(args, &reader);
|
||||
while (flushes || multi_ack) {
|
||||
int ack = get_ack(fd[0], result_oid);
|
||||
int ack = get_ack(&reader, result_oid);
|
||||
if (ack) {
|
||||
print_verbose(args, _("got %s (%d) %s"), "ack",
|
||||
ack, oid_to_hex(result_oid));
|
||||
|
|
|
@ -409,28 +409,36 @@ static struct discovery *discover_refs(const char *service, int for_push)
|
|||
if (maybe_smart &&
|
||||
(5 <= last->len && last->buf[4] == '#') &&
|
||||
!strbuf_cmp(&exp, &type)) {
|
||||
char *line;
|
||||
struct packet_reader reader;
|
||||
packet_reader_init(&reader, -1, last->buf, last->len,
|
||||
PACKET_READ_CHOMP_NEWLINE);
|
||||
|
||||
/*
|
||||
* smart HTTP response; validate that the service
|
||||
* pkt-line matches our request.
|
||||
*/
|
||||
line = packet_read_line_buf(&last->buf, &last->len, NULL);
|
||||
if (!line)
|
||||
if (packet_reader_read(&reader) != PACKET_READ_NORMAL)
|
||||
die("invalid server response; expected service, got flush packet");
|
||||
|
||||
strbuf_reset(&exp);
|
||||
strbuf_addf(&exp, "# service=%s", service);
|
||||
if (strcmp(line, exp.buf))
|
||||
die("invalid server response; got '%s'", line);
|
||||
if (strcmp(reader.line, exp.buf))
|
||||
die("invalid server response; got '%s'", reader.line);
|
||||
strbuf_release(&exp);
|
||||
|
||||
/* The header can include additional metadata lines, up
|
||||
* until a packet flush marker. Ignore these now, but
|
||||
* in the future we might start to scan them.
|
||||
*/
|
||||
while (packet_read_line_buf(&last->buf, &last->len, NULL))
|
||||
;
|
||||
for (;;) {
|
||||
packet_reader_read(&reader);
|
||||
if (reader.pktlen <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
last->buf = reader.src_buffer;
|
||||
last->len = reader.src_len;
|
||||
|
||||
last->proto_git = 1;
|
||||
} else if (maybe_smart &&
|
||||
|
|
37
send-pack.c
37
send-pack.c
|
@ -135,38 +135,36 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *extra, struc
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int receive_unpack_status(int in)
|
||||
static int receive_unpack_status(struct packet_reader *reader)
|
||||
{
|
||||
const char *line = packet_read_line(in, NULL);
|
||||
if (!line)
|
||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||
return error(_("unexpected flush packet while reading remote unpack status"));
|
||||
if (!skip_prefix(line, "unpack ", &line))
|
||||
return error(_("unable to parse remote unpack status: %s"), line);
|
||||
if (strcmp(line, "ok"))
|
||||
return error(_("remote unpack failed: %s"), line);
|
||||
if (!skip_prefix(reader->line, "unpack ", &reader->line))
|
||||
return error(_("unable to parse remote unpack status: %s"), reader->line);
|
||||
if (strcmp(reader->line, "ok"))
|
||||
return error(_("remote unpack failed: %s"), reader->line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int receive_status(int in, struct ref *refs)
|
||||
static int receive_status(struct packet_reader *reader, struct ref *refs)
|
||||
{
|
||||
struct ref *hint;
|
||||
int ret;
|
||||
|
||||
hint = NULL;
|
||||
ret = receive_unpack_status(in);
|
||||
ret = receive_unpack_status(reader);
|
||||
while (1) {
|
||||
char *refname;
|
||||
const char *refname;
|
||||
char *msg;
|
||||
char *line = packet_read_line(in, NULL);
|
||||
if (!line)
|
||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||
break;
|
||||
if (!starts_with(line, "ok ") && !starts_with(line, "ng ")) {
|
||||
error("invalid ref status from remote: %s", line);
|
||||
if (!starts_with(reader->line, "ok ") && !starts_with(reader->line, "ng ")) {
|
||||
error("invalid ref status from remote: %s", reader->line);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
refname = line + 3;
|
||||
refname = reader->line + 3;
|
||||
msg = strchr(refname, ' ');
|
||||
if (msg)
|
||||
*msg++ = '\0';
|
||||
|
@ -187,7 +185,7 @@ static int receive_status(int in, struct ref *refs)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (line[0] == 'o' && line[1] == 'k')
|
||||
if (reader->line[0] == 'o' && reader->line[1] == 'k')
|
||||
hint->status = REF_STATUS_OK;
|
||||
else {
|
||||
hint->status = REF_STATUS_REMOTE_REJECT;
|
||||
|
@ -390,6 +388,7 @@ int send_pack(struct send_pack_args *args,
|
|||
int ret;
|
||||
struct async demux;
|
||||
const char *push_cert_nonce = NULL;
|
||||
struct packet_reader reader;
|
||||
|
||||
/* Does the other end support the reporting? */
|
||||
if (server_supports("report-status"))
|
||||
|
@ -559,6 +558,8 @@ int send_pack(struct send_pack_args *args,
|
|||
in = demux.out;
|
||||
}
|
||||
|
||||
packet_reader_init(&reader, in, NULL, 0, PACKET_READ_CHOMP_NEWLINE);
|
||||
|
||||
if (need_pack_data && cmds_sent) {
|
||||
if (pack_objects(out, remote_refs, extra_have, args) < 0) {
|
||||
for (ref = remote_refs; ref; ref = ref->next)
|
||||
|
@ -573,7 +574,7 @@ int send_pack(struct send_pack_args *args,
|
|||
* are failing, and just want the error() side effects.
|
||||
*/
|
||||
if (status_report)
|
||||
receive_unpack_status(in);
|
||||
receive_unpack_status(&reader);
|
||||
|
||||
if (use_sideband) {
|
||||
close(demux.out);
|
||||
|
@ -590,7 +591,7 @@ int send_pack(struct send_pack_args *args,
|
|||
packet_flush(out);
|
||||
|
||||
if (status_report && cmds_sent)
|
||||
ret = receive_status(in, remote_refs);
|
||||
ret = receive_status(&reader, remote_refs);
|
||||
else
|
||||
ret = 0;
|
||||
if (args->stateless_rpc)
|
||||
|
|
|
@ -354,7 +354,8 @@ static int ok_to_give_up(const struct object_array *have_obj,
|
|||
min_generation);
|
||||
}
|
||||
|
||||
static int get_common_commits(struct object_array *have_obj,
|
||||
static int get_common_commits(struct packet_reader *reader,
|
||||
struct object_array *have_obj,
|
||||
struct object_array *want_obj)
|
||||
{
|
||||
struct object_id oid;
|
||||
|
@ -366,12 +367,11 @@ static int get_common_commits(struct object_array *have_obj,
|
|||
save_commit_buffer = 0;
|
||||
|
||||
for (;;) {
|
||||
char *line = packet_read_line(0, NULL);
|
||||
const char *arg;
|
||||
|
||||
reset_timeout();
|
||||
|
||||
if (!line) {
|
||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL) {
|
||||
if (multi_ack == 2 && got_common
|
||||
&& !got_other && ok_to_give_up(have_obj, want_obj)) {
|
||||
sent_ready = 1;
|
||||
|
@ -390,7 +390,7 @@ static int get_common_commits(struct object_array *have_obj,
|
|||
got_other = 0;
|
||||
continue;
|
||||
}
|
||||
if (skip_prefix(line, "have ", &arg)) {
|
||||
if (skip_prefix(reader->line, "have ", &arg)) {
|
||||
switch (got_oid(arg, &oid, have_obj)) {
|
||||
case -1: /* they have what we do not */
|
||||
got_other = 1;
|
||||
|
@ -416,7 +416,7 @@ static int get_common_commits(struct object_array *have_obj,
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(line, "done")) {
|
||||
if (!strcmp(reader->line, "done")) {
|
||||
if (have_obj->nr > 0) {
|
||||
if (multi_ack)
|
||||
packet_write_fmt(1, "ACK %s\n", last_hex);
|
||||
|
@ -425,7 +425,7 @@ static int get_common_commits(struct object_array *have_obj,
|
|||
packet_write_fmt(1, "NAK\n");
|
||||
return -1;
|
||||
}
|
||||
die("git upload-pack: expected SHA1 list, got '%s'", line);
|
||||
die("git upload-pack: expected SHA1 list, got '%s'", reader->line);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -826,7 +826,7 @@ static int process_deepen_not(const char *line, struct string_list *deepen_not,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void receive_needs(struct object_array *want_obj)
|
||||
static void receive_needs(struct packet_reader *reader, struct object_array *want_obj)
|
||||
{
|
||||
struct object_array shallows = OBJECT_ARRAY_INIT;
|
||||
struct string_list deepen_not = STRING_LIST_INIT_DUP;
|
||||
|
@ -840,33 +840,32 @@ static void receive_needs(struct object_array *want_obj)
|
|||
struct object *o;
|
||||
const char *features;
|
||||
struct object_id oid_buf;
|
||||
char *line = packet_read_line(0, NULL);
|
||||
const char *arg;
|
||||
|
||||
reset_timeout();
|
||||
if (!line)
|
||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||
break;
|
||||
|
||||
if (process_shallow(line, &shallows))
|
||||
if (process_shallow(reader->line, &shallows))
|
||||
continue;
|
||||
if (process_deepen(line, &depth))
|
||||
if (process_deepen(reader->line, &depth))
|
||||
continue;
|
||||
if (process_deepen_since(line, &deepen_since, &deepen_rev_list))
|
||||
if (process_deepen_since(reader->line, &deepen_since, &deepen_rev_list))
|
||||
continue;
|
||||
if (process_deepen_not(line, &deepen_not, &deepen_rev_list))
|
||||
if (process_deepen_not(reader->line, &deepen_not, &deepen_rev_list))
|
||||
continue;
|
||||
|
||||
if (skip_prefix(line, "filter ", &arg)) {
|
||||
if (skip_prefix(reader->line, "filter ", &arg)) {
|
||||
if (!filter_capability_requested)
|
||||
die("git upload-pack: filtering capability not negotiated");
|
||||
parse_list_objects_filter(&filter_options, arg);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!skip_prefix(line, "want ", &arg) ||
|
||||
if (!skip_prefix(reader->line, "want ", &arg) ||
|
||||
parse_oid_hex(arg, &oid_buf, &features))
|
||||
die("git upload-pack: protocol error, "
|
||||
"expected to get object ID, not '%s'", line);
|
||||
"expected to get object ID, not '%s'", reader->line);
|
||||
|
||||
if (parse_feature_request(features, "deepen-relative"))
|
||||
deepen_relative = 1;
|
||||
|
@ -1055,6 +1054,7 @@ void upload_pack(struct upload_pack_options *options)
|
|||
{
|
||||
struct string_list symref = STRING_LIST_INIT_DUP;
|
||||
struct object_array want_obj = OBJECT_ARRAY_INIT;
|
||||
struct packet_reader reader;
|
||||
|
||||
stateless_rpc = options->stateless_rpc;
|
||||
timeout = options->timeout;
|
||||
|
@ -1078,10 +1078,12 @@ void upload_pack(struct upload_pack_options *options)
|
|||
if (options->advertise_refs)
|
||||
return;
|
||||
|
||||
receive_needs(&want_obj);
|
||||
packet_reader_init(&reader, 0, NULL, 0, PACKET_READ_CHOMP_NEWLINE);
|
||||
|
||||
receive_needs(&reader, &want_obj);
|
||||
if (want_obj.nr) {
|
||||
struct object_array have_obj = OBJECT_ARRAY_INIT;
|
||||
get_common_commits(&have_obj, &want_obj);
|
||||
get_common_commits(&reader, &have_obj, &want_obj);
|
||||
create_pack_file(&have_obj, &want_obj);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче