about summary refs log tree commit diff
path: root/third_party/git/fetch-pack.c
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2020-05-25T23·06+0100
committerVincent Ambo <tazjin@google.com>2020-05-25T23·06+0100
commit93ba78d6f4632ef1c5228965e3edc8c0faf88c1e (patch)
tree85730c182a9f5f492ade8e8ccdb1c2356f9900bd /third_party/git/fetch-pack.c
parent6f8fbf4aa4b1654ab27d4829e114538761817de0 (diff)
revert(3p/git): Revert merge of git upstream at v2.26.2 r/852
This causes cgit to serve error pages, which is undesirable.

This reverts commit 5229c9b232de5bfa959ad6ebbb4c8192ac513352, reversing
changes made to f2b211131f2347342dde63975b09cf603149f1a3.
Diffstat (limited to 'third_party/git/fetch-pack.c')
-rw-r--r--third_party/git/fetch-pack.c161
1 files changed, 44 insertions, 117 deletions
diff --git a/third_party/git/fetch-pack.c b/third_party/git/fetch-pack.c
index 1734a573b010..65be043f2afa 100644
--- a/third_party/git/fetch-pack.c
+++ b/third_party/git/fetch-pack.c
@@ -36,6 +36,7 @@ static int agent_supported;
 static int server_supports_filtering;
 static struct lock_file shallow_lock;
 static const char *alternate_shallow_file;
+static char *negotiation_algorithm;
 static struct strbuf fsck_msg_types = STRBUF_INIT;
 
 /* Remember to update object flag allocation in object.h */
@@ -167,16 +168,16 @@ static enum ack_type get_ack(struct packet_reader *reader,
 	if (!strcmp(reader->line, "NAK"))
 		return NAK;
 	if (skip_prefix(reader->line, "ACK ", &arg)) {
-		const char *p;
-		if (!parse_oid_hex(arg, result_oid, &p)) {
-			len -= p - reader->line;
+		if (!get_oid_hex(arg, result_oid)) {
+			arg += 40;
+			len -= arg - reader->line;
 			if (len < 1)
 				return ACK;
-			if (strstr(p, "continue"))
+			if (strstr(arg, "continue"))
 				return ACK_continue;
-			if (strstr(p, "common"))
+			if (strstr(arg, "common"))
 				return ACK_common;
-			if (strstr(p, "ready"))
+			if (strstr(arg, "ready"))
 				return ACK_ready;
 			return ACK;
 		}
@@ -338,9 +339,12 @@ static int find_common(struct fetch_negotiator *negotiator,
 		}
 	}
 	if (server_supports_filtering && args->filter_options.choice) {
-		const char *spec =
-			expand_list_objects_filter_spec(&args->filter_options);
-		packet_buf_write(&req_buf, "filter %s", spec);
+		struct strbuf expanded_filter_spec = STRBUF_INIT;
+		expand_list_objects_filter_spec(&args->filter_options,
+						&expanded_filter_spec);
+		packet_buf_write(&req_buf, "filter %s",
+				 expanded_filter_spec.buf);
+		strbuf_release(&expanded_filter_spec);
 	}
 	packet_buf_flush(&req_buf);
 	state_len = req_buf.len;
@@ -382,7 +386,6 @@ static int find_common(struct fetch_negotiator *negotiator,
 		state_len = 0;
 	}
 
-	trace2_region_enter("fetch-pack", "negotiation_v0_v1", the_repository);
 	flushes = 0;
 	retval = -1;
 	if (args->no_dependents)
@@ -467,7 +470,6 @@ static int find_common(struct fetch_negotiator *negotiator,
 		}
 	}
 done:
-	trace2_region_leave("fetch-pack", "negotiation_v0_v1", the_repository);
 	if (!got_ready || !no_done) {
 		packet_buf_write(&req_buf, "done\n");
 		send_request(args, fd[1], &req_buf);
@@ -669,20 +671,17 @@ static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
 
 	save_commit_buffer = 0;
 
-	trace2_region_enter("fetch-pack", "parse_remote_refs_and_find_cutoff", NULL);
 	for (ref = *refs; ref; ref = ref->next) {
 		struct object *o;
 
 		if (!has_object_file_with_flags(&ref->old_oid,
-						OBJECT_INFO_QUICK |
-							OBJECT_INFO_SKIP_FETCH_OBJECT))
+						OBJECT_INFO_QUICK))
 			continue;
 		o = parse_object(the_repository, &ref->old_oid);
 		if (!o)
 			continue;
 
-		/*
-		 * We already have it -- which may mean that we were
+		/* We already have it -- which may mean that we were
 		 * in sync with the other side at some time after
 		 * that (it is OK if we guess wrong here).
 		 */
@@ -692,13 +691,7 @@ static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
 				cutoff = commit->date;
 		}
 	}
-	trace2_region_leave("fetch-pack", "parse_remote_refs_and_find_cutoff", NULL);
 
-	/*
-	 * This block marks all local refs as COMPLETE, and then recursively marks all
-	 * parents of those refs as COMPLETE.
-	 */
-	trace2_region_enter("fetch-pack", "mark_complete_local_refs", NULL);
 	if (!args->deepen) {
 		for_each_ref(mark_complete_oid, NULL);
 		for_each_cached_alternate(NULL, mark_alternate_complete);
@@ -706,13 +699,11 @@ static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
 		if (cutoff)
 			mark_recent_complete_commits(args, cutoff);
 	}
-	trace2_region_leave("fetch-pack", "mark_complete_local_refs", NULL);
 
 	/*
 	 * Mark all complete remote refs as common refs.
 	 * Don't mark them common yet; the server has to be told so first.
 	 */
-	trace2_region_enter("fetch-pack", "mark_common_remote_refs", NULL);
 	for (ref = *refs; ref; ref = ref->next) {
 		struct object *o = deref_tag(the_repository,
 					     lookup_object(the_repository,
@@ -725,7 +716,6 @@ static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator,
 		negotiator->known_common(negotiator,
 					 (struct commit *)o);
 	}
-	trace2_region_leave("fetch-pack", "mark_common_remote_refs", NULL);
 
 	save_commit_buffer = old_save_commit_buffer;
 }
@@ -768,33 +758,8 @@ static int sideband_demux(int in, int out, void *data)
 	return ret;
 }
 
