Second update to address Junio comments. Interdiff diff --git a/upload-pack.c b/upload-pack.c index ef693bd..e40d15a 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -453,6 +453,9 @@ static int is_our_ref(struct object *o) return o->flags & ((allow_hidden_ref ? HIDDEN_REF : 0) | OUR_REF); } +/* + * on successful case, it's up to the caller to close cmd->out + */ static int do_reachable_revlist(struct child_process *cmd, struct object_array *src, struct object_array *reachable) @@ -470,16 +473,16 @@ static int do_reachable_revlist(struct child_process *cmd, cmd->in = -1; cmd->out = -1; - if (start_command(cmd)) - goto error; - /* - * If rev-list --stdin encounters an unknown commit, it - * terminates, which will cause SIGPIPE in the write loop + * If the next rev-list --stdin encounters an unknown commit, + * it terminates, which will cause SIGPIPE in the write loop * below. */ sigchain_push(SIGPIPE, SIG_IGN); + if (start_command(cmd)) + goto error; + namebuf[0] = '^'; namebuf[41] = '\n'; for (i = get_max_object_index(); 0 < i; ) { @@ -491,10 +494,8 @@ static int do_reachable_revlist(struct child_process *cmd, if (!is_our_ref(o)) continue; memcpy(namebuf + 1, oid_to_hex(&o->oid), GIT_SHA1_HEXSZ); - if (write_in_full(cmd->in, namebuf, 42) < 0) { - sigchain_pop(SIGPIPE); + if (write_in_full(cmd->in, namebuf, 42) < 0) goto error; - } } namebuf[40] = '\n'; for (i = 0; i < src->nr; i++) { @@ -507,18 +508,18 @@ static int do_reachable_revlist(struct child_process *cmd, if (reachable && o->type == OBJ_COMMIT) o->flags |= TMP_MARK; memcpy(namebuf, oid_to_hex(&o->oid), GIT_SHA1_HEXSZ); - if (write_in_full(cmd->in, namebuf, 41) < 0) { - sigchain_pop(SIGPIPE); + if (write_in_full(cmd->in, namebuf, 41) < 0) goto error; - } } close(cmd->in); cmd->in = -1; - sigchain_pop(SIGPIPE); + return 0; error: + sigchain_pop(SIGPIPE); + if (cmd->in >= 0) close(cmd->in); if (cmd->out >= 0) @@ -530,11 +531,11 @@ static int get_reachable_list(struct object_array *src, struct object_array *reachable) { struct child_process cmd = CHILD_PROCESS_INIT; - int i, ret = do_reachable_revlist(&cmd, src, reachable); + int i; struct object *o; char namebuf[42]; /* ^ + SHA-1 + LF */ - if (ret < 0) + if (do_reachable_revlist(&cmd, src, reachable) < 0) return -1; while ((i = read_in_full(cmd.out, namebuf, 41)) == 41) { @@ -564,14 +565,14 @@ static int get_reachable_list(struct object_array *src, return 0; } -static int check_unreachable(struct object_array *src) +static int has_unreachable(struct object_array *src) { struct child_process cmd = CHILD_PROCESS_INIT; char buf[1]; int i; if (do_reachable_revlist(&cmd, src, NULL) < 0) - return 0; + return 1; /* * The commits out of the rev-list are not ancestors of @@ -592,14 +593,13 @@ static int check_unreachable(struct object_array *src) goto error; /* All the non-tip ones are ancestors of what we advertised */ - return 1; + return 0; error: - if (cmd.in >= 0) - close(cmd.in); + sigchain_pop(SIGPIPE); if (cmd.out >= 0) close(cmd.out); - return 0; + return 1; } static void check_non_tip(void) @@ -613,7 +613,7 @@ static void check_non_tip(void) */ if (!stateless_rpc && !(allow_unadvertised_object_request & ALLOW_REACHABLE_SHA1)) goto error; - if (check_unreachable(&want_obj)) + if (!has_unreachable(&want_obj)) /* All the non-tip ones are ancestors of what we advertised */ return; @@ -678,25 +678,33 @@ static void send_unshallow(const struct object_array *shallows) static void deepen(int depth, int deepen_relative, struct object_array *shallows) { - struct commit_list *result = NULL; - int i; - if (depth == INFINITE_DEPTH && !is_repository_shallow()) + if (depth == INFINITE_DEPTH && !is_repository_shallow()) { + int i; + for (i = 0; i < shallows->nr; i++) { struct object *object = shallows->objects[i].item; object->flags |= NOT_SHALLOW; } - else if (deepen_relative) { + } else if (deepen_relative) { struct object_array reachable_shallows = OBJECT_ARRAY_INIT; + struct commit_list *result; + get_reachable_list(shallows, &reachable_shallows); result = get_shallow_commits(&reachable_shallows, depth + 1, SHALLOW, NOT_SHALLOW); + send_shallow(result); + free_commit_list(result); object_array_clear(&reachable_shallows); - } else + } else { + struct commit_list *result; + result = get_shallow_commits(&want_obj, depth, SHALLOW, NOT_SHALLOW); - send_shallow(result); - free_commit_list(result); + send_shallow(result); + free_commit_list(result); + } + send_unshallow(shallows); packet_flush(1); } -- 2.8.2.524.g6ff3d78 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html