Simplify fetch transport API to just one function
authorShawn O. Pearce <spearce@spearce.org>
Fri, 14 Sep 2007 07:31:21 +0000 (03:31 -0400)
committerJunio C Hamano <gitster@pobox.com>
Wed, 19 Sep 2007 10:22:30 +0000 (03:22 -0700)
Commit walkers need to know the SHA-1 name of any objects they
have been asked to fetch while the native pack transport only
wants to know the names of the remote refs as the remote side
must do the name->SHA-1 translation.

Since we only have three fetch implementations and one of them
(bundle) doesn't even need the name information we can reduce
the code required to perform a fetch by having just one function
and passing of the filtered list of refs to be fetched.  Each
transport can then obtain the information it needs from that ref
array to construct its own internal operation state.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Conflicts:

transport.c
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-fetch.c
transport.c
transport.h

index a041df9faf7e612bf84e588834446c0cfaf67620..f5a2718acc490ce9c746d2bf12db84c5a5cc0481 100644 (file)
@@ -355,7 +355,7 @@ static int do_fetch(struct transport *transport,
                no_tags = 1;
 
        if (!transport->ops || !transport->ops->get_refs_list ||
-           !(transport->ops->fetch_refs || transport->ops->fetch_objs))
+           !transport->ops->fetch)
                die("Don't know how to fetch from %s", transport->url);
 
        /* if not appending, truncate FETCH_HEAD */
index 2258492ae736eb6a7e0430de023ece70887dc242..d2cbf3acc117705888a81b27f53f2512e6a22db4 100644 (file)
 /* Generic functions for using commit walkers */
 
 static int fetch_objs_via_walker(const struct transport *transport,
-                                int nr_objs, char **objs)
+                                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;
 
+       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, dest))
                die("Fetch failed.");
 
+       for (i = 0; i < nr_objs; i++)
+               free(objs[i]);
+       free(objs);
        free(dest);
        return 0;
 }
@@ -179,8 +187,7 @@ static struct ref *get_refs_via_curl(const struct transport *transport)
 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_walker,
        /* push */              curl_transport_push,
        /* disconnect */        disconnect_walker
 };
@@ -213,7 +220,7 @@ static struct ref *get_refs_from_bundle(const struct transport *transport)
 }
 
 static int fetch_refs_from_bundle(const struct transport *transport,
-                              int nr_heads, char **heads)
+                              int nr_heads, struct ref **to_fetch)
 {
        struct bundle_transport_data *data = transport->data;
        return unbundle(&data->header, data->fd);
@@ -230,8 +237,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
 };
@@ -301,12 +307,14 @@ static struct ref *get_refs_via_connect(const struct transport *transport)
 }
 
 static int fetch_refs_via_pack(const struct transport *transport,
-                              int nr_heads, char **heads)
+                              int nr_heads, struct ref **to_fetch)
 {
        struct git_transport_data *data = transport->data;
+       char **heads = xmalloc(nr_heads * sizeof(*heads));
        struct ref *refs;
        char *dest = xstrdup(transport->url);
        struct fetch_pack_args args;
+       int i;
 
        args.uploadpack = data->uploadpack;
        args.quiet = 0;
@@ -320,14 +328,13 @@ static int fetch_refs_via_pack(const struct transport *transport,
 
        setup_fetch_pack(&args);
 
+       for (i = 0; i < nr_heads; i++)
+               heads[i] = xstrdup(to_fetch[i]->name);
        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++)
+               free(heads[i]);
        free_refs(refs);
-
        free(dest);
        return 0;
 }
@@ -379,8 +386,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
 };
 
@@ -476,37 +482,22 @@ struct ref *transport_get_remote_refs(struct transport *transport)
 
 int transport_fetch_refs(struct transport *transport, struct ref *refs)
 {
-       int i;
+       int rc;
        int nr_heads = 0, nr_alloc = 0;
-       char **heads = NULL;
+       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;
                ALLOC_GROW(heads, nr_heads + 1, nr_alloc);
-               if (use_objs) {
-                       heads[nr_heads++] = xstrdup(sha1_to_hex(rm->old_sha1));
-               } else {
-                       heads[nr_heads++] = xstrdup(rm->name);
-               }
-       }
-
-       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;
+               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;
 }
 
 int transport_disconnect(struct transport *transport)
index 5b0a6b065824c142babcdb28c03bceb48778827c..b354a8fd18be48c826558a2052872eb56bb136f0 100644 (file)
@@ -30,10 +30,7 @@ struct transport_ops {
                          const char *value);
 
        struct ref *(*get_refs_list)(const struct transport *transport);
-       int (*fetch_refs)(const struct transport *transport,
-                         int nr_refs, char **refs);
-       int (*fetch_objs)(const struct transport *transport,
-                         int nr_objs, char **objs);
+       int (*fetch)(const struct transport *transport, int refs_nr, struct ref **refs);
        int (*push)(struct transport *connection, int refspec_nr, const char **refspec, int flags);
 
        int (*disconnect)(struct transport *connection);