Commit ec24e542 by Vicent Marti

What are the chances, really

parent 56960b83
......@@ -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);
/**
......
......@@ -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 */
......@@ -66,35 +85,9 @@ struct git_refdb_backend {
*/
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.
......
......@@ -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)
......
......@@ -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;
GIT_REFCOUNT_INC(db);
ref->db = db;
return error;
*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)
int git_refdb_iterator_next(git_reference **out, git_reference_iterator *iter)
{
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);
int error;
/* If the backend doesn't support glob-filtering themselves, we have to do it */
if (db->backend->iterator(out, db->backend) < 0)
return -1;
if ((error = iter->next(out, iter)) < 0)
return error;
(*out)->glob = git__strdup(glob);
if (!(*out)->glob) {
db->backend->iterator_free(*out);
return -1;
}
GIT_REFCOUNT_INC(iter->db);
(*out)->db = iter->db;
return 0;
}
int git_refdb_next(git_reference **out, git_reference_iterator *iter)
int git_refdb_iterator_next_name(const char **out, git_reference_iterator *iter)
{
int error;
if (!iter->glob) {
if ((error = iter->backend->next(out, iter)) < 0)
return error;
(*out)->db = iter->backend;
return 0;
}
/* 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;
}
git_reference_free(*out);
}
return error;
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);
}
......@@ -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
......@@ -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;
......
......@@ -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)
{
......
......@@ -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;
}
......
......@@ -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 {
......
#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);
}
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment