send-pack --keep: do not explode into loose objects on the receiving end.
[gitweb.git] / upload-pack.c
index b673d8cb9748de0758d1c5269178e70a018f43a1..9ec3775049a44bf1ffdc145240e6d7cdea303b91 100644 (file)
@@ -16,7 +16,7 @@ static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=n
 #define OUR_REF (1U << 1)
 #define WANTED (1U << 2)
 static int multi_ack, nr_our_refs;
-static int use_thin_pack;
+static int use_thin_pack, use_ofs_delta;
 static struct object_array have_obj;
 static struct object_array want_obj;
 static unsigned int timeout;
@@ -137,7 +137,9 @@ static void create_pack_file(void)
                close(pu_pipe[1]);
                close(pe_pipe[0]);
                close(pe_pipe[1]);
-               execl_git_cmd("pack-objects", "--stdout", "--progress", NULL);
+               execl_git_cmd("pack-objects", "--stdout", "--progress",
+                             use_ofs_delta ? "--delta-base-offset" : NULL,
+                             NULL);
                kill(pid_rev_list, SIGKILL);
                die("git-upload-pack: unable to exec git-pack-objects");
        }
@@ -329,7 +331,8 @@ static int got_sha1(char *hex, unsigned char *sha1)
 static int get_common_commits(void)
 {
        static char line[1000];
-       unsigned char sha1[20], last_sha1[20];
+       unsigned char sha1[20];
+       char hex[41], last_hex[41];
        int len;
 
        track_object_refs = 0;
@@ -346,21 +349,22 @@ static int get_common_commits(void)
                }
                len = strip(line, len);
                if (!strncmp(line, "have ", 5)) {
-                       if (got_sha1(line+5, sha1) &&
-                           (multi_ack || have_obj.nr == 1)) {
-                               packet_write(1, "ACK %s%s\n",
-                                            sha1_to_hex(sha1),
-                                            multi_ack ?  " continue" : "");
-                               if (multi_ack)
-                                       hashcpy(last_sha1, sha1);
+                       if (got_sha1(line+5, sha1)) {
+                               memcpy(hex, sha1_to_hex(sha1), 41);
+                               if (multi_ack) {
+                                       const char *msg = "ACK %s continue\n";
+                                       packet_write(1, msg, hex);
+                                       memcpy(last_hex, hex, 41);
+                               }
+                               else if (have_obj.nr == 1)
+                                       packet_write(1, "ACK %s\n", hex);
                        }
                        continue;
                }
                if (!strcmp(line, "done")) {
                        if (have_obj.nr > 0) {
                                if (multi_ack)
-                                       packet_write(1, "ACK %s\n",
-                                                       sha1_to_hex(last_sha1));
+                                       packet_write(1, "ACK %s\n", last_hex);
                                return 0;
                        }
                        packet_write(1, "NAK\n");
@@ -391,6 +395,8 @@ static void receive_needs(void)
                        multi_ack = 1;
                if (strstr(line+45, "thin-pack"))
                        use_thin_pack = 1;
+               if (strstr(line+45, "ofs-delta"))
+                       use_ofs_delta = 1;
                if (strstr(line+45, "side-band-64k"))
                        use_sideband = LARGE_PACKET_MAX;
                else if (strstr(line+45, "side-band"))
@@ -416,7 +422,7 @@ static void receive_needs(void)
 
 static int send_ref(const char *refname, const unsigned char *sha1)
 {
-       static const char *capabilities = "multi_ack thin-pack side-band side-band-64k";
+       static const char *capabilities = "multi_ack thin-pack side-band side-band-64k ofs-delta";
        struct object *o = parse_object(sha1);
 
        if (!o)