git-svn: optimize --branch and --branch-all-ref
[gitweb.git] / http-push.c
index 21c5289cde14d1a91c691f263c35c498d7beeaea..b39b36b7679d5c5d928d711895ccfc5f66c353d4 100644 (file)
@@ -6,6 +6,7 @@
 #include "blob.h"
 #include "http.h"
 #include "refs.h"
+#include "diff.h"
 #include "revision.h"
 #include "exec_cmd.h"
 
@@ -59,12 +60,12 @@ enum XML_Status {
 #define LOCK_TIME 600
 #define LOCK_REFRESH 30
 
-/* bits #0-4 in revision.h */
+/* bits #0-15 in revision.h */
 
-#define LOCAL    (1u << 5)
-#define REMOTE   (1u << 6)
-#define FETCHING (1u << 7)
-#define PUSHING  (1u << 8)
+#define LOCAL    (1u<<16)
+#define REMOTE   (1u<<17)
+#define FETCHING (1u<<18)
+#define PUSHING  (1u<<19)
 
 /* We allow "recursive" symbolic refs. Only within reason, though */
 #define MAXDEPTH 5
@@ -185,6 +186,7 @@ static void process_response(void *callback_data)
        finish_request(request);
 }
 
+#ifdef USE_CURL_MULTI
 static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
                               void *data)
 {
@@ -348,6 +350,41 @@ static void start_fetch_loose(struct transfer_request *request)
        }
 }
 
+static void start_mkcol(struct transfer_request *request)
+{
+       char *hex = sha1_to_hex(request->obj->sha1);
+       struct active_request_slot *slot;
+       char *posn;
+
+       request->url = xmalloc(strlen(remote->url) + 13);
+       strcpy(request->url, remote->url);
+       posn = request->url + strlen(remote->url);
+       strcpy(posn, "objects/");
+       posn += 8;
+       memcpy(posn, hex, 2);
+       posn += 2;
+       strcpy(posn, "/");
+
+       slot = get_active_slot();
+       slot->callback_func = process_response;
+       slot->callback_data = request;
+       curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); /* undo PUT setup */
+       curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
+       curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, request->errorstr);
+       curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MKCOL);
+       curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
+
+       if (start_active_slot(slot)) {
+               request->slot = slot;
+               request->state = RUN_MKCOL;
+       } else {
+               request->state = ABORTED;
+               free(request->url);
+               request->url = NULL;
+       }
+}
+#endif
+
 static void start_fetch_packed(struct transfer_request *request)
 {
        char *url;
@@ -437,40 +474,6 @@ static void start_fetch_packed(struct transfer_request *request)
        }
 }
 
-static void start_mkcol(struct transfer_request *request)
-{
-       char *hex = sha1_to_hex(request->obj->sha1);
-       struct active_request_slot *slot;
-       char *posn;
-
-       request->url = xmalloc(strlen(remote->url) + 13);
-       strcpy(request->url, remote->url);
-       posn = request->url + strlen(remote->url);
-       strcpy(posn, "objects/");
-       posn += 8;
-       memcpy(posn, hex, 2);
-       posn += 2;
-       strcpy(posn, "/");
-
-       slot = get_active_slot();
-       slot->callback_func = process_response;
-       slot->callback_data = request;
-       curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); /* undo PUT setup */
-       curl_easy_setopt(slot->curl, CURLOPT_URL, request->url);
-       curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, request->errorstr);
-       curl_easy_setopt(slot->curl, CURLOPT_CUSTOMREQUEST, DAV_MKCOL);
-       curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_null);
-
-       if (start_active_slot(slot)) {
-               request->slot = slot;
-               request->state = RUN_MKCOL;
-       } else {
-               request->state = ABORTED;
-               free(request->url);
-               request->url = NULL;
-       }
-}
-
 static void start_put(struct transfer_request *request)
 {
        char *hex = sha1_to_hex(request->obj->sha1);
@@ -622,7 +625,7 @@ static int refresh_lock(struct remote_lock *lock)
        return rc;
 }
 
-static void check_locks()
+static void check_locks(void)
 {
        struct remote_lock *lock = remote->locks;
        time_t current_time = time(NULL);
@@ -787,6 +790,7 @@ static void finish_request(struct transfer_request *request)
        }
 }
 
+#ifdef USE_CURL_MULTI
 void fill_active_slots(void)
 {
        struct transfer_request *request = request_queue_head;
@@ -820,6 +824,7 @@ void fill_active_slots(void)
                slot = slot->next;
        }
 }
+#endif
 
 static void get_remote_object_list(unsigned char parent);
 
@@ -850,8 +855,10 @@ static void add_fetch_request(struct object *obj)
        request->next = request_queue_head;
        request_queue_head = request;
 
