diff options
Diffstat (limited to 'transport.c')
-rw-r--r-- | transport.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/transport.c b/transport.c index 1e7374977e..e0111dcf0b 100644 --- a/transport.c +++ b/transport.c @@ -5,6 +5,7 @@ #include "pkt-line.h" #include "fetch-pack.h" #include "walker.h" +#include "bundle.h" /* Generic functions for using commit walkers */ @@ -184,7 +185,55 @@ static const struct transport_ops curl_transport = { /* disconnect */ disconnect_walker }; +struct bundle_transport_data { + int fd; + struct bundle_header header; +}; + +static struct ref *get_refs_from_bundle(const struct transport *transport) +{ + struct bundle_transport_data *data = transport->data; + struct ref *result = NULL; + int i; + + if (data->fd > 0) + close(data->fd); + data->fd = read_bundle_header(transport->url, &data->header); + if (data->fd < 0) + die ("Could not read bundle '%s'.", transport->url); + for (i = 0; i < data->header.references.nr; i++) { + struct ref_list_entry *e = data->header.references.list + i; + struct ref *ref = alloc_ref(strlen(e->name)); + hashcpy(ref->old_sha1, e->sha1); + strcpy(ref->name, e->name); + ref->next = result; + result = ref; + } + return result; +} + +static int fetch_refs_from_bundle(const struct transport *transport, + int nr_heads, char **heads) +{ + struct bundle_transport_data *data = transport->data; + return unbundle(&data->header, data->fd); +} + +static int close_bundle(struct transport *transport) +{ + struct bundle_transport_data *data = transport->data; + if (data->fd > 0) + close(data->fd); + return 0; +} + 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, + /* push */ NULL, + /* disconnect */ close_bundle }; struct git_transport_data { @@ -367,8 +416,9 @@ struct transport *transport_get(struct remote *remote, const char *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 = NULL; + ret->data = data; ret->ops = &bundle_transport; } else { struct git_transport_data *data = xcalloc(1, sizeof(*data)); |