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>maint
							parent
							
								
									b21ebb671b
								
							
						
					
					
						commit
						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")) | ||||
| 					break; /* end of cert */ | ||||
| 				strbuf_addstr(&push_cert, certbuf); | ||||
| 				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, 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); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Masaya Suzuki
						Masaya Suzuki