send-pack: new return code "ERROR_SEND_PACK_BAD_REF_STATUS"
The "push_refs" function in the transport_vtable is the handler for git-push operation. All the "push_refs" functions for different transports (protocols) should have the same behavior, but the behavior of "git_transport_push()" function for builtin_smart_vtable in "transport.c" (which calls "send_pack()" in "send-pack.c") differs from the handler of the HTTP protocol. The "push_refs()" function for the HTTP protocol which calls the "push_refs_with_push()" function in "transport-helper.c" will return 0 even when a bad REF_STATUS (such as REF_STATUS_REJECT_NONFASTFORWARD) was found. But "send_pack()" for Git smart protocol will return -1 for a bad REF_STATUS. We cannot ignore bad REF_STATUS directly in the "send_pack()" function, because the function is also used in "builtin/send-pack.c". So we add a new non-zero error code "SEND_PACK_ERROR_REF_STATUS" for "send_pack()". Ignore the specific error code in the "git_transport_push()" function to have the same behavior as "push_refs()" for HTTP protocol. Note that even though we ignore the error here, we'll ultimately still end up detecting that a subset of refs was not pushed in `transport_push()` because we eventually call `push_had_errors()` on the remote refs. Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									dd69a12e6a
								
							
						
					
					
						commit
						3028db4af2
					
				|  | @ -632,7 +632,7 @@ int send_pack(struct repository *r, | |||
| 				reject_atomic_push(remote_refs, args->send_mirror); | ||||
| 				error("atomic push failed for ref %s. status: %d", | ||||
| 				      ref->name, ref->status); | ||||
| 				ret = args->porcelain ? 0 : -1; | ||||
| 				ret = ERROR_SEND_PACK_BAD_REF_STATUS; | ||||
| 				goto out; | ||||
| 			} | ||||
| 			/* else fallthrough */ | ||||
|  | @ -763,11 +763,6 @@ int send_pack(struct repository *r, | |||
| 	if (ret < 0) | ||||
| 		goto out; | ||||
|  | ||||
| 	if (args->porcelain) { | ||||
| 		ret = 0; | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
| 	for (ref = remote_refs; ref; ref = ref->next) { | ||||
| 		switch (ref->status) { | ||||
| 		case REF_STATUS_NONE: | ||||
|  | @ -775,7 +770,7 @@ int send_pack(struct repository *r, | |||
| 		case REF_STATUS_OK: | ||||
| 			break; | ||||
| 		default: | ||||
| 			ret = -1; | ||||
| 			ret = ERROR_SEND_PACK_BAD_REF_STATUS; | ||||
| 			goto out; | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
							
								
								
									
										13
									
								
								send-pack.h
								
								
								
								
							
							
						
						
									
										13
									
								
								send-pack.h
								
								
								
								
							|  | @ -13,6 +13,9 @@ struct repository; | |||
| #define SEND_PACK_PUSH_CERT_IF_ASKED 1 | ||||
| #define SEND_PACK_PUSH_CERT_ALWAYS 2 | ||||
|  | ||||
| /* At least one reference has been rejected by the remote side. */ | ||||
| #define ERROR_SEND_PACK_BAD_REF_STATUS 1 | ||||
|  | ||||
| struct send_pack_args { | ||||
| 	const char *url; | ||||
| 	unsigned verbose:1, | ||||
|  | @ -36,6 +39,16 @@ struct option; | |||
| int option_parse_push_signed(const struct option *opt, | ||||
| 			     const char *arg, int unset); | ||||
|  | ||||
| /* | ||||
|  * Compute a packfile and write it to a file descriptor. The `fd` array needs | ||||
|  * to contain two file descriptors: `fd[0]` is the file descriptor used as | ||||
|  * input for the packet reader, whereas `fd[1]` is the file descriptor the | ||||
|  * packfile will be written to. | ||||
|  * | ||||
|  * Returns 0 on success, non-zero otherwise. Negative return values indicate a | ||||
|  * generic error, whereas positive return values indicate specific error | ||||
|  * conditions as documented with the `ERROR_SEND_PACK_*` constants. | ||||
|  */ | ||||
| int send_pack(struct repository *r, struct send_pack_args *args, | ||||
| 	      int fd[], struct child_process *conn, | ||||
| 	      struct ref *remote_refs, struct oid_array *extra_have); | ||||
|  |  | |||
|  | @ -934,6 +934,13 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re | |||
| 	case protocol_v0: | ||||
| 		ret = send_pack(the_repository, &args, data->fd, data->conn, remote_refs, | ||||
| 				&data->extra_have); | ||||
| 		/* | ||||
| 		 * Ignore the specific error code to maintain consistent behavior | ||||
| 		 * with the "push_refs()" function across different transports, | ||||
| 		 * such as "push_refs_with_push()" for HTTP protocol. | ||||
| 		 */ | ||||
| 		if (ret == ERROR_SEND_PACK_BAD_REF_STATUS) | ||||
| 			ret = 0; | ||||
| 		break; | ||||
| 	case protocol_unknown_version: | ||||
| 		BUG("unknown protocol version"); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Jiang Xin
						Jiang Xin