make shallow repository deepening more network efficient
authorNicolas Pitre <nico@cam.org>
Thu, 3 Sep 2009 23:08:33 +0000 (19:08 -0400)
committerJunio C Hamano <gitster@pobox.com>
Sun, 6 Sep 2009 05:25:26 +0000 (22:25 -0700)
First of all, I can't find any reason why thin pack generation is
explicitly disabled when dealing with a shallow repository.  The
possible delta base objects are collected from the edge commits which
are always obtained through history walking with the same shallow refs
as the client, Therefore the client is always going to have those base
objects available. So let's remove that restriction.

Then we can make shallow repository deepening much more efficient by
using the remote's unshallowed commits as edge commits to get preferred
base objects for thin pack generation.  On git.git, this makes the data
transfer for the deepening of a shallow repository from depth 1 to depth 2
around 134 KB instead of 3.68 MB.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
upload-pack.c

index edc7861..7428ff7 100644 (file)
@@ -31,6 +31,7 @@ static int use_thin_pack, use_ofs_delta, use_include_tag;
 static int no_progress;
 static struct object_array have_obj;
 static struct object_array want_obj;
 static int no_progress;
 static struct object_array have_obj;
 static struct object_array want_obj;
+static struct object_array extra_edge_obj;
 static unsigned int timeout;
 /* 0 for no sideband,
  * otherwise maximum packet size (up to 65520 bytes).
 static unsigned int timeout;
 /* 0 for no sideband,
  * otherwise maximum packet size (up to 65520 bytes).
@@ -136,6 +137,10 @@ static int do_rev_list(int fd, void *create_full_pack)
        if (prepare_revision_walk(&revs))
                die("revision walk setup failed");
        mark_edges_uninteresting(revs.commits, &revs, show_edge);
        if (prepare_revision_walk(&revs))
                die("revision walk setup failed");
        mark_edges_uninteresting(revs.commits, &revs, show_edge);
+       if (use_thin_pack)
+               for (i = 0; i < extra_edge_obj.nr; i++)
+                       fprintf(pack_pipe, "-%s\n", sha1_to_hex(
+                                       extra_edge_obj.objects[i].item->sha1));
        traverse_commit_list(&revs, show_commit, show_object, NULL);
        fflush(pack_pipe);
        fclose(pack_pipe);
        traverse_commit_list(&revs, show_commit, show_object, NULL);
        fflush(pack_pipe);
        fclose(pack_pipe);
@@ -466,7 +471,6 @@ static void receive_needs(void)
                if (!prefixcmp(line, "shallow ")) {
                        unsigned char sha1[20];
                        struct object *object;
                if (!prefixcmp(line, "shallow ")) {
                        unsigned char sha1[20];
                        struct object *object;
-                       use_thin_pack = 0;
                        if (get_sha1(line + 8, sha1))
                                die("invalid shallow line: %s", line);
                        object = parse_object(sha1);
                        if (get_sha1(line + 8, sha1))
                                die("invalid shallow line: %s", line);
                        object = parse_object(sha1);
@@ -478,7 +482,6 @@ static void receive_needs(void)
                }
                if (!prefixcmp(line, "deepen ")) {
                        char *end;
                }
                if (!prefixcmp(line, "deepen ")) {
                        char *end;
-                       use_thin_pack = 0;
                        depth = strtol(line + 7, &end, 0);
                        if (end == line + 7 || depth <= 0)
                                die("Invalid deepen: %s", line);
                        depth = strtol(line + 7, &end, 0);
                        if (end == line + 7 || depth <= 0)
                                die("Invalid deepen: %s", line);
@@ -556,6 +559,7 @@ static void receive_needs(void)
                                                        NULL, &want_obj);
                                        parents = parents->next;
                                }
                                                        NULL, &want_obj);
                                        parents = parents->next;
                                }
+                               add_object_array(object, NULL, &extra_edge_obj);
                        }
                        /* make sure commit traversal conforms to client */
                        register_shallow(object->sha1);
                        }
                        /* make sure commit traversal conforms to client */
                        register_shallow(object->sha1);