Merge branch 'sp/maint-upload-pack-stop-early'
authorJunio C Hamano <gitster@pobox.com>
Wed, 23 Mar 2011 04:38:06 +0000 (21:38 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 23 Mar 2011 04:38:06 +0000 (21:38 -0700)
* sp/maint-upload-pack-stop-early:
upload-pack: Implement no-done capability
upload-pack: More aggressively send 'ACK %s ready'

1  2 
upload-pack.c
diff --combined upload-pack.c
index 0c87bc00f0e06e57b10154a026d797fb1500b4fe,5924f6f988aa03d8a2d74ab0b616524111bffcce..72aa661f8dabb7203001a7d9295dcf6c10ca75ee
@@@ -27,6 -27,7 +27,7 @@@ static const char upload_pack_usage[] 
  static unsigned long oldest_have;
  
  static int multi_ack, nr_our_refs;
+ static int no_done;
  static int use_thin_pack, use_ofs_delta, use_include_tag;
  static int no_progress, daemon_mode;
  static int shallow_nr;
@@@ -429,6 -430,9 +430,9 @@@ static int get_common_commits(void
        static char line[1000];
        unsigned char sha1[20];
        char last_hex[41];
+       int got_common = 0;
+       int got_other = 0;
+       int sent_ready = 0;
  
        save_commit_buffer = 0;
  
                reset_timeout();
  
                if (!len) {
+                       if (multi_ack == 2 && got_common
+                           && !got_other && ok_to_give_up()) {
+                               sent_ready = 1;
+                               packet_write(1, "ACK %s ready\n", last_hex);
+                       }
                        if (have_obj.nr == 0 || multi_ack)
                                packet_write(1, "NAK\n");
+                       if (no_done && sent_ready) {
+                               packet_write(1, "ACK %s\n", last_hex);
+                               return 0;
+                       }
                        if (stateless_rpc)
                                exit(0);
+                       got_common = 0;
+                       got_other = 0;
                        continue;
                }
                strip(line, len);
                if (!prefixcmp(line, "have ")) {
                        switch (got_sha1(line+5, sha1)) {
                        case -1: /* they have what we do not */
+                               got_other = 1;
                                if (multi_ack && ok_to_give_up()) {
                                        const char *hex = sha1_to_hex(sha1);
-                                       if (multi_ack == 2)
+                                       if (multi_ack == 2) {
+                                               sent_ready = 1;
                                                packet_write(1, "ACK %s ready\n", hex);
-                                       else
+                                       else
                                                packet_write(1, "ACK %s continue\n", hex);
                                }
                                break;
                        default:
+                               got_common = 1;
                                memcpy(last_hex, sha1_to_hex(sha1), 41);
                                if (multi_ack == 2)
                                        packet_write(1, "ACK %s common\n", last_hex);
@@@ -526,6 -545,8 +545,8 @@@ static void receive_needs(void
                        multi_ack = 2;
                else if (strstr(line+45, "multi_ack"))
                        multi_ack = 1;
+               if (strstr(line+45, "no-done"))
+                       no_done = 1;
                if (strstr(line+45, "thin-pack"))
                        use_thin_pack = 1;
                if (strstr(line+45, "ofs-delta"))
@@@ -619,7 -640,7 +640,7 @@@ static int send_ref(const char *refname
  {
        static const char *capabilities = "multi_ack thin-pack side-band"
                " side-band-64k ofs-delta shallow no-progress"
-               " include-tag multi_ack_detailed";
+               " include-tag multi_ack_detailed no-done";
        struct object *o = parse_object(sha1);
  
        if (!o)
@@@ -682,7 -703,6 +703,7 @@@ int main(int argc, char **argv
        int i;
        int strict = 0;
  
 +      packet_trace_identity("upload-pack");
        git_extract_argv0_path(argv[0]);
        read_replace_refs = 0;