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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html