mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-02 12:29:08 +00:00

Nobody should ever be using anything other than ALL at this level, so remove the option altogether. As part of this, git_reference_foreach_glob is now implemented in the frontend using an iterator. Backends will later regain the ability of doing the glob filtering in the backend.
229 lines
4.8 KiB
C
229 lines
4.8 KiB
C
#include "vector.h"
|
|
#include "util.h"
|
|
#include "testdb.h"
|
|
|
|
typedef struct refdb_test_backend {
|
|
git_refdb_backend parent;
|
|
|
|
git_repository *repo;
|
|
git_vector refs;
|
|
} refdb_test_backend;
|
|
|
|
typedef struct refdb_test_entry {
|
|
char *name;
|
|
git_ref_t type;
|
|
|
|
union {
|
|
git_oid oid;
|
|
char *symbolic;
|
|
} target;
|
|
} refdb_test_entry;
|
|
|
|
static int ref_name_cmp(const void *a, const void *b)
|
|
{
|
|
return strcmp(git_reference_name((git_reference *)a),
|
|
git_reference_name((git_reference *)b));
|
|
}
|
|
|
|
static int refdb_test_backend__exists(
|
|
int *exists,
|
|
git_refdb_backend *_backend,
|
|
const char *ref_name)
|
|
{
|
|
refdb_test_backend *backend;
|
|
refdb_test_entry *entry;
|
|
size_t i;
|
|
|
|
assert(_backend);
|
|
backend = (refdb_test_backend *)_backend;
|
|
|
|
*exists = 0;
|
|
|
|
git_vector_foreach(&backend->refs, i, entry) {
|
|
if (strcmp(entry->name, ref_name) == 0) {
|
|
*exists = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int refdb_test_backend__write(
|
|
git_refdb_backend *_backend,
|
|
const git_reference *ref)
|
|
{
|
|
refdb_test_backend *backend;
|
|
refdb_test_entry *entry;
|
|
|
|
assert(_backend);
|
|
backend = (refdb_test_backend *)_backend;
|
|
|
|
entry = git__calloc(1, sizeof(refdb_test_entry));
|
|
GITERR_CHECK_ALLOC(entry);
|
|
|
|
entry->name = git__strdup(git_reference_name(ref));
|
|
GITERR_CHECK_ALLOC(entry->name);
|
|
|
|
entry->type = git_reference_type(ref);
|
|
|
|
if (entry->type == GIT_REF_OID)
|
|
git_oid_cpy(&entry->target.oid, git_reference_target(ref));
|
|
else {
|
|
entry->target.symbolic = git__strdup(git_reference_symbolic_target(ref));
|
|
GITERR_CHECK_ALLOC(entry->target.symbolic);
|
|
}
|
|
|
|
git_vector_insert(&backend->refs, entry);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int refdb_test_backend__lookup(
|
|
git_reference **out,
|
|
git_refdb_backend *_backend,
|
|
const char *ref_name)
|
|
{
|
|
refdb_test_backend *backend;
|
|
refdb_test_entry *entry;
|
|
size_t i;
|
|
|
|
assert(_backend);
|
|
backend = (refdb_test_backend *)_backend;
|
|
|
|
git_vector_foreach(&backend->refs, i, entry) {
|
|
if (strcmp(entry->name, ref_name) == 0) {
|
|
|
|
if (entry->type == GIT_REF_OID) {
|
|
*out = git_reference__alloc(ref_name,
|
|
&entry->target.oid, NULL);
|
|
} else if (entry->type == GIT_REF_SYMBOLIC) {
|
|
*out = git_reference__alloc_symbolic(ref_name,
|
|
entry->target.symbolic);
|
|
}
|
|
|
|
if (*out == NULL)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
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__malloc(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(const char **name, 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;
|
|
|
|
*name = entry->name;
|
|
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)
|
|
git__free(entry->target.symbolic);
|
|
|
|
git__free(entry->name);
|
|
git__free(entry);
|
|
}
|
|
|
|
static int refdb_test_backend__delete(
|
|
git_refdb_backend *_backend,
|
|
const git_reference *ref)
|
|
{
|
|
refdb_test_backend *backend;
|
|
refdb_test_entry *entry;
|
|
size_t i;
|
|
|
|
assert(_backend);
|
|
backend = (refdb_test_backend *)_backend;
|
|
|
|
git_vector_foreach(&backend->refs, i, entry) {
|
|
if (strcmp(entry->name, git_reference_name(ref)) == 0) {
|
|
git_vector_remove(&backend->refs, i);
|
|
refdb_test_entry_free(entry);
|
|
}
|
|
}
|
|
|
|
return GIT_ENOTFOUND;
|
|
}
|
|
|
|
static void refdb_test_backend__free(git_refdb_backend *_backend)
|
|
{
|
|
refdb_test_backend *backend;
|
|
refdb_test_entry *entry;
|
|
size_t i;
|
|
|
|
assert(_backend);
|
|
backend = (refdb_test_backend *)_backend;
|
|
|
|
git_vector_foreach(&backend->refs, i, entry)
|
|
refdb_test_entry_free(entry);
|
|
|
|
git_vector_free(&backend->refs);
|
|
git__free(backend);
|
|
}
|
|
|
|
int refdb_backend_test(
|
|
git_refdb_backend **backend_out,
|
|
git_repository *repo)
|
|
{
|
|
refdb_test_backend *backend;
|
|
|
|
backend = git__calloc(1, sizeof(refdb_test_backend));
|
|
GITERR_CHECK_ALLOC(backend);
|
|
|
|
git_vector_init(&backend->refs, 0, ref_name_cmp);
|
|
|
|
backend->repo = repo;
|
|
|
|
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;
|
|
|
|
*backend_out = (git_refdb_backend *)backend;
|
|
return 0;
|
|
}
|