autodetect number of CPUs by default when using threads
[gitweb.git] / upload-pack.c
index eaea9990e944ead3d03967bcb026539cd2dc39eb..e5adbc011e0ab71eeb06a42c4bd40cbea0bf3fa2 100644 (file)
@@ -27,7 +27,8 @@ static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=n
 static unsigned long oldest_have;
 
 static int multi_ack, nr_our_refs;
-static int use_thin_pack, use_ofs_delta, no_progress;
+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 unsigned int timeout;
@@ -35,6 +36,7 @@ static unsigned int timeout;
  * otherwise maximum packet size (up to 65520 bytes).
  */
 static int use_sideband;
+static int debug_fd;
 
 static void reset_timeout(void)
 {
@@ -129,9 +131,12 @@ static int do_rev_list(int fd, void *create_full_pack)
                }
                setup_revisions(0, NULL, &revs, NULL);
        }
-       prepare_revision_walk(&revs);
+       if (prepare_revision_walk(&revs))
+               die("revision walk setup failed");
        mark_edges_uninteresting(revs.commits, &revs, show_edge);
        traverse_commit_list(&revs, show_commit, show_object);
+       fflush(pack_pipe);
+       fclose(pack_pipe);
        return 0;
 }
 
@@ -152,7 +157,7 @@ static void create_pack_file(void)
        /* .data is just a boolean: any non-NULL value will do */
        rev_list.data = create_full_pack ? &rev_list : NULL;
        if (start_async(&rev_list))
-               die("git-upload-pack: unable to fork git-rev-list");
+               die("git upload-pack: unable to fork git-rev-list");
 
        argv[arg++] = "pack-objects";
        argv[arg++] = "--stdout";
@@ -160,6 +165,8 @@ static void create_pack_file(void)
                argv[arg++] = "--progress";
        if (use_ofs_delta)
                argv[arg++] = "--delta-base-offset";
+       if (use_include_tag)
+               argv[arg++] = "--include-tag";
        argv[arg++] = NULL;
 
        memset(&pack_objects, 0, sizeof(pack_objects));
@@ -170,7 +177,7 @@ static void create_pack_file(void)
        pack_objects.argv = argv;
 
        if (start_command(&pack_objects))
-               die("git-upload-pack: unable to fork git-pack-objects");
+               die("git upload-pack: unable to fork git-pack-objects");
 
        /* We read from pack_objects.err to capture stderr output for
         * progress bar, and pack_objects.out to capture the pack data.
@@ -264,7 +271,7 @@ static void create_pack_file(void)
        }
 
        if (finish_command(&pack_objects)) {
-               error("git-upload-pack: git-pack-objects died with error.");
+               error("git upload-pack: git-pack-objects died with error.");
                goto fail;
        }
        if (finish_async(&rev_list))
@@ -284,7 +291,7 @@ static void create_pack_file(void)
 
  fail:
        send_client_data(3, abort_msg, sizeof(abort_msg));
-       die("git-upload-pack: %s", abort_msg);
+       die("git upload-pack: %s", abort_msg);
 }
 
 static int got_sha1(char *hex, unsigned char *sha1)
@@ -293,7 +300,7 @@ static int got_sha1(char *hex, unsigned char *sha1)
        int we_knew_they_have = 0;
 
        if (get_sha1_hex(hex, sha1))
-               die("git-upload-pack: expected SHA1 object, got '%s'", hex);
+               die("git upload-pack: expected SHA1 object, got '%s'", hex);
        if (!has_sha1_file(sha1))
                return -1;
 
@@ -392,7 +399,6 @@ static int get_common_commits(void)
        char hex[41], last_hex[41];
        int len;
 
-       track_object_refs = 0;
        save_commit_buffer = 0;
 
        for(;;) {
@@ -434,7 +440,7 @@ static int get_common_commits(void)
                        packet_write(1, "NAK\n");
                        return -1;
                }
-               die("git-upload-pack: expected SHA1 list, got '%s'", line);
+               die("git upload-pack: expected SHA1 list, got '%s'", line);
        }
 }
 
@@ -444,6 +450,8 @@ static void receive_needs(void)
        static char line[1000];
        int len, depth = 0;
 
+       if (debug_fd)
+               write_in_full(debug_fd, "#S\n", 3);
        for (;;) {
                struct object *o;
                unsigned char sha1_buf[20];
@@ -451,6 +459,8 @@ static void receive_needs(void)
                reset_timeout();
                if (!len)
                        break;
+               if (debug_fd)
+                       write_in_full(debug_fd, line, len);
 
                if (!prefixcmp(line, "shallow ")) {
                        unsigned char sha1[20];
@@ -475,7 +485,7 @@ static void receive_needs(void)
                }
                if (prefixcmp(line, "want ") ||
                    get_sha1_hex(line+5, sha1_buf))
-                       die("git-upload-pack: protocol error, "
+                       die("git upload-pack: protocol error, "
                            "expected to get sha, not '%s'", line);
                if (strstr(line+45, "multi_ack"))
                        multi_ack = 1;
@@ -489,6 +499,8 @@ static void receive_needs(void)
                        use_sideband = DEFAULT_PACKET_MAX;
                if (strstr(line+45, "no-progress"))
                        no_progress = 1;
+               if (strstr(line+45, "include-tag"))
+                       use_include_tag = 1;
 
                /* We have sent all our refs already, and the other end
                 * should have chosen out of them; otherwise they are
@@ -500,12 +512,14 @@ static void receive_needs(void)
                 */
                o = lookup_object(sha1_buf);
                if (!o || !(o->flags & OUR_REF))
-                       die("git-upload-pack: not our ref %s", line+5);
+                       die("git upload-pack: not our ref %s", line+5);
                if (!(o->flags & WANTED)) {
                        o->flags |= WANTED;
                        add_object_array(o, NULL, &want_obj);
                }
        }
+       if (debug_fd)
+               write_in_full(debug_fd, "#E\n", 3);
        if (depth == 0 && shallows.nr == 0)
                return;
        if (depth > 0) {
@@ -533,7 +547,8 @@ static void receive_needs(void)
                                /* make sure the real parents are parsed */
                                unregister_shallow(object->sha1);
                                object->parsed = 0;
-                               parse_commit((struct commit *)object);
+                               if (parse_commit((struct commit *)object))
+                                       die("invalid commit");
                                parents = ((struct commit *)object)->parents;
                                while (parents) {
                                        add_object_array(&parents->item->object,
@@ -557,11 +572,12 @@ static void receive_needs(void)
 static int send_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
 {
        static const char *capabilities = "multi_ack thin-pack side-band"
-               " side-band-64k ofs-delta shallow no-progress";
+               " side-band-64k ofs-delta shallow no-progress"
+               " include-tag";
        struct object *o = parse_object(sha1);
 
        if (!o)
-               die("git-upload-pack: cannot find object %s:", sha1_to_hex(sha1));
+               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,
@@ -622,7 +638,7 @@ int main(int argc, char **argv)
        if (i != argc-1)
                usage(upload_pack_usage);
 
-       setup_path(NULL);
+       setup_path();
 
        dir = argv[i];
 
@@ -630,6 +646,8 @@ int main(int argc, char **argv)
                die("'%s': unable to chdir or not a git archive", dir);
        if (is_repository_shallow())
                die("attempt to fetch/clone from a shallow repository");
+       if (getenv("GIT_DEBUG_SEND_PACK"))
+               debug_fd = atoi(getenv("GIT_DEBUG_SEND_PACK"));
        upload_pack();
        return 0;
 }