+#ifdef USE_CURL_MULTI
        fill_active_slots();
        step_active_slots();
+#endif
 }
 
 static int add_send_request(struct object *obj, struct remote_lock *lock)
@@ -888,8 +895,10 @@ static int add_send_request(struct object *obj, struct remote_lock *lock)
        request->next = request_queue_head;
        request_queue_head = request;
 
+#ifdef USE_CURL_MULTI
        fill_active_slots();
        step_active_slots();
+#endif
 
        return 1;
 }
@@ -1008,8 +1017,7 @@ static int fetch_indices(void)
        struct active_request_slot *slot;
        struct slot_results results;
 
-       data = xmalloc(4096);
-       memset(data, 0, 4096);
+       data = xcalloc(1, 4096);
        buffer.size = 4096;
        buffer.posn = 0;
        buffer.buffer = data;
@@ -1212,7 +1220,7 @@ static void
 xml_start_tag(void *userData, const char *name, const char **atts)
 {
        struct xml_ctx *ctx = (struct xml_ctx *)userData;
-       const char *c = index(name, ':');
+       const char *c = strchr(name, ':');
        int new_len;
 
        if (c == NULL)
@@ -1241,7 +1249,7 @@ static void
 xml_end_tag(void *userData, const char *name)
 {
        struct xml_ctx *ctx = (struct xml_ctx *)userData;
-       const char *c = index(name, ':');
+       const char *c = strchr(name, ':');
        char *ep;
 
        ctx->userFunc(ctx, 1);
@@ -1704,6 +1712,7 @@ static struct object_list **process_blob(struct blob *blob,
                return p;
 
        obj->flags |= SEEN;
+       name = strdup(name);
        return add_object(obj, p, path, name);
 }
 
@@ -1713,7 +1722,8 @@ static struct object_list **process_tree(struct tree *tree,
                                         const char *name)
 {
        struct object *obj = &tree->object;
-       struct tree_entry_list *entry;
+       struct tree_desc desc;
+       struct name_entry entry;
        struct name_path me;
 
        obj->flags |= LOCAL;
@@ -1724,21 +1734,23 @@ static struct object_list **process_tree(struct tree *tree,
                die("bad tree object %s", sha1_to_hex(obj->sha1));
 
        obj->flags |= SEEN;
+       name = strdup(name);
        p = add_object(obj, p, NULL, name);
        me.up = path;
        me.elem = name;
        me.elem_len = strlen(name);
-       entry = tree->entries;
-       tree->entries = NULL;
-       while (entry) {
-               struct tree_entry_list *next = entry->next;
-               if (entry->directory)
-                       p = process_tree(entry->item.tree, p, &me, entry->name);
+
+       desc.buf = tree->buffer;
+       desc.size = tree->size;
+
+       while (tree_entry(&desc, &entry)) {
+               if (S_ISDIR(entry.mode))
+                       p = process_tree(lookup_tree(entry.sha1), p, &me, name);
                else
-                       p = process_blob(entry->item.blob, p, &me, entry->name);
-               free(entry);
-               entry = next;
+                       p = process_blob(lookup_blob(entry.sha1), p, &me, name);
        }
+       free(tree->buffer);
+       tree->buffer = NULL;
        return p;
 }
 
@@ -2042,8 +2054,7 @@ static void update_remote_info_refs(struct remote_lock *lock)
        char *if_header;
        struct curl_slist *dav_headers = NULL;
 
-       buffer.buffer = xmalloc(4096);
-       memset(buffer.buffer, 0, 4096);
+       buffer.buffer = xcalloc(1, 4096);
        buffer.size = 4096;
        buffer.posn = 0;
        remote_ls("refs/", (PROCESS_FILES | RECURSIVE),
@@ -2352,7 +2363,7 @@ int main(int argc, char **argv)
                        char *path = strstr(arg, "//");
                        remote->url = arg;
                        if (path) {
-                               path = index(path+2, '/');
+                               path = strchr(path+2, '/');
                                if (path)
                                        remote->path_len = strlen(path);
                        }
@@ -2499,6 +2510,7 @@ int main(int argc, char **argv)
                        commit_argv[3] = old_sha1_hex;
                        commit_argc++;
                }
+               init_revisions(&revs);
                setup_revisions(commit_argc, commit_argv, &revs, NULL);
                free(new_sha1_hex);
                if (old_sha1_hex) {
@@ -2519,7 +2531,9 @@ int main(int argc, char **argv)
                if (objects_to_send)
                        fprintf(stderr, "    sending %d objects\n",
                                objects_to_send);
+#ifdef USE_CURL_MULTI
                fill_active_slots();
+#endif
                finish_all_active_slots();
 
                /* Update the remote branch if all went well */