X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=transport.c;h=7f94d30f95c26b8139fe7d63059633303f719d66;hb=e5f4e214636f9c9bd36c2897634108d5ad5587a1;hp=e0111dcf0b90e6d284505dd819144e5955cad699;hpb=c7a8a16239c6bdbb4041dd8a8773ae055d3cccf8;p=git.git diff --git a/transport.c b/transport.c index e0111dcf0..7f94d30f9 100644 --- a/transport.c +++ b/transport.c @@ -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)