diff options
author | Vicent Marti <tanoku@gmail.com> | 2011-11-28 08:40:40 +0100 |
---|---|---|
committer | Vicent Marti <tanoku@gmail.com> | 2011-11-28 08:40:40 +0100 |
commit | d88d4311c7e08ad0d38edae006b50e2a548c937d (patch) | |
tree | 1b26cee0c3d383043902c599893299fd8fdc5302 /src/transports/local.c | |
parent | c94785a9f373b6604402ba6a301b828b80ab8cd8 (diff) | |
download | libgit2-d88d4311c7e08ad0d38edae006b50e2a548c937d.tar.gz |
remote: Cleanup the remotes coderepo-ownership
- Hide the remaining transports code
- Drop `git_headarray`, switch to using a callback to list refs. Makes
the code cleaner.
Diffstat (limited to 'src/transports/local.c')
-rw-r--r-- | src/transports/local.c | 167 |
1 files changed, 86 insertions, 81 deletions
diff --git a/src/transports/local.c b/src/transports/local.c index afc17e55f..f50a96173 100644 --- a/src/transports/local.c +++ b/src/transports/local.c @@ -6,7 +6,6 @@ */ #include "common.h" #include "git2/types.h" -#include "git2/transport.h" #include "git2/net.h" #include "git2/repository.h" #include "git2/object.h" @@ -18,39 +17,10 @@ typedef struct { git_transport parent; git_repository *repo; - git_vector *refs; + git_vector refs; } transport_local; -/* - * Try to open the url as a git directory. The direction doesn't - * matter in this case because we're calulating the heads ourselves. - */ -static int local_connect(git_transport *transport, int GIT_UNUSED(direction)) -{ - git_repository *repo; - int error; - transport_local *t = (transport_local *) transport; - const char *path; - const char file_prefix[] = "file://"; - GIT_UNUSED_ARG(direction); - - /* The repo layer doesn't want the prefix */ - if (!git__prefixcmp(transport->url, file_prefix)) - path = transport->url + strlen(file_prefix); - else - path = transport->url; - - error = git_repository_open(&repo, path); - if (error < GIT_SUCCESS) - return git__rethrow(error, "Failed to open remote"); - - t->repo = repo; - t->parent.connected = 1; - - return GIT_SUCCESS; -} - -static int add_ref(const char *name, git_repository *repo, git_vector *vec) +static int add_ref(transport_local *t, const char *name) { const char peeled[] = "^{}"; git_remote_head *head; @@ -68,7 +38,7 @@ static int add_ref(const char *name, git_repository *repo, git_vector *vec) goto out; } - error = git_reference_lookup(&ref, repo, name); + error = git_reference_lookup(&ref, t->repo, name); if (error < GIT_SUCCESS) goto out; @@ -78,15 +48,17 @@ static int add_ref(const char *name, git_repository *repo, git_vector *vec) git_oid_cpy(&head->oid, git_reference_oid(ref)); - error = git_vector_insert(vec, head); + error = git_vector_insert(&t->refs, head); if (error < GIT_SUCCESS) goto out; + head = NULL; + /* If it's not a tag, we don't need to try to peel it */ if (git__prefixcmp(name, GIT_REFS_TAGS_DIR)) goto out; - error = git_object_lookup(&obj, repo, &head->oid, GIT_OBJ_ANY); + error = git_object_lookup(&obj, t->repo, &head->oid, GIT_OBJ_ANY); if (error < GIT_SUCCESS) { git__rethrow(error, "Failed to lookup object"); } @@ -100,13 +72,12 @@ static int add_ref(const char *name, git_repository *repo, git_vector *vec) peel_len = strlen(name) + strlen(peeled); head->name = git__malloc(peel_len + 1); ret = p_snprintf(head->name, peel_len + 1, "%s%s", name, peeled); - if (ret >= peel_len + 1) { - error = git__throw(GIT_ERROR, "The string is magically to long"); - } + + assert(ret < peel_len + 1); git_oid_cpy(&head->oid, git_tag_target_oid((git_tag *) obj)); - error = git_vector_insert(vec, head); + error = git_vector_insert(&t->refs, head); if (error < GIT_SUCCESS) goto out; @@ -115,70 +86,108 @@ static int add_ref(const char *name, git_repository *repo, git_vector *vec) git_reference_free(resolved_ref); git_object_free(obj); - if (error < GIT_SUCCESS) { + if (head && error < GIT_SUCCESS) { git__free(head->name); git__free(head); } + return error; } -static int local_ls(git_transport *transport, git_headarray *array) +static int store_refs(transport_local *t) { int error; unsigned int i; - git_repository *repo; - git_vector *vec; - git_strarray refs; - transport_local *t = (transport_local *) transport; + git_strarray ref_names = {0}; - assert(transport && transport->connected); - - repo = t->repo; + assert(t); - error = git_reference_listall(&refs, repo, GIT_REF_LISTALL); + error = git_vector_init(&t->refs, ref_names.count, NULL); if (error < GIT_SUCCESS) - return git__rethrow(error, "Failed to list remote heads"); - - vec = git__malloc(sizeof(git_vector)); - if (vec == NULL) { - error = GIT_ENOMEM; - goto out; - } + return error; - error = git_vector_init(vec, refs.count, NULL); + error = git_reference_listall(&ref_names, t->repo, GIT_REF_LISTALL); if (error < GIT_SUCCESS) - return error; + return git__rethrow(error, "Failed to list remote heads"); /* Sort the references first */ - git__tsort((void **)refs.strings, refs.count, &git__strcmp_cb); + git__tsort((void **)ref_names.strings, ref_names.count, &git__strcmp_cb); /* Add HEAD */ - error = add_ref(GIT_HEAD_FILE, repo, vec); + error = add_ref(t, GIT_HEAD_FILE); if (error < GIT_SUCCESS) - goto out; + goto cleanup; - for (i = 0; i < refs.count; ++i) { - error = add_ref(refs.strings[i], repo, vec); + for (i = 0; i < ref_names.count; ++i) { + error = add_ref(t, ref_names.strings[i]); if (error < GIT_SUCCESS) - goto out; + goto cleanup; } - array->len = vec->length; - array->heads = (git_remote_head **)vec->contents; +cleanup: + git_strarray_free(&ref_names); + return error; +} - t->refs = vec; +static int local_ls(git_transport *transport, git_headlist_cb list_cb, void *payload) +{ + transport_local *t = (transport_local *) transport; + git_vector *refs = &t->refs; + unsigned int i; + git_remote_head *h; - out: + assert(transport && transport->connected); - git_strarray_free(&refs); + git_vector_foreach(refs, i, h) { + if (list_cb(h, payload) < 0) + return git__throw(GIT_ERROR, + "The user callback returned an error code"); + } - return error; + return GIT_SUCCESS; +} + + +/* + * Try to open the url as a git directory. The direction doesn't + * matter in this case because we're calulating the heads ourselves. + */ +static int local_connect(git_transport *transport, int GIT_UNUSED(direction)) +{ + git_repository *repo; + int error; + transport_local *t = (transport_local *) transport; + const char *path; + const char file_prefix[] = "file://"; + GIT_UNUSED_ARG(direction); + + /* The repo layer doesn't want the prefix */ + if (!git__prefixcmp(transport->url, file_prefix)) + path = transport->url + strlen(file_prefix); + else + path = transport->url; + + error = git_repository_open(&repo, path); + if (error < GIT_SUCCESS) + return git__rethrow(error, "Failed to open remote"); + + error = store_refs(t); + if (error < GIT_SUCCESS) + return git__rethrow(error, "Failed to retrieve references"); + + t->repo = repo; + t->parent.connected = 1; + + return GIT_SUCCESS; } static int local_close(git_transport *GIT_UNUSED(transport)) { - /* Nothing to do */ - GIT_UNUSED_ARG(transport); + transport_local *t = (transport_local *)transport; + + git_repository_free(t->repo); + t->repo = NULL; + return GIT_SUCCESS; } @@ -186,21 +195,17 @@ static void local_free(git_transport *transport) { unsigned int i; transport_local *t = (transport_local *) transport; - git_vector *vec = t->refs; + git_vector *vec = &t->refs; git_remote_head *h; assert(transport); - if (t->refs != NULL) { - git_vector_foreach (vec, i, h) { - git__free(h->name); - git__free(h); - } - git_vector_free(vec); - git__free(vec); + git_vector_foreach (vec, i, h) { + git__free(h->name); + git__free(h); } + git_vector_free(vec); - git_repository_free(t->repo); git__free(t->parent.url); git__free(t); } |