fetch-pack: add refetch
Allow a "refetch" where the contents of the local object store are ignored and a full fetch is performed, not attempting to find or negotiate common commits with the remote. A key use case is to apply a new partial clone blob/tree filter and refetch all the associated matching content, which would otherwise not be transferred when the commit objects are already present locally. Signed-off-by: Robert Coup <robert@coup.net.nz> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									1836836593
								
							
						
					
					
						commit
						4dfd0925cb
					
				
							
								
								
									
										16
									
								
								fetch-pack.c
								
								
								
								
							
							
						
						
									
										16
									
								
								fetch-pack.c
								
								
								
								
							|  | @ -312,6 +312,7 @@ static int find_common(struct fetch_negotiator *negotiator, | ||||||
| 		const char *remote_hex; | 		const char *remote_hex; | ||||||
| 		struct object *o; | 		struct object *o; | ||||||
|  |  | ||||||
|  | 		if (!args->refetch) { | ||||||
| 			/* | 			/* | ||||||
| 			* If that object is complete (i.e. it is an ancestor of a | 			* If that object is complete (i.e. it is an ancestor of a | ||||||
| 			* local ref), we tell them we have it but do not have to | 			* local ref), we tell them we have it but do not have to | ||||||
|  | @ -326,6 +327,7 @@ static int find_common(struct fetch_negotiator *negotiator, | ||||||
| 					(o->flags & COMPLETE)) { | 					(o->flags & COMPLETE)) { | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		remote_hex = oid_to_hex(remote); | 		remote_hex = oid_to_hex(remote); | ||||||
| 		if (!fetching) { | 		if (!fetching) { | ||||||
|  | @ -692,6 +694,9 @@ static void mark_complete_and_common_ref(struct fetch_negotiator *negotiator, | ||||||
| 	int old_save_commit_buffer = save_commit_buffer; | 	int old_save_commit_buffer = save_commit_buffer; | ||||||
| 	timestamp_t cutoff = 0; | 	timestamp_t cutoff = 0; | ||||||
|  |  | ||||||
|  | 	if (args->refetch) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
| 	save_commit_buffer = 0; | 	save_commit_buffer = 0; | ||||||
|  |  | ||||||
| 	trace2_region_enter("fetch-pack", "parse_remote_refs_and_find_cutoff", NULL); | 	trace2_region_enter("fetch-pack", "parse_remote_refs_and_find_cutoff", NULL); | ||||||
|  | @ -1028,7 +1033,11 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args, | ||||||
| 	struct fetch_negotiator *negotiator; | 	struct fetch_negotiator *negotiator; | ||||||
|  |  | ||||||
| 	negotiator = &negotiator_alloc; | 	negotiator = &negotiator_alloc; | ||||||
|  | 	if (args->refetch) { | ||||||
|  | 		fetch_negotiator_init_noop(negotiator); | ||||||
|  | 	} else { | ||||||
| 		fetch_negotiator_init(r, negotiator); | 		fetch_negotiator_init(r, negotiator); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	sort_ref_list(&ref, ref_compare_name); | 	sort_ref_list(&ref, ref_compare_name); | ||||||
| 	QSORT(sought, nr_sought, cmp_ref_by_name); | 	QSORT(sought, nr_sought, cmp_ref_by_name); | ||||||
|  | @ -1121,7 +1130,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args, | ||||||
|  |  | ||||||
| 	mark_complete_and_common_ref(negotiator, args, &ref); | 	mark_complete_and_common_ref(negotiator, args, &ref); | ||||||
| 	filter_refs(args, &ref, sought, nr_sought); | 	filter_refs(args, &ref, sought, nr_sought); | ||||||
| 	if (everything_local(args, &ref)) { | 	if (!args->refetch && everything_local(args, &ref)) { | ||||||
| 		packet_flush(fd[1]); | 		packet_flush(fd[1]); | ||||||
| 		goto all_done; | 		goto all_done; | ||||||
| 	} | 	} | ||||||
|  | @ -1587,6 +1596,9 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args, | ||||||
| 	struct strvec index_pack_args = STRVEC_INIT; | 	struct strvec index_pack_args = STRVEC_INIT; | ||||||
|  |  | ||||||
| 	negotiator = &negotiator_alloc; | 	negotiator = &negotiator_alloc; | ||||||
|  | 	if (args->refetch) | ||||||
|  | 		fetch_negotiator_init_noop(negotiator); | ||||||
|  | 	else | ||||||
| 		fetch_negotiator_init(r, negotiator); | 		fetch_negotiator_init(r, negotiator); | ||||||
|  |  | ||||||
| 	packet_reader_init(&reader, fd[0], NULL, 0, | 	packet_reader_init(&reader, fd[0], NULL, 0, | ||||||
|  | @ -1613,7 +1625,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args, | ||||||
| 			/* Filter 'ref' by 'sought' and those that aren't local */ | 			/* Filter 'ref' by 'sought' and those that aren't local */ | ||||||
| 			mark_complete_and_common_ref(negotiator, args, &ref); | 			mark_complete_and_common_ref(negotiator, args, &ref); | ||||||
| 			filter_refs(args, &ref, sought, nr_sought); | 			filter_refs(args, &ref, sought, nr_sought); | ||||||
| 			if (everything_local(args, &ref)) | 			if (!args->refetch && everything_local(args, &ref)) | ||||||
| 				state = FETCH_DONE; | 				state = FETCH_DONE; | ||||||
| 			else | 			else | ||||||
| 				state = FETCH_SEND_REQUEST; | 				state = FETCH_SEND_REQUEST; | ||||||
|  |  | ||||||
|  | @ -42,6 +42,7 @@ struct fetch_pack_args { | ||||||
| 	unsigned update_shallow:1; | 	unsigned update_shallow:1; | ||||||
| 	unsigned reject_shallow_remote:1; | 	unsigned reject_shallow_remote:1; | ||||||
| 	unsigned deepen:1; | 	unsigned deepen:1; | ||||||
|  | 	unsigned refetch:1; | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 * Indicate that the remote of this request is a promisor remote. The | 	 * Indicate that the remote of this request is a promisor remote. The | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Robert Coup
						Robert Coup