Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- object.h | 2 +- upload-pack.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/object.h b/object.h index f8b6442..614a006 100644 --- a/object.h +++ b/object.h @@ -31,7 +31,7 @@ struct object_array { * revision.h: 0---------10 26 * fetch-pack.c: 0---4 * walker.c: 0-2 - * upload-pack.c: 11----------------19 + * upload-pack.c: 4 11----------------19 * builtin/blame.c: 12-13 * bisect.c: 16 * bundle.c: 16 diff --git a/upload-pack.c b/upload-pack.c index a72ffc2..1270aa3 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -451,8 +451,16 @@ static int is_our_ref(struct object *o) (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1)); return o->flags & ((allow_hidden_ref ? HIDDEN_REF : 0) | OUR_REF); } - -static int check_unreachable(struct object_array *src) +/* + * If reachable is NULL, return 1 if there is no unreachable object, + * zero otherwise. + * + * If reachable is not NULL, it's filled with reachable objects. + * Return value is irrelevant. The caller has to compare reachable and + * src to find out if there's any unreachable object. + */ +static int check_unreachable(struct object_array *reachable, + struct object_array *src) { static const char *argv[] = { "rev-list", "--stdin", NULL, @@ -484,6 +492,8 @@ static int check_unreachable(struct object_array *src) o = get_indexed_object(--i); if (!o) continue; + if (reachable && o->type == OBJ_COMMIT) + o->flags &= ~TMP_MARK; if (!is_our_ref(o)) continue; memcpy(namebuf + 1, oid_to_hex(&o->oid), GIT_SHA1_HEXSZ); @@ -493,8 +503,13 @@ static int check_unreachable(struct object_array *src) namebuf[40] = '\n'; for (i = 0; i < src->nr; i++) { o = src->objects[i].item; - if (is_our_ref(o)) + if (is_our_ref(o)) { + if (reachable) + add_object_array(o, NULL, reachable); continue; + } + 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) return 0; @@ -507,9 +522,31 @@ static int check_unreachable(struct object_array *src) * The commits out of the rev-list are not ancestors of * our ref. */ - i = read_in_full(cmd.out, namebuf, 1); - if (i) - return 0; + if (!reachable) { + i = read_in_full(cmd.out, namebuf, 1); + if (i) + return 0; + } else { + while ((i = read_in_full(cmd.out, namebuf, 41)) == 41) { + struct object_id sha1; + + if (namebuf[40] != '\n' || get_oid_hex(namebuf, &sha1)) + break; + + o = lookup_object(sha1.hash); + if (o && o->type == OBJ_COMMIT) { + o->flags &= ~TMP_MARK; + } + } + for (i = get_max_object_index(); 0 < i; ) { + o = get_indexed_object(--i); + if (o && o->type == OBJ_COMMIT && + (o->flags & TMP_MARK)) { + add_object_array(o, NULL, reachable); + o->flags &= ~TMP_MARK; + } + } + } close(cmd.out); /* @@ -535,7 +572,7 @@ static void check_non_tip(void) */ if (!stateless_rpc && !(allow_unadvertised_object_request & ALLOW_REACHABLE_SHA1)) ; /* error */ - else if (check_unreachable(&want_obj)) + else if (check_unreachable(NULL, &want_obj)) return; /* Pick one of them (we know there at least is one) */ -- 2.7.0.377.g4cd97dd -- 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