-static void write_promisor_file(const char *keep_name,
-				struct ref **sought, int nr_sought)
-{
-	struct strbuf promisor_name = STRBUF_INIT;
-	int suffix_stripped;
-	FILE *output;
-	int i;
-
-	strbuf_addstr(&promisor_name, keep_name);
-	suffix_stripped = strbuf_strip_suffix(&promisor_name, ".keep");
-	if (!suffix_stripped)
-		BUG("name of pack lockfile should end with .keep (was '%s')",
-		    keep_name);
-	strbuf_addstr(&promisor_name, ".promisor");
-
-	output = xfopen(promisor_name.buf, "w");
-	for (i = 0; i < nr_sought; i++)
-		fprintf(output, "%s %s\n", oid_to_hex(&sought[i]->old_oid),
-			sought[i]->name);
-	fclose(output);
-
-	strbuf_release(&promisor_name);
-}
-
 static int get_pack(struct fetch_pack_args *args,
-		    int xd[2], char **pack_lockfile,
-		    struct ref **sought, int nr_sought)
+		    int xd[2], char **pack_lockfile)
 {
 	struct async demux;
 	int do_keep = args->keep_pack;
@@ -856,13 +821,7 @@ static int get_pack(struct fetch_pack_args *args,
 		}
 		if (args->check_self_contained_and_connected)
 			argv_array_push(&cmd.args, "--check-self-contained-and-connected");
-		/*
-		 * If we're obtaining the filename of a lockfile, we'll use
-		 * that filename to write a .promisor file with more
-		 * information below. If not, we need index-pack to do it for
-		 * us.
-		 */
-		if (!(do_keep && pack_lockfile) && args->from_promisor)
+		if (args->from_promisor)
 			argv_array_push(&cmd.args, "--promisor");
 	}
 	else {
@@ -916,14 +875,6 @@ static int get_pack(struct fetch_pack_args *args,
 		die(_("%s failed"), cmd_name);
 	if (use_sideband && finish_async(&demux))
 		die(_("error in sideband demultiplexer"));
-
-	/*
-	 * Now that index-pack has succeeded, write the promisor file using the
-	 * obtained .keep filename if necessary
-	 */
-	if (do_keep && pack_lockfile && args->from_promisor)
-		write_promisor_file(*pack_lockfile, sought, nr_sought);
-
 	return 0;
 }
 
@@ -941,20 +892,12 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
 				 struct shallow_info *si,
 				 char **pack_lockfile)
 {
-	struct repository *r = the_repository;
 	struct ref *ref = copy_ref_list(orig_ref);
 	struct object_id oid;
 	const char *agent_feature;
 	int agent_len;
-	struct fetch_negotiator negotiator_alloc;
-	struct fetch_negotiator *negotiator;
-
-	if (args->no_dependents) {
-		negotiator = NULL;
-	} else {
-		negotiator = &negotiator_alloc;
-		fetch_negotiator_init(r, negotiator);
-	}
+	struct fetch_negotiator negotiator;
+	fetch_negotiator_init(&negotiator, negotiation_algorithm);
 
 	sort_ref_list(&ref, ref_compare_name);
 	QSORT(sought, nr_sought, cmp_ref_by_name);
@@ -968,7 +911,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
 
 	if (server_supports("shallow"))
 		print_verbose(args, _("Server supports %s"), "shallow");
-	else if (args->depth > 0 || is_repository_shallow(r))
+	else if (args->depth > 0 || is_repository_shallow(the_repository))
 		die(_("Server does not support shallow clients"));
 	if (args->depth > 0 || args->deepen_since || args->deepen_not)
 		args->deepen = 1;
@@ -1041,7 +984,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
 		die(_("Server does not support --deepen"));
 
 	if (!args->no_dependents) {
-		mark_complete_and_common_ref(negotiator, args, &ref);
+		mark_complete_and_common_ref(&negotiator, args, &ref);
 		filter_refs(args, &ref, sought, nr_sought);
 		if (everything_local(args, &ref)) {
 			packet_flush(fd[1]);
@@ -1050,7 +993,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
 	} else {
 		filter_refs(args, &ref, sought, nr_sought);
 	}
-	if (find_common(negotiator, args, fd, &oid, ref) < 0)
+	if (find_common(&negotiator, args, fd, &oid, ref) < 0)
 		if (!args->keep_pack)
 			/* When cloning, it is not unusual to have
 			 * no common commit.
@@ -1066,12 +1009,11 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
 		alternate_shallow_file = setup_temporary_shallow(si->shallow);
 	else
 		alternate_shallow_file = NULL;
-	if (get_pack(args, fd, pack_lockfile, sought, nr_sought))
+	if (get_pack(args, fd, pack_lockfile))
 		die(_("git fetch-pack: fetch failed."));
 
  all_done:
-	if (negotiator)
-		negotiator->release(negotiator);
+	negotiator.release(&negotiator);
 	return ref;
 }
 
@@ -1170,7 +1112,7 @@ static int add_haves(struct fetch_negotiator *negotiator,
 }
 
 static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out,
-			      struct fetch_pack_args *args,
+			      const struct fetch_pack_args *args,
 			      const struct ref *wants, struct oidset *common,
 			      int *haves_to_send, int *in_vain,
 			      int sideband_all)
@@ -1211,10 +1153,13 @@ static int send_fetch_request(struct fetch_negotiator *negotiator, int fd_out,
 	/* Add filter */
 	if (server_supports_feature("fetch", "filter", 0) &&
 	    args->filter_options.choice) {
-		const char *spec =
-			expand_list_objects_filter_spec(&args->filter_options);
+		struct strbuf expanded_filter_spec = STRBUF_INIT;
 		print_verbose(args, _("Server supports filter"));
-		packet_buf_write(&req_buf, "filter %s", spec);
+		expand_list_objects_filter_spec(&args->filter_options,
+						&expanded_filter_spec);
+		packet_buf_write(&req_buf, "filter %s",
+				 expanded_filter_spec.buf);
+		strbuf_release(&expanded_filter_spec);
 	} else if (args->filter_options.choice) {
 		warning("filtering not recognized by server, ignoring");
 	}
@@ -1289,8 +1234,7 @@ static int process_acks(struct fetch_negotiator *negotiator,
 				struct commit *commit;
 				oidset_insert(common, &oid);
 				commit = lookup_commit(the_repository, &oid);
-				if (negotiator)
-					negotiator->ack(negotiator, commit);
+				negotiator->ack(negotiator, commit);
 			}
 			continue;
 		}
@@ -1435,23 +1379,14 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
 				    struct shallow_info *si,
 				    char **pack_lockfile)
 {
-	struct repository *r = the_repository;
 	struct ref *ref = copy_ref_list(orig_ref);
 	enum fetch_state state = FETCH_CHECK_LOCAL;
 	struct oidset common = OIDSET_INIT;
 	struct packet_reader reader;
-	int in_vain = 0, negotiation_started = 0;
+	int in_vain = 0;
 	int haves_to_send = INITIAL_FLUSH;
-	struct fetch_negotiator negotiator_alloc;
-	struct fetch_negotiator *negotiator;
-
-	if (args->no_dependents) {
-		negotiator = NULL;
-	} else {
-		negotiator = &negotiator_alloc;
-		fetch_negotiator_init(r, negotiator);
-	}
-
+	struct fetch_negotiator negotiator;
+	fetch_negotiator_init(&negotiator, negotiation_algorithm);
 	packet_reader_init(&reader, fd[0], NULL, 0,
 			   PACKET_READ_CHOMP_NEWLINE |
 			   PACKET_READ_DIE_ON_ERR_PACKET);
@@ -1475,15 +1410,15 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
 
 			/* Filter 'ref' by 'sought' and those that aren't local */
 			if (!args->no_dependents) {
-				mark_complete_and_common_ref(negotiator, args, &ref);
+				mark_complete_and_common_ref(&negotiator, args, &ref);
 				filter_refs(args, &ref, sought, nr_sought);
 				if (everything_local(args, &ref))
 					state = FETCH_DONE;
 				else
 					state = FETCH_SEND_REQUEST;
 
-				mark_tips(negotiator, args->negotiation_tips);
-				for_each_cached_alternate(negotiator,
+				mark_tips(&negotiator, args->negotiation_tips);
+				for_each_cached_alternate(&negotiator,
 							  insert_one_alternate_object);
 			} else {
 				filter_refs(args, &ref, sought, nr_sought);
@@ -1491,13 +1426,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
 			}
 			break;
 		case FETCH_SEND_REQUEST:
-			if (!negotiation_started) {
-				negotiation_started = 1;
-				trace2_region_enter("fetch-pack",
-						    "negotiation_v2",
-						    the_repository);
-			}
-			if (send_fetch_request(negotiator, fd[1], args, ref,
+			if (send_fetch_request(&negotiator, fd[1], args, ref,
 					       &common,
 					       &haves_to_send, &in_vain,
 					       reader.use_sideband))
@@ -1507,7 +1436,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
 			break;
 		case FETCH_PROCESS_ACKS:
 			/* Process ACKs/NAKs */
-			switch (process_acks(negotiator, &reader, &common)) {
+			switch (process_acks(&negotiator, &reader, &common)) {
 			case 2:
 				state = FETCH_GET_PACK;
 				break;
@@ -1520,9 +1449,6 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
 			}
 			break;
 		case FETCH_GET_PACK:
-			trace2_region_leave("fetch-pack",
-					    "negotiation_v2",
-					    the_repository);
 			/* Check for shallow-info section */
 			if (process_section_header(&reader, "shallow-info", 1))
 				receive_shallow_info(args, &reader, shallows, si);
@@ -1532,7 +1458,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
 
 			/* get the pack */
 			process_section_header(&reader, "packfile", 0);
-			if (get_pack(args, fd, pack_lockfile, sought, nr_sought))
+			if (get_pack(args, fd, pack_lockfile))
 				die(_("git fetch-pack: fetch failed."));
 
 			state = FETCH_DONE;
@@ -1542,8 +1468,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
 		}
 	}
 
-	if (negotiator)
-		negotiator->release(negotiator);
+	negotiator.release(&negotiator);
 	oidset_clear(&common);
 	return ref;
 }
@@ -1580,6 +1505,8 @@ static void fetch_pack_config(void)
 	git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta);
 	git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects);
 	git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects);
+	git_config_get_string("fetch.negotiationalgorithm",
+			      &negotiation_algorithm);
 
 	git_config(fetch_pack_config_cb, NULL);
 }