Code

Remove unnecessary 'fetch' argument from transport_get API
[git.git] / transport.c
index e0111dcf0b90e6d284505dd819144e5955cad699..7f94d30f95c26b8139fe7d63059633303f719d66 100644 (file)
@@ -9,11 +9,13 @@
 
 /* Generic functions for using commit walkers */
 
-static int fetch_objs_via_walker(const struct transport *transport,
-                                int nr_objs, char **objs)
+static int fetch_objs_via_walker(struct transport *transport,
+                                int nr_objs, struct ref **to_fetch)
 {
        char *dest = xstrdup(transport->url);
        struct walker *walker = transport->data;
+       char **objs = xmalloc(nr_objs * sizeof(*objs));
+       int i;
 
        walker->get_all = 1;
        walker->get_tree = 1;
@@ -21,9 +23,15 @@ static int fetch_objs_via_walker(const struct transport *transport,
        walker->get_verbosely = transport->verbose;
        walker->get_recover = 0;
 
-       if (walker_fetch(walker, nr_objs, objs, NULL, dest))
+       for (i = 0; i < nr_objs; i++)
+               objs[i] = xstrdup(sha1_to_hex(to_fetch[i]->old_sha1));
+
+       if (walker_fetch(walker, nr_objs, objs, NULL, NULL))
                die("Fetch failed.");
 
+       for (i = 0; i < nr_objs; i++)
+               free(objs[i]);
+       free(objs);
        free(dest);
        return 0;
 }
@@ -166,6 +174,14 @@ static struct ref *get_refs_via_curl(const struct transport *transport)
        return refs;
 }
 
+static int fetch_objs_via_curl(struct transport *transport,
+                                int nr_objs, struct ref **to_fetch)
+{
+       if (!transport->data)
+               transport->data = get_http_walker(transport->url);
+       return fetch_objs_via_walker(transport, nr_objs, to_fetch);
+}
+
 #else
 
 static struct ref *get_refs_via_curl(const struct transport *transport)
@@ -174,13 +190,19 @@ static struct ref *get_refs_via_curl(const struct transport *transport)
        return NULL;
 }
 
+static int fetch_objs_via_curl(struct transport *transport,
+                                int nr_objs, struct ref **to_fetch)
+{
+       die("Cannot fetch from '%s' without curl ...", transport->url);
+       return -1;
+}
+
 #endif
 
 static const struct transport_ops curl_transport = {
        /* set_option */        NULL,
        /* get_refs_list */     get_refs_via_curl,
-       /* fetch_refs */        NULL,
-       /* fetch_objs */        fetch_objs_via_walker,
+       /* fetch */             fetch_objs_via_curl,
        /* push */              curl_transport_push,
        /* disconnect */        disconnect_walker
 };
@@ -212,8 +234,8 @@ static struct ref *get_refs_from_bundle(const struct transport *transport)
        return result;
 }
 
-static int fetch_refs_from_bundle(const struct transport *transport,
-                              int nr_heads, char **heads)
+static int fetch_refs_from_bundle(struct transport *transport,
+                              int nr_heads, struct ref **to_fetch)
 {
        struct bundle_transport_data *data = transport->data;
        return unbundle(&data->header, data->fd);
@@ -230,8 +252,7 @@ static int close_bundle(struct transport *transport)
 static const struct transport_ops bundle_transport = {
        /* set_option */        NULL,
        /* get_refs_list */     get_refs_from_bundle,
-       /* fetch_refs */        fetch_refs_from_bundle,
-       /* fetch_objs */        NULL,
+       /* fetch */             fetch_refs_from_bundle,
        /* push */              NULL,
        /* disconnect */        close_bundle
 };
@@ -300,13 +321,16 @@ static struct ref *get_refs_via_connect(const struct transport *transport)
        return refs;
 }
 
