Merge branch 'mm/fetch-show-error-message-on-unadvertised-object'
"git fetch" that requests a commit by object name, when the other side does not allow such an request, failed without much explanation. * mm/fetch-show-error-message-on-unadvertised-object: fetch-pack: add specific error for fetching an unadvertised object fetch_refs_via_pack: call report_unmatched_refs fetch-pack: move code to report unmatched refs to a functionmaint
						commit
						07198afbd1
					
				|  | @ -219,12 +219,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) | |||
| 	 * remote no-such-ref' would silently succeed without issuing | ||||
| 	 * an error. | ||||
| 	 */ | ||||
| 	for (i = 0; i < nr_sought; i++) { | ||||
| 		if (!sought[i] || sought[i]->matched) | ||||
| 			continue; | ||||
| 		error("no such remote ref %s", sought[i]->name); | ||||
| 		ret = 1; | ||||
| 	} | ||||
| 	ret |= report_unmatched_refs(sought, nr_sought); | ||||
|  | ||||
| 	while (ref) { | ||||
| 		printf("%s %s\n", | ||||
|  |  | |||
							
								
								
									
										35
									
								
								fetch-pack.c
								
								
								
								
							
							
						
						
									
										35
									
								
								fetch-pack.c
								
								
								
								
							|  | @ -614,7 +614,7 @@ static void filter_refs(struct fetch_pack_args *args, | |||
| 					break; /* definitely do not have it */ | ||||
| 				else if (cmp == 0) { | ||||
| 					keep = 1; /* definitely have it */ | ||||
| 					sought[i]->matched = 1; | ||||
| 					sought[i]->match_status = REF_MATCHED; | ||||
| 				} | ||||
| 				i++; | ||||
| 			} | ||||
|  | @ -634,22 +634,24 @@ static void filter_refs(struct fetch_pack_args *args, | |||
| 	} | ||||
|  | ||||
| 	/* Append unmatched requests to the list */ | ||||
| 	if ((allow_unadvertised_object_request & | ||||
| 	    (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1))) { | ||||
| 	for (i = 0; i < nr_sought; i++) { | ||||
| 		unsigned char sha1[20]; | ||||
|  | ||||
| 		ref = sought[i]; | ||||
| 			if (ref->matched) | ||||
| 		if (ref->match_status != REF_NOT_MATCHED) | ||||
| 			continue; | ||||
| 		if (get_sha1_hex(ref->name, sha1) || | ||||
| 		    ref->name[40] != '\0' || | ||||
| 		    hashcmp(sha1, ref->old_oid.hash)) | ||||
| 			continue; | ||||
|  | ||||
| 			ref->matched = 1; | ||||
| 		if ((allow_unadvertised_object_request & | ||||
| 		    (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1))) { | ||||
| 			ref->match_status = REF_MATCHED; | ||||
| 			*newtail = copy_ref(ref); | ||||
| 			newtail = &(*newtail)->next; | ||||
| 		} else { | ||||
| 			ref->match_status = REF_UNADVERTISED_NOT_ALLOWED; | ||||
| 		} | ||||
| 	} | ||||
| 	*refs = newlist; | ||||
|  | @ -1130,3 +1132,26 @@ struct ref *fetch_pack(struct fetch_pack_args *args, | |||
| 	clear_shallow_info(&si); | ||||
| 	return ref_cpy; | ||||
| } | ||||
|  | ||||
| int report_unmatched_refs(struct ref **sought, int nr_sought) | ||||
| { | ||||
| 	int i, ret = 0; | ||||
|  | ||||
| 	for (i = 0; i < nr_sought; i++) { | ||||
| 		if (!sought[i]) | ||||
| 			continue; | ||||
| 		switch (sought[i]->match_status) { | ||||
| 		case REF_MATCHED: | ||||
| 			continue; | ||||
| 		case REF_NOT_MATCHED: | ||||
| 			error(_("no such remote ref %s"), sought[i]->name); | ||||
| 			break; | ||||
| 		case REF_UNADVERTISED_NOT_ALLOWED: | ||||
| 			error(_("Server does not allow request for unadvertised object %s"), | ||||
| 			      sought[i]->name); | ||||
| 			break; | ||||
| 		} | ||||
| 		ret = 1; | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
|  |  | |||
|  | @ -45,4 +45,10 @@ struct ref *fetch_pack(struct fetch_pack_args *args, | |||
| 		       struct sha1_array *shallow, | ||||
| 		       char **pack_lockfile); | ||||
|  | ||||
| /* | ||||
|  * Print an appropriate error message for each sought ref that wasn't | ||||
|  * matched.  Return 0 if all sought refs were matched, otherwise 1. | ||||
|  */ | ||||
| int report_unmatched_refs(struct ref **sought, int nr_sought); | ||||
|  | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										9
									
								
								remote.h
								
								
								
								
							
							
						
						
									
										9
									
								
								remote.h
								
								
								
								
							|  | @ -89,8 +89,13 @@ struct ref { | |||
| 		force:1, | ||||
| 		forced_update:1, | ||||
| 		expect_old_sha1:1, | ||||
| 		deletion:1, | ||||
| 		matched:1; | ||||
| 		deletion:1; | ||||
|  | ||||
| 	enum { | ||||
| 		REF_NOT_MATCHED = 0, /* initial value */ | ||||
| 		REF_MATCHED, | ||||
| 		REF_UNADVERTISED_NOT_ALLOWED | ||||
| 	} match_status; | ||||
|  | ||||
| 	/* | ||||
| 	 * Order is important here, as we write to FETCH_HEAD | ||||
|  |  | |||
|  | @ -484,7 +484,7 @@ test_expect_success 'test lonely missing ref' ' | |||
| 		cd client && | ||||
| 		test_must_fail git fetch-pack --no-progress .. refs/heads/xyzzy | ||||
| 	) >/dev/null 2>error-m && | ||||
| 	test_cmp expect-error error-m | ||||
| 	test_i18ncmp expect-error error-m | ||||
| ' | ||||
|  | ||||
| test_expect_success 'test missing ref after existing' ' | ||||
|  | @ -492,7 +492,7 @@ test_expect_success 'test missing ref after existing' ' | |||
| 		cd client && | ||||
| 		test_must_fail git fetch-pack --no-progress .. refs/heads/A refs/heads/xyzzy | ||||
| 	) >/dev/null 2>error-em && | ||||
| 	test_cmp expect-error error-em | ||||
| 	test_i18ncmp expect-error error-em | ||||
| ' | ||||
|  | ||||
| test_expect_success 'test missing ref before existing' ' | ||||
|  | @ -500,7 +500,7 @@ test_expect_success 'test missing ref before existing' ' | |||
| 		cd client && | ||||
| 		test_must_fail git fetch-pack --no-progress .. refs/heads/xyzzy refs/heads/A | ||||
| 	) >/dev/null 2>error-me && | ||||
| 	test_cmp expect-error error-me | ||||
| 	test_i18ncmp expect-error error-me | ||||
| ' | ||||
|  | ||||
| test_expect_success 'test --all, --depth, and explicit head' ' | ||||
|  |  | |||
|  | @ -1098,7 +1098,8 @@ test_expect_success 'fetch exact SHA1' ' | |||
| 		test_must_fail git cat-file -t $the_commit && | ||||
|  | ||||
| 		# fetching the hidden object should fail by default | ||||
| 		test_must_fail git fetch -v ../testrepo $the_commit:refs/heads/copy && | ||||
| 		test_must_fail git fetch -v ../testrepo $the_commit:refs/heads/copy 2>err && | ||||
| 		test_i18ngrep "Server does not allow request for unadvertised object" err && | ||||
| 		test_must_fail git rev-parse --verify refs/heads/copy && | ||||
|  | ||||
| 		# the server side can allow it to succeed | ||||
|  |  | |||
							
								
								
									
										14
									
								
								transport.c
								
								
								
								
							
							
						
						
									
										14
									
								
								transport.c
								
								
								
								
							|  | @ -204,6 +204,7 @@ static struct ref *get_refs_via_connect(struct transport *transport, int for_pus | |||
| static int fetch_refs_via_pack(struct transport *transport, | ||||
| 			       int nr_heads, struct ref **to_fetch) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	struct git_transport_data *data = transport->data; | ||||
| 	struct ref *refs; | ||||
| 	char *dest = xstrdup(transport->url); | ||||
|  | @ -241,19 +242,22 @@ static int fetch_refs_via_pack(struct transport *transport, | |||
| 			  &transport->pack_lockfile); | ||||
| 	close(data->fd[0]); | ||||
| 	close(data->fd[1]); | ||||
| 	if (finish_connect(data->conn)) { | ||||
| 		free_refs(refs); | ||||
| 		refs = NULL; | ||||
| 	} | ||||
| 	if (finish_connect(data->conn)) | ||||
| 		ret = -1; | ||||
| 	data->conn = NULL; | ||||
| 	data->got_remote_heads = 0; | ||||
| 	data->options.self_contained_and_connected = | ||||
| 		args.self_contained_and_connected; | ||||
|  | ||||
| 	if (refs == NULL) | ||||
| 		ret = -1; | ||||
| 	if (report_unmatched_refs(to_fetch, nr_heads)) | ||||
| 		ret = -1; | ||||
|  | ||||
| 	free_refs(refs_tmp); | ||||
| 	free_refs(refs); | ||||
| 	free(dest); | ||||
| 	return (refs ? 0 : -1); | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static int push_had_errors(struct ref *ref) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano