OSDN Git Service

upload-pack: add get_reachable_list()
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Sun, 12 Jun 2016 10:54:08 +0000 (17:54 +0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 13 Jun 2016 21:38:16 +0000 (14:38 -0700)
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
object.h
upload-pack.c

index f8b6442..614a006 100644 (file)
--- 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
index adb8e33..3227df8 100644 (file)
@@ -456,7 +456,8 @@ static int is_our_ref(struct object *o)
  * 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 *src,
+                               struct object_array *reachable)
 {
        static const char *argv[] = {
                "rev-list", "--stdin", NULL,
@@ -487,6 +488,8 @@ static int do_reachable_revlist(struct child_process *cmd,
                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);
@@ -496,8 +499,13 @@ static int do_reachable_revlist(struct child_process *cmd,
        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)
                        goto error;
@@ -518,13 +526,51 @@ error:
        return -1;
 }
 
+static int get_reachable_list(struct object_array *src,
+                             struct object_array *reachable)
+{
+       struct child_process cmd = CHILD_PROCESS_INIT;
+       int i;
+       struct object *o;
+       char namebuf[42]; /* ^ + SHA-1 + LF */
+
+       if (do_reachable_revlist(&cmd, src, reachable) < 0)
+               return -1;
+
+       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; i--) {
+               o = get_indexed_object(i - 1);
+               if (o && o->type == OBJ_COMMIT &&
+                   (o->flags & TMP_MARK)) {
+                       add_object_array(o, NULL, reachable);
+                               o->flags &= ~TMP_MARK;
+               }
+       }
+       close(cmd.out);
+
+       if (finish_command(&cmd))
+               return -1;
+
+       return 0;
+}
+
 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) < 0)
+       if (do_reachable_revlist(&cmd, src, NULL) < 0)
                return 1;
 
        /*