-static int fetch_refs_via_pack(const struct transport *transport,
-                              int nr_heads, char **heads)
+static int fetch_refs_via_pack(struct transport *transport,
+                              int nr_heads, struct ref **to_fetch)
 {
        struct git_transport_data *data = transport->data;
+       char **heads = xmalloc(nr_heads * sizeof(*heads));
+       char **origh = xmalloc(nr_heads * sizeof(*origh));
        struct ref *refs;
        char *dest = xstrdup(transport->url);
        struct fetch_pack_args args;
+       int i;
 
        args.uploadpack = data->uploadpack;
        args.quiet = 0;
@@ -320,14 +344,15 @@ static int fetch_refs_via_pack(const struct transport *transport,
 
        setup_fetch_pack(&args);
 
-       refs = fetch_pack(dest, nr_heads, heads);
-
-       // ???? check that refs got everything?
-
-       /* free the memory used for the refs list ... */
+       for (i = 0; i < nr_heads; i++)
+               origh[i] = heads[i] = xstrdup(to_fetch[i]->name);
+       refs = fetch_pack(dest, nr_heads, heads, &transport->pack_lockfile);
 
+       for (i = 0; i < nr_heads; i++)
+               free(origh[i]);
+       free(origh);
+       free(heads);
        free_refs(refs);
-
        free(dest);
        return 0;
 }
@@ -379,8 +404,7 @@ static int git_transport_push(struct transport *transport, int refspec_nr, const
 static const struct transport_ops git_transport = {
        /* set_option */        set_git_option,
        /* get_refs_list */     get_refs_via_connect,
-       /* fetch_refs */        fetch_refs_via_pack,
-       /* fetch_objs */        NULL,
+       /* fetch */             fetch_refs_via_pack,
        /* push */              git_transport_push
 };
 
@@ -399,30 +423,25 @@ static int is_file(const char *url)
        return S_ISREG(buf.st_mode);
 }
 
-struct transport *transport_get(struct remote *remote, const char *url,
-                               int fetch)
+struct transport *transport_get(struct remote *remote, const char *url)
 {
-       struct transport *ret = NULL;
+       struct transport *ret = xcalloc(1, sizeof(*ret));
+
+       ret->remote = remote;
+       ret->url = url;
+
        if (!prefixcmp(url, "rsync://")) {
-               ret = xmalloc(sizeof(*ret));
-               ret->data = NULL;
                ret->ops = &rsync_transport;
-       } else if (!prefixcmp(url, "http://") || !prefixcmp(url, "https://") ||
-                  !prefixcmp(url, "ftp://")) {
-               ret = xmalloc(sizeof(*ret));
+       } else if (!prefixcmp(url, "http://")
+               || !prefixcmp(url, "https://")
+               || !prefixcmp(url, "ftp://")) {
                ret->ops = &curl_transport;
-               if (fetch)
-                       ret->data = get_http_walker(url);
-               else
-                       ret->data = NULL;
        } else if (is_local(url) && is_file(url)) {
                struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
-               ret = xmalloc(sizeof(*ret));
                ret->data = data;
                ret->ops = &bundle_transport;
        } else {
                struct git_transport_data *data = xcalloc(1, sizeof(*data));
-               ret = xcalloc(1, sizeof(*ret));
                ret->data = data;
                data->thin = 1;
                data->uploadpack = "git-upload-pack";
@@ -434,12 +453,7 @@ struct transport *transport_get(struct remote *remote, const char *url,
                data->unpacklimit = -1;
                ret->ops = &git_transport;
        }
-       if (ret) {
-               ret->remote = remote;
-               ret->url = url;
-               ret->remote_refs = NULL;
-               ret->fetch = !!fetch;
-       }
+
        return ret;
 }
 
@@ -474,44 +488,33 @@ struct ref *transport_get_remote_refs(struct transport *transport)
        return transport->remote_refs;
 }
 
-#define PACK_HEADS_CHUNK_COUNT 256
-
 int transport_fetch_refs(struct transport *transport, struct ref *refs)
 {
-       int i;
-       int nr_heads = 0;
-       char **heads = xmalloc(PACK_HEADS_CHUNK_COUNT * sizeof(char *));
+       int rc;
+       int nr_heads = 0, nr_alloc = 0;
+       struct ref **heads = NULL;
        struct ref *rm;
-       int use_objs = !transport->ops->fetch_refs;
 
        for (rm = refs; rm; rm = rm->next) {
                if (rm->peer_ref &&
                    !hashcmp(rm->peer_ref->old_sha1, rm->old_sha1))
                        continue;
-               if (use_objs) {
-                       heads[nr_heads++] = xstrdup(sha1_to_hex(rm->old_sha1));
-               } else {
-                       heads[nr_heads++] = xstrdup(rm->name);
-               }
-               if (nr_heads % PACK_HEADS_CHUNK_COUNT == 0)
-                       heads = xrealloc(heads,
-                                        (nr_heads + PACK_HEADS_CHUNK_COUNT) *
-                                        sizeof(char *));
-       }
-
-       if (use_objs) {
-               if (transport->ops->fetch_objs(transport, nr_heads, heads))
-                       return -1;
-       } else {
-               if (transport->ops->fetch_refs(transport, nr_heads, heads))
-                       return -1;
+               ALLOC_GROW(heads, nr_heads + 1, nr_alloc);
+               heads[nr_heads++] = rm;
        }
 
-       /* free the memory used for the heads list ... */
-       for (i = 0; i < nr_heads; i++)
-               free(heads[i]);
+       rc = transport->ops->fetch(transport, nr_heads, heads);
        free(heads);
-       return 0;
+       return rc;
+}
+
+void transport_unlock_pack(struct transport *transport)
+{
+       if (transport->pack_lockfile) {
+               unlink(transport->pack_lockfile);
+               free(transport->pack_lockfile);
+               transport->pack_lockfile = NULL;
+       }
 }
 
 int transport_disconnect(struct transport *transport)