diff --git a/include/git2/refs.h b/include/git2/refs.h index 4d9ec8344..44b658d5b 100644 --- a/include/git2/refs.h +++ b/include/git2/refs.h @@ -308,7 +308,8 @@ GIT_EXTERN(int) git_reference_delete(git_reference *ref); */ GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo); -typedef int (*git_reference_foreach_cb)(const char *refname, void *payload); +typedef int (*git_reference_foreach_cb)(git_reference *reference, void *payload); +typedef int (*git_reference_foreach_name_cb)(const char *name, void *payload); /** * Perform a callback on each reference in the repository. @@ -328,6 +329,11 @@ GIT_EXTERN(int) git_reference_foreach( git_reference_foreach_cb callback, void *payload); +GIT_EXTERN(int) git_reference_foreach_name( + git_repository *repo, + git_reference_foreach_name_cb callback, + void *payload); + /** * Free the given reference. * @@ -378,6 +384,8 @@ GIT_EXTERN(int) git_reference_iterator_glob_new( */ GIT_EXTERN(int) git_reference_next(git_reference **out, git_reference_iterator *iter); +GIT_EXTERN(int) git_reference_next_name(const char **out, git_reference_iterator *iter); + /** * Free the iterator and its associated resources * @@ -406,7 +414,7 @@ GIT_EXTERN(void) git_reference_iterator_free(git_reference_iterator *iter); GIT_EXTERN(int) git_reference_foreach_glob( git_repository *repo, const char *glob, - git_reference_foreach_cb callback, + git_reference_foreach_name_cb callback, void *payload); /** diff --git a/include/git2/sys/refdb_backend.h b/include/git2/sys/refdb_backend.h index 0820cd9c5..a78d22658 100644 --- a/include/git2/sys/refdb_backend.h +++ b/include/git2/sys/refdb_backend.h @@ -33,8 +33,27 @@ GIT_BEGIN_DECL * and assign `iter->parent.backend` to your `git_refdb_backend`. */ struct git_reference_iterator { - git_refdb_backend *backend; - char *glob; + git_refdb *db; + + /** + * Return the current reference and advance the iterator. + */ + int (*next)( + git_reference **ref, + git_reference_iterator *iter); + + /** + * Return the name of the current reference and advance the iterator + */ + int (*next_name)( + const char **ref_name, + git_reference_iterator *iter); + + /** + * Free the iterator + */ + void (*free)( + git_reference_iterator *iter); }; /** An instance for a custom backend */ @@ -65,36 +84,10 @@ struct git_refdb_backend { * A refdb implementation must provide this function. */ int (*iterator)( - git_reference_iterator **iter, - struct git_refdb_backend *backend); - - /** - * Allocate a glob-filtering iterator object for the backend. - * - * A refdb implementation may provide this function. If it's - * not available, the glob matching will be done by the frontend. - */ - int (*iterator_glob)( git_reference_iterator **iter, struct git_refdb_backend *backend, const char *glob); - /** - * Return the current value and advance the iterator. - * - * A refdb implementation must provide this function. - */ - int (*next)( - git_reference **ref, - git_reference_iterator *iter); - - /** - * Free the iterator - * - * A refdb implementation must provide this function. - */ - void (*iterator_free)( - git_reference_iterator *iter); /* * Writes the given reference to the refdb. A refdb implementation * must provide this function. diff --git a/src/clone.c b/src/clone.c index 7ebdb5765..72906c3ce 100644 --- a/src/clone.c +++ b/src/clone.c @@ -241,7 +241,7 @@ static int update_head_to_remote(git_repository *repo, git_remote *remote) } /* Not master. Check all the other refs. */ - if (git_reference_foreach( + if (git_reference_foreach_name( repo, reference_matches_remote_head, &head_info) < 0) diff --git a/src/refdb.c b/src/refdb.c index 6cb879288..e0701d347 100644 --- a/src/refdb.c +++ b/src/refdb.c @@ -114,99 +114,65 @@ int git_refdb_lookup(git_reference **out, git_refdb *db, const char *ref_name) assert(db && db->backend && out && ref_name); - if (!(error = db->backend->lookup(&ref, db->backend, ref_name))) { - ref->db = db; - *out = ref; - } else { - *out = NULL; - } + error = db->backend->lookup(&ref, db->backend, ref_name); + if (error < 0) + return error; - return error; + GIT_REFCOUNT_INC(db); + ref->db = db; + + *out = ref; + return 0; } -int git_refdb_iterator(git_reference_iterator **out, git_refdb *db) +int git_refdb_iterator(git_reference_iterator **out, git_refdb *db, const char *glob) { if (!db->backend || !db->backend->iterator) { giterr_set(GITERR_REFERENCE, "This backend doesn't support iterators"); return -1; } - if (db->backend->iterator(out, db->backend) < 0) + if (db->backend->iterator(out, db->backend, glob) < 0) return -1; + GIT_REFCOUNT_INC(db); + (*out)->db = db; + return 0; } -int git_refdb_iterator_glob(git_reference_iterator **out, git_refdb *db, const char *glob) -{ - if (!db->backend) { - giterr_set(GITERR_REFERENCE, "There are no backends loaded"); - return -1; - } - - if (db->backend->iterator_glob) - return db->backend->iterator_glob(out, db->backend, glob); - - /* If the backend doesn't support glob-filtering themselves, we have to do it */ - if (db->backend->iterator(out, db->backend) < 0) - return -1; - - (*out)->glob = git__strdup(glob); - if (!(*out)->glob) { - db->backend->iterator_free(*out); - return -1; - } - - return 0; -} - -int git_refdb_next(git_reference **out, git_reference_iterator *iter) +int git_refdb_iterator_next(git_reference **out, git_reference_iterator *iter) { int error; - if (!iter->glob) { - if ((error = iter->backend->next(out, iter)) < 0) - return error; + if ((error = iter->next(out, iter)) < 0) + return error; - (*out)->db = iter->backend; - return 0; - } + GIT_REFCOUNT_INC(iter->db); + (*out)->db = iter->db; - /* If the iterator has a glob, we need to filter */ - while ((error = iter->backend->next(out, iter)) == 0) { - if (!p_fnmatch(iter->glob, (*out)->name, 0)) { - (*out)->db = iter->backend; - return 0; - } + return 0; +} - git_reference_free(*out); - } - - return error; +int git_refdb_iterator_next_name(const char **out, git_reference_iterator *iter) +{ + return iter->next_name(out, iter); } void git_refdb_iterator_free(git_reference_iterator *iter) { - git__free(iter->glob); - iter->backend->iterator_free(iter); + GIT_REFCOUNT_DEC(iter->db, refdb_free); + iter->free(iter); } -struct glob_cb_data { - const char *glob; - git_reference_foreach_cb callback; - void *payload; -}; - int git_refdb_write(git_refdb *db, const git_reference *ref) { assert(db && db->backend); - return db->backend->write(db->backend, ref); } int git_refdb_delete(struct git_refdb *db, const git_reference *ref) { assert(db && db->backend); - return db->backend->delete(db->backend, ref); } diff --git a/src/refdb.h b/src/refdb.h index 82522e191..1dcd70da8 100644 --- a/src/refdb.h +++ b/src/refdb.h @@ -26,13 +26,12 @@ int git_refdb_lookup( git_refdb *refdb, const char *ref_name); -int git_refdb_iterator(git_reference_iterator **out, git_refdb *db); -int git_refdb_iterator_glob(git_reference_iterator **out, git_refdb *db, const char *glob); -int git_refdb_next(git_reference **out, git_reference_iterator *iter); +int git_refdb_iterator(git_reference_iterator **out, git_refdb *db, const char *glob); +int git_refdb_iterator_next(git_reference **out, git_reference_iterator *iter); +int git_refdb_iterator_next_name(const char **out, git_reference_iterator *iter); void git_refdb_iterator_free(git_reference_iterator *iter); int git_refdb_write(git_refdb *refdb, const git_reference *ref); - int git_refdb_delete(git_refdb *refdb, const git_reference *ref); #endif diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 457964570..ecd033de0 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -556,34 +556,12 @@ static int refdb_fs_backend__lookup( typedef struct { git_reference_iterator parent; + char *glob; git_vector loose; unsigned int loose_pos; khiter_t packed_pos; } refdb_fs_iter; -static int iter_load_loose_paths(refdb_fs_iter *iter); - -static int refdb_fs_backend__iterator(git_reference_iterator **out, git_refdb_backend *_backend) -{ - refdb_fs_iter *iter; - refdb_fs_backend *backend; - - assert(_backend); - backend = (refdb_fs_backend *)_backend; - - if (packed_load(backend) < 0) - return -1; - - iter = git__calloc(1, sizeof(refdb_fs_iter)); - GITERR_CHECK_ALLOC(iter); - - iter->parent.backend = _backend; - iter_load_loose_paths(iter); - - *out = (git_reference_iterator *)iter; - return 0; -} - static void refdb_fs_backend__iterator_free(git_reference_iterator *_iter) { refdb_fs_iter *iter = (refdb_fs_iter *) _iter; @@ -595,14 +573,14 @@ static void refdb_fs_backend__iterator_free(git_reference_iterator *_iter) } git_vector_free(&iter->loose); + + git__free(iter->glob); git__free(iter); } -static int iter_load_loose_paths(refdb_fs_iter *iter) +static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter) { - refdb_fs_backend *backend = (refdb_fs_backend *) iter->parent.backend; git_strmap *packfile = backend->refcache.packfile; - git_buf path = GIT_BUF_INIT; git_iterator *fsit; const git_index_entry *entry = NULL; @@ -624,7 +602,8 @@ static int iter_load_loose_paths(refdb_fs_iter *iter) git_buf_puts(&path, entry->path); ref_name = git_buf_cstr(&path); - if (git__suffixcmp(ref_name, ".lock") == 0) { + if (git__suffixcmp(ref_name, ".lock") == 0 || + (iter->glob && p_fnmatch(iter->glob, ref_name, 0) != 0)) { git_iterator_advance(NULL, fsit); continue; } @@ -645,10 +624,11 @@ static int iter_load_loose_paths(refdb_fs_iter *iter) return 0; } -static int refdb_fs_backend__next(git_reference **out, git_reference_iterator *_iter) +static int refdb_fs_backend__iterator_next( + git_reference **out, git_reference_iterator *_iter) { refdb_fs_iter *iter = (refdb_fs_iter *)_iter; - refdb_fs_backend *backend = (refdb_fs_backend *)iter->parent.backend; + refdb_fs_backend *backend = (refdb_fs_backend *)iter->parent.db->backend; git_strmap *packfile = backend->refcache.packfile; while (iter->loose_pos < iter->loose.length) { @@ -660,19 +640,23 @@ static int refdb_fs_backend__next(git_reference **out, git_reference_iterator *_ giterr_clear(); } - if (iter->packed_pos < kh_end(packfile)) { + while (iter->packed_pos < kh_end(packfile)) { struct packref *ref = NULL; - do { - while (!kh_exist(packfile, iter->packed_pos)) { - iter->packed_pos++; - if (iter->packed_pos == kh_end(packfile)) - return GIT_ITEROVER; - } - - ref = kh_val(packfile, iter->packed_pos); + while (!kh_exist(packfile, iter->packed_pos)) { iter->packed_pos++; - } while (ref->flags & PACKREF_SHADOWED); + if (iter->packed_pos == kh_end(packfile)) + return GIT_ITEROVER; + } + + ref = kh_val(packfile, iter->packed_pos); + iter->packed_pos++; + + if (ref->flags & PACKREF_SHADOWED) + continue; + + if (iter->glob && p_fnmatch(iter->glob, ref->name, 0) != 0) + continue; *out = git_reference__alloc(ref->name, &ref->oid, &ref->peel); if (*out == NULL) @@ -684,6 +668,74 @@ static int refdb_fs_backend__next(git_reference **out, git_reference_iterator *_ return GIT_ITEROVER; } +static int refdb_fs_backend__iterator_next_name( + const char **out, git_reference_iterator *_iter) +{ + refdb_fs_iter *iter = (refdb_fs_iter *)_iter; + refdb_fs_backend *backend = (refdb_fs_backend *)iter->parent.db->backend; + git_strmap *packfile = backend->refcache.packfile; + + while (iter->loose_pos < iter->loose.length) { + const char *path = git_vector_get(&iter->loose, iter->loose_pos++); + + if (git_strmap_exists(packfile, path)) + continue; + + *out = path; + return 0; + } + + while (iter->packed_pos < kh_end(packfile)) { + while (!kh_exist(packfile, iter->packed_pos)) { + iter->packed_pos++; + if (iter->packed_pos == kh_end(packfile)) + return GIT_ITEROVER; + } + + *out = kh_key(packfile, iter->packed_pos); + iter->packed_pos++; + + if (iter->glob && p_fnmatch(iter->glob, *out, 0) != 0) + continue; + + return 0; + } + + return GIT_ITEROVER; +} + +static int refdb_fs_backend__iterator( + git_reference_iterator **out, git_refdb_backend *_backend, const char *glob) +{ + refdb_fs_iter *iter; + refdb_fs_backend *backend; + + assert(_backend); + backend = (refdb_fs_backend *)_backend; + + if (packed_load(backend) < 0) + return -1; + + iter = git__calloc(1, sizeof(refdb_fs_iter)); + GITERR_CHECK_ALLOC(iter); + + if (glob != NULL) + iter->glob = git__strdup(glob); + + iter->parent.next = refdb_fs_backend__iterator_next; + iter->parent.next_name = refdb_fs_backend__iterator_next_name; + iter->parent.free = refdb_fs_backend__iterator_free; + + if (iter_load_loose_paths(backend, iter) < 0) { + refdb_fs_backend__iterator_free((git_reference_iterator *)iter); + return -1; + } + + *out = (git_reference_iterator *)iter; + return 0; +} + + static int loose_write(refdb_fs_backend *backend, const git_reference *ref) { git_filebuf file = GIT_FILEBUF_INIT; @@ -1118,8 +1170,6 @@ int git_refdb_backend_fs( backend->parent.exists = &refdb_fs_backend__exists; backend->parent.lookup = &refdb_fs_backend__lookup; backend->parent.iterator = &refdb_fs_backend__iterator; - backend->parent.next = &refdb_fs_backend__next; - backend->parent.iterator_free = &refdb_fs_backend__iterator_free; backend->parent.write = &refdb_fs_backend__write; backend->parent.delete = &refdb_fs_backend__delete; backend->parent.compress = &refdb_fs_backend__compress; diff --git a/src/refs.c b/src/refs.c index 43231b0cf..a8583de19 100644 --- a/src/refs.c +++ b/src/refs.c @@ -104,20 +104,20 @@ struct reference_available_t { int available; }; -static int _reference_available_cb(const char *ref, void *data) +static int _reference_available_cb(const char *refname, void *data) { struct reference_available_t *d; - assert(ref && data); + assert(refname && data); d = (struct reference_available_t *)data; - if (!d->old_ref || strcmp(d->old_ref, ref)) { - size_t reflen = strlen(ref); + if (!d->old_ref || strcmp(d->old_ref, refname)) { + size_t reflen = strlen(refname); size_t newlen = strlen(d->new_ref); size_t cmplen = reflen < newlen ? reflen : newlen; - const char *lead = reflen < newlen ? d->new_ref : ref; + const char *lead = reflen < newlen ? d->new_ref : refname; - if (!strncmp(d->new_ref, ref, cmplen) && lead[cmplen] == '/') { + if (!strncmp(d->new_ref, refname, cmplen) && lead[cmplen] == '/') { d->available = 0; return -1; } @@ -126,6 +126,9 @@ static int _reference_available_cb(const char *ref, void *data) return 0; } +/** + * TODO: this should be part of the FS backend + */ static int reference_path_available( git_repository *repo, const char *ref, @@ -138,8 +141,7 @@ static int reference_path_available( data.old_ref = old_ref; data.available = 1; - error = git_reference_foreach( - repo, _reference_available_cb, (void *)&data); + error = git_reference_foreach_name(repo, _reference_available_cb, (void *)&data); if (error < 0) return error; @@ -430,6 +432,7 @@ static int reference__create( ref = git_reference__alloc_symbolic(name, symbolic); } + /* TODO: this needs to be written more explicitly */ GITERR_CHECK_ALLOC(ref); ref->db = refdb; @@ -558,6 +561,7 @@ int git_reference_rename( if (result == NULL) return -1; + /* TODO: this is bad */ result->db = ref->db; /* Check if we have to update HEAD. */ @@ -623,14 +627,69 @@ int git_reference_foreach( void *payload) { git_reference_iterator *iter; - const char *name; + git_reference *ref; int error; if (git_reference_iterator_new(&iter, repo) < 0) return -1; - while ((error = git_reference_next(&name, iter)) == 0) { - if (callback(name, payload)) { + while ((error = git_reference_next(&ref, iter)) == 0) { + if (callback(ref, payload)) { + error = GIT_EUSER; + goto out; + } + } + + if (error == GIT_ITEROVER) + error = 0; + +out: + git_reference_iterator_free(iter); + return error; +} + +int git_reference_foreach_name( + git_repository *repo, + git_reference_foreach_name_cb callback, + void *payload) +{ + git_reference_iterator *iter; + const char *refname; + int error; + + if (git_reference_iterator_new(&iter, repo) < 0) + return -1; + + while ((error = git_reference_next_name(&refname, iter)) == 0) { + if (callback(refname, payload)) { + error = GIT_EUSER; + goto out; + } + } + + if (error == GIT_ITEROVER) + error = 0; + +out: + git_reference_iterator_free(iter); + return error; +} + +int git_reference_foreach_glob( + git_repository *repo, + const char *glob, + git_reference_foreach_name_cb callback, + void *payload) +{ + git_reference_iterator *iter; + const char *refname; + int error; + + if (git_reference_iterator_glob_new(&iter, repo, glob) < 0) + return -1; + + while ((error = git_reference_next_name(&refname, iter)) == 0) { + if (callback(refname, payload)) { error = GIT_EUSER; goto out; } @@ -651,22 +710,28 @@ int git_reference_iterator_new(git_reference_iterator **out, git_repository *rep if (git_repository_refdb__weakptr(&refdb, repo) < 0) return -1; - return git_refdb_iterator(out, refdb); + return git_refdb_iterator(out, refdb, NULL); } -int git_reference_iterator_glob_new(git_reference_iterator **out, git_repository *repo, const char *glob) +int git_reference_iterator_glob_new( + git_reference_iterator **out, git_repository *repo, const char *glob) { git_refdb *refdb; if (git_repository_refdb__weakptr(&refdb, repo) < 0) return -1; - return git_refdb_iterator_glob(out, refdb, glob); + return git_refdb_iterator(out, refdb, glob); } int git_reference_next(git_reference **out, git_reference_iterator *iter) { - return git_refdb_next(out, iter); + return git_refdb_iterator_next(out, iter); +} + +int git_reference_next_name(const char **out, git_reference_iterator *iter) +{ + return git_refdb_iterator_next_name(out, iter); } void git_reference_iterator_free(git_reference_iterator *iter) @@ -693,7 +758,7 @@ int git_reference_list( if (git_vector_init(&ref_list, 8, NULL) < 0) return -1; - if (git_reference_foreach( + if (git_reference_foreach_name( repo, &cb__reflist_add, (void *)&ref_list) < 0) { git_vector_free(&ref_list); return -1; @@ -991,34 +1056,6 @@ int git_reference__update_terminal( return reference__update_terminal(repo, ref_name, oid, 0); } -int git_reference_foreach_glob( - git_repository *repo, - const char *glob, - git_reference_foreach_cb callback, - void *payload) -{ - git_reference_iterator *iter; - const char *name; - int error; - - if (git_reference_iterator_glob_new(&iter, repo, glob) < 0) - return -1; - - while ((error = git_reference_next(&name, iter)) == 0) { - if (callback(name, payload)) { - error = GIT_EUSER; - goto out; - } - } - - if (error == GIT_ITEROVER) - error = 0; - -out: - git_reference_iterator_free(iter); - return error; -} - int git_reference_has_log( git_reference *ref) { diff --git a/src/repository.c b/src/repository.c index 28505e822..2e7a334c9 100644 --- a/src/repository.c +++ b/src/repository.c @@ -1473,12 +1473,14 @@ static int at_least_one_cb(const char *refname, void *payload) static int repo_contains_no_reference(git_repository *repo) { - int error = git_reference_foreach(repo, at_least_one_cb, NULL); + int error = git_reference_foreach_name(repo, &at_least_one_cb, NULL); if (error == GIT_EUSER) return 0; + if (!error) return 1; + return error; } diff --git a/src/tag.c b/src/tag.c index ecf3876cb..71f4c1eb1 100644 --- a/src/tag.c +++ b/src/tag.c @@ -440,7 +440,7 @@ int git_tag_foreach(git_repository *repo, git_tag_foreach_cb cb, void *cb_data) data.cb_data = cb_data; data.repo = repo; - return git_reference_foreach(repo, &tags_cb, &data); + return git_reference_foreach_name(repo, &tags_cb, &data); } typedef struct { diff --git a/tests-clar/refdb/inmemory.c b/tests-clar/refdb/inmemory.c deleted file mode 100644 index d2594cd6d..000000000 --- a/tests-clar/refdb/inmemory.c +++ /dev/null @@ -1,217 +0,0 @@ -#include "clar_libgit2.h" - -#include "buffer.h" -#include "posix.h" -#include "path.h" -#include "refs.h" - -#include "testdb.h" - -#define TEST_REPO_PATH "testrepo" - -static git_repository *repo; - -int unlink_ref(void *payload, git_buf *file) -{ - GIT_UNUSED(payload); - return p_unlink(git_buf_cstr(file)); -} - -int empty(void *payload, git_buf *file) -{ - GIT_UNUSED(payload); - GIT_UNUSED(file); - return -1; -} - -int ref_file_foreach(git_repository *repo, int (* cb)(void *payload, git_buf *filename)) -{ - const char *repo_path; - git_buf repo_refs_dir = GIT_BUF_INIT; - int error = 0; - - repo_path = git_repository_path(repo); - - git_buf_joinpath(&repo_refs_dir, repo_path, "HEAD"); - if (git_path_exists(git_buf_cstr(&repo_refs_dir)) && - cb(NULL, &repo_refs_dir) < 0) - return -1; - - git_buf_joinpath(&repo_refs_dir, repo_path, "refs"); - git_buf_joinpath(&repo_refs_dir, git_buf_cstr(&repo_refs_dir), "heads"); - if (git_path_direach(&repo_refs_dir, cb, NULL) != 0) - return -1; - - git_buf_joinpath(&repo_refs_dir, repo_path, "packed-refs"); - if (git_path_exists(git_buf_cstr(&repo_refs_dir)) && - cb(NULL, &repo_refs_dir) < 0) - return -1; - - git_buf_free(&repo_refs_dir); - - return error; -} - -void test_refdb_inmemory__initialize(void) -{ - git_buf repo_refs_dir = GIT_BUF_INIT; - git_refdb *refdb; - git_refdb_backend *refdb_backend; - - repo = cl_git_sandbox_init(TEST_REPO_PATH); - - cl_git_pass(git_repository_refdb(&refdb, repo)); - cl_git_pass(refdb_backend_test(&refdb_backend, repo)); - cl_git_pass(git_refdb_set_backend(refdb, refdb_backend)); - - ref_file_foreach(repo, unlink_ref); - - git_buf_free(&repo_refs_dir); - git_refdb_free(refdb); -} - -void test_refdb_inmemory__cleanup(void) -{ - cl_git_sandbox_cleanup(); -} - -void test_refdb_inmemory__doesnt_write_ref_file(void) -{ - git_reference *ref; - git_oid oid; - - cl_git_pass(git_oid_fromstr(&oid, "c47800c7266a2be04c571c04d5a6614691ea99bd")); - cl_git_pass(git_reference_create(&ref, repo, GIT_REFS_HEADS_DIR "test1", &oid, 0)); - - ref_file_foreach(repo, empty); - - git_reference_free(ref); -} - -void test_refdb_inmemory__read(void) -{ - git_reference *write1, *write2, *write3, *read1, *read2, *read3; - git_oid oid1, oid2, oid3; - - cl_git_pass(git_oid_fromstr(&oid1, "c47800c7266a2be04c571c04d5a6614691ea99bd")); - cl_git_pass(git_reference_create(&write1, repo, GIT_REFS_HEADS_DIR "test1", &oid1, 0)); - - cl_git_pass(git_oid_fromstr(&oid2, "e90810b8df3e80c413d903f631643c716887138d")); - cl_git_pass(git_reference_create(&write2, repo, GIT_REFS_HEADS_DIR "test2", &oid2, 0)); - - cl_git_pass(git_oid_fromstr(&oid3, "763d71aadf09a7951596c9746c024e7eece7c7af")); - cl_git_pass(git_reference_create(&write3, repo, GIT_REFS_HEADS_DIR "test3", &oid3, 0)); - - - cl_git_pass(git_reference_lookup(&read1, repo, GIT_REFS_HEADS_DIR "test1")); - cl_assert(strcmp(git_reference_name(read1), git_reference_name(write1)) == 0); - cl_assert(git_oid_cmp(git_reference_target(read1), git_reference_target(write1)) == 0); - - cl_git_pass(git_reference_lookup(&read2, repo, GIT_REFS_HEADS_DIR "test2")); - cl_assert(strcmp(git_reference_name(read2), git_reference_name(write2)) == 0); - cl_assert(git_oid_cmp(git_reference_target(read2), git_reference_target(write2)) == 0); - - cl_git_pass(git_reference_lookup(&read3, repo, GIT_REFS_HEADS_DIR "test3")); - cl_assert(strcmp(git_reference_name(read3), git_reference_name(write3)) == 0); - cl_assert(git_oid_cmp(git_reference_target(read3), git_reference_target(write3)) == 0); - - git_reference_free(write1); - git_reference_free(write2); - git_reference_free(write3); - - git_reference_free(read1); - git_reference_free(read2); - git_reference_free(read3); -} - -int foreach_test(const char *ref_name, void *payload) -{ - git_reference *ref; - git_oid expected; - size_t *i = payload; - - cl_git_pass(git_reference_lookup(&ref, repo, ref_name)); - - if (*i == 0) - cl_git_pass(git_oid_fromstr(&expected, "c47800c7266a2be04c571c04d5a6614691ea99bd")); - else if (*i == 1) - cl_git_pass(git_oid_fromstr(&expected, "e90810b8df3e80c413d903f631643c716887138d")); - else if (*i == 2) - cl_git_pass(git_oid_fromstr(&expected, "763d71aadf09a7951596c9746c024e7eece7c7af")); - - cl_assert(git_oid_cmp(&expected, git_reference_target(ref)) == 0); - - ++(*i); - - git_reference_free(ref); - - return 0; -} - -void test_refdb_inmemory__foreach(void) -{ - git_reference *write1, *write2, *write3; - git_oid oid1, oid2, oid3; - size_t i = 0; - - cl_git_pass(git_oid_fromstr(&oid1, "c47800c7266a2be04c571c04d5a6614691ea99bd")); - cl_git_pass(git_reference_create(&write1, repo, GIT_REFS_HEADS_DIR "test1", &oid1, 0)); - - cl_git_pass(git_oid_fromstr(&oid2, "e90810b8df3e80c413d903f631643c716887138d")); - cl_git_pass(git_reference_create(&write2, repo, GIT_REFS_HEADS_DIR "test2", &oid2, 0)); - - cl_git_pass(git_oid_fromstr(&oid3, "763d71aadf09a7951596c9746c024e7eece7c7af")); - cl_git_pass(git_reference_create(&write3, repo, GIT_REFS_HEADS_DIR "test3", &oid3, 0)); - - cl_git_pass(git_reference_foreach(repo,foreach_test, &i)); - cl_assert_equal_i(3, (int)i); - - git_reference_free(write1); - git_reference_free(write2); - git_reference_free(write3); -} - -int delete_test(const char *ref_name, void *payload) -{ - git_reference *ref; - git_oid expected; - size_t *i = payload; - - cl_git_pass(git_reference_lookup(&ref, repo, ref_name)); - - cl_git_pass(git_oid_fromstr(&expected, "e90810b8df3e80c413d903f631643c716887138d")); - cl_assert(git_oid_cmp(&expected, git_reference_target(ref)) == 0); - - ++(*i); - - git_reference_free(ref); - - return 0; -} - -void test_refdb_inmemory__delete(void) -{ - git_reference *write1, *write2, *write3; - git_oid oid1, oid2, oid3; - size_t i = 0; - - cl_git_pass(git_oid_fromstr(&oid1, "c47800c7266a2be04c571c04d5a6614691ea99bd")); - cl_git_pass(git_reference_create(&write1, repo, GIT_REFS_HEADS_DIR "test1", &oid1, 0)); - - cl_git_pass(git_oid_fromstr(&oid2, "e90810b8df3e80c413d903f631643c716887138d")); - cl_git_pass(git_reference_create(&write2, repo, GIT_REFS_HEADS_DIR "test2", &oid2, 0)); - - cl_git_pass(git_oid_fromstr(&oid3, "763d71aadf09a7951596c9746c024e7eece7c7af")); - cl_git_pass(git_reference_create(&write3, repo, GIT_REFS_HEADS_DIR "test3", &oid3, 0)); - - git_reference_delete(write1); - git_reference_free(write1); - - git_reference_delete(write3); - git_reference_free(write3); - - cl_git_pass(git_reference_foreach(repo, delete_test, &i)); - cl_assert_equal_i(1, (int)i); - - git_reference_free(write2); -} diff --git a/tests-clar/refdb/testdb.c b/tests-clar/refdb/testdb.c index c89bcce9f..6509ae9a2 100644 --- a/tests-clar/refdb/testdb.c +++ b/tests-clar/refdb/testdb.c @@ -112,55 +112,6 @@ static int refdb_test_backend__lookup( return GIT_ENOTFOUND; } -typedef struct { - git_reference_iterator parent; - size_t i; -} refdb_test_iter; - -static int refdb_test_backend__iterator(git_reference_iterator **out, git_refdb_backend *_backend) -{ - refdb_test_iter *iter; - - GIT_UNUSED(_backend); - - iter = git__calloc(1, sizeof(refdb_test_iter)); - GITERR_CHECK_ALLOC(iter); - - iter->parent.backend = _backend; - iter->i = 0; - - *out = (git_reference_iterator *) iter; - - return 0; -} - -static int refdb_test_backend__next(git_reference **out, git_reference_iterator *_iter) -{ - refdb_test_entry *entry; - refdb_test_backend *backend = (refdb_test_backend *) _iter->backend; - refdb_test_iter *iter = (refdb_test_iter *) _iter; - - entry = git_vector_get(&backend->refs, iter->i); - if (!entry) - return GIT_ITEROVER; - - if (entry->type == GIT_REF_OID) { - *out = git_reference__alloc(entry->name, &entry->target.oid, NULL); - } else if (entry->type == GIT_REF_SYMBOLIC) { - *out = git_reference__alloc_symbolic(entry->name, entry->target.symbolic); - } else { - return -1; - } - - iter->i++; - return 0; -} - -static void refdb_test_backend__iterator_free(git_reference_iterator *iter) -{ - git__free(iter); -} - static void refdb_test_entry_free(refdb_test_entry *entry) { if (entry->type == GIT_REF_SYMBOLIC) @@ -222,9 +173,6 @@ int refdb_backend_test( backend->parent.exists = &refdb_test_backend__exists; backend->parent.lookup = &refdb_test_backend__lookup; - backend->parent.iterator = &refdb_test_backend__iterator; - backend->parent.next = &refdb_test_backend__next; - backend->parent.iterator_free = &refdb_test_backend__iterator_free; backend->parent.write = &refdb_test_backend__write; backend->parent.delete = &refdb_test_backend__delete; backend->parent.free = &refdb_test_backend__free;