Code

Merge branches 'sp/maint-fetch-pack-stop-early' and 'sp/maint-upload-pack-stop-early'
authorJunio C Hamano <gitster@pobox.com>
Tue, 29 Mar 2011 21:09:02 +0000 (14:09 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 29 Mar 2011 21:09:02 +0000 (14:09 -0700)
* sp/maint-fetch-pack-stop-early:
  enable "no-done" extension only when fetching over smart-http

* sp/maint-upload-pack-stop-early:
  enable "no-done" extension only when serving over smart-http

1  2  3 
builtin/fetch-pack.c
upload-pack.c

diff --combined builtin/fetch-pack.c
index bf9990ce15bf582293535606467fb209457bcfe1,52707a80adb403a887fa880c3286eb54afac5c05,b9994139345834a58b08a5ce57cf59c124e21760..65a8727453320f68e1230f702392c5ca3bb76884
@@@@ -1,4 -1,4 -1,4 +1,4 @@@@
 --#include "cache.h"
 ++#include "builtin.h"
   #include "refs.h"
   #include "pkt-line.h"
   #include "commit.h"
   #include "fetch-pack.h"
   #include "remote.h"
   #include "run-command.h"
 ++#include "transport.h"
   
   static int transfer_unpack_limit = -1;
   static int fetch_unpack_limit = -1;
   static int unpack_limit = 100;
   static int prefer_ofs_delta = 1;
  +static int no_done = 0;
   static struct fetch_pack_args args = {
        /* .uploadpack = */ "git-upload-pack",
   };
@@@@ -219,39 -218,15 -217,14 +219,39 @@@@ static void send_request(int fd, struc
                safe_write(fd, buf->buf, buf->len);
   }
   
 ++static void insert_one_alternate_ref(const struct ref *ref, void *unused)
 ++{
 ++     rev_list_insert_ref(NULL, ref->old_sha1, 0, NULL);
 ++}
 ++
 ++static void insert_alternate_refs(void)
 ++{
 ++     foreach_alt_odb(refs_from_alternate_cb, insert_one_alternate_ref);
 ++}
 ++
 ++#define INITIAL_FLUSH 16
 ++#define LARGE_FLUSH 1024
 ++
 ++static int next_flush(int count)
 ++{
 ++     if (count < INITIAL_FLUSH * 2)
 ++             count += INITIAL_FLUSH;
 ++     else if (count < LARGE_FLUSH)
 ++             count <<= 1;
 ++     else
 ++             count += LARGE_FLUSH;
 ++     return count;
 ++}
 ++
   static int find_common(int fd[2], unsigned char *result_sha1,
                       struct ref *refs)
   {
        int fetching;
 --     int count = 0, flushes = 0, retval;
 ++     int count = 0, flushes = 0, flush_at = INITIAL_FLUSH, retval;
        const unsigned char *sha1;
        unsigned in_vain = 0;
        int got_continue = 0;
  +     int got_ready = 0;
        struct strbuf req_buf = STRBUF_INIT;
        size_t state_len = 0;
   
        marked = 1;
   
        for_each_ref(rev_list_insert_ref, NULL);
 ++     insert_alternate_refs();
   
        fetching = 0;
        for ( ; refs ; refs = refs->next) {
                        struct strbuf c = STRBUF_INIT;
                        if (multi_ack == 2)     strbuf_addstr(&c, " multi_ack_detailed");
                        if (multi_ack == 1)     strbuf_addstr(&c, " multi_ack");
  +                     if (no_done)            strbuf_addstr(&c, " no-done");
                        if (use_sideband == 2)  strbuf_addstr(&c, " side-band-64k");
                        if (use_sideband == 1)  strbuf_addstr(&c, " side-band");
                        if (args.use_thin_pack) strbuf_addstr(&c, " thin-pack");
                if (args.verbose)
                        fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
                in_vain++;
 --             if (!(31 & ++count)) {
 ++             if (flush_at <= ++count) {
                        int ack;
   
                        packet_buf_flush(&req_buf);
                        send_request(fd[1], &req_buf);
                        strbuf_setlen(&req_buf, state_len);
                        flushes++;
 ++                     flush_at = next_flush(count);
   
                        /*
                         * We keep one window "ahead" of the other side, and
                         * will wait for an ACK only on the next one
                         */
 --                     if (!args.stateless_rpc && count == 32)
 ++                     if (!args.stateless_rpc && count == INITIAL_FLUSH)
                                continue;
   
                        consume_shallow_list(fd[0]);
                                        retval = 0;
                                        in_vain = 0;
                                        got_continue = 1;
  +                                     if (ack == ACK_ready) {
  +                                             rev_list = NULL;
  +                                             got_ready = 1;
  +                                     }
                                        break;
                                        }
                                }
                }
        }
   done:
  -     packet_buf_write(&req_buf, "done\n");
  -     send_request(fd[1], &req_buf);
  +     if (!got_ready || !no_done) {
  +             packet_buf_write(&req_buf, "done\n");
  +             send_request(fd[1], &req_buf);
  +     }
        if (args.verbose)
                fprintf(stderr, "done\n");
        if (retval != 0) {
@@@@ -732,11 -705,12 -696,6 +732,12 @@@@ static struct ref *do_fetch_pack(int fd
                if (args.verbose)
                        fprintf(stderr, "Server supports multi_ack_detailed\n");
                multi_ack = 2;
-                       no_done = 1;
  +             if (server_supports("no-done")) {
  +                     if (args.verbose)
  +                             fprintf(stderr, "Server supports no-done\n");
+ +                     if (args.stateless_rpc)
+ +                             no_done = 1;
  +             }
        }
        else if (server_supports("multi_ack")) {
                if (args.verbose)
@@@@ -845,8 -819,6 -804,6 +846,8 @@@@ int cmd_fetch_pack(int argc, const cha
        char **pack_lockfile_ptr = NULL;
        struct child_process *conn;
   
 ++     packet_trace_identity("fetch-pack");
 ++
        nr_heads = 0;
        heads = NULL;
        for (i = 1; i < argc; i++) {
diff --combined upload-pack.c
index 72aa661f8dabb7203001a7d9295dcf6c10ca75ee,b40a43f27d0e16f0305153f984741938b3a6ab89,a247fb9e272e3a44ded0fb9cfe1b64d3df5a158c..bba053f0aac8eef982d6779983dc6fd979d69d69
@@@@ -27,7 -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;
@@@@ -430,9 -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);
@@@@ -545,8 -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"))
@@@@ -640,15 -619,15 -640,16 +640,16 @@@@ 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 no-done";
+               " include-tag multi_ack_detailed";
        struct object *o = parse_object(sha1);
   
        if (!o)
                die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
   
        if (capabilities)
--              packet_write(1, "%s %s%c%s\n", sha1_to_hex(sha1), refname,
--                      0, capabilities);
++              packet_write(1, "%s %s%c%s%s\n", sha1_to_hex(sha1), refname,
++                           0, capabilities,
++                           stateless_rpc ? " no-done" : "");
        else
                packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname);
        capabilities = NULL;
@@@@ -703,7 -682,6 -704,6 +704,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;