mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-08 19:51:31 +00:00
What are the chances, really
This commit is contained in:
parent
56960b8396
commit
ec24e54296
@ -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 */
|
||||
@ -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.
|
||||
|
@ -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)
|
||||
|
80
src/refdb.c
80
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;
|
||||
|
||||
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)
|
||||
if ((error = iter->next(out, iter)) < 0)
|
||||
return error;
|
||||
|
||||
(*out)->db = iter->backend;
|
||||
GIT_REFCOUNT_INC(iter->db);
|
||||
(*out)->db = iter->db;
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
118
src/refdb_fs.c
118
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,10 +640,9 @@ 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))
|
||||
@ -672,7 +651,12 @@ static int refdb_fs_backend__next(git_reference **out, git_reference_iterator *_
|
||||
|
||||
ref = kh_val(packfile, iter->packed_pos);
|
||||
iter->packed_pos++;
|
||||
} while (ref->flags & PACKREF_SHADOWED);
|
||||
|
||||
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;
|
||||
|
125
src/refs.c
125
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)
|
||||
{
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user