mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-04 20:05:38 +00:00
Merge pull request #1385 from carlosmn/refs-iter
Introduce a refs iterator
This commit is contained in:
commit
b6cc559a78
@ -453,7 +453,7 @@ int main (int argc, char** argv)
|
||||
// Here we will implement something like `git for-each-ref` simply listing
|
||||
// out all available references and the object SHA they resolve to.
|
||||
git_strarray ref_list;
|
||||
git_reference_list(&ref_list, repo, GIT_REF_LISTALL);
|
||||
git_reference_list(&ref_list, repo);
|
||||
|
||||
const char *refname;
|
||||
git_reference *ref;
|
||||
|
@ -297,12 +297,6 @@ GIT_EXTERN(int) git_reference_delete(git_reference *ref);
|
||||
/**
|
||||
* Fill a list with all the references that can be found in a repository.
|
||||
*
|
||||
* Using the `list_flags` parameter, the listed references may be filtered
|
||||
* by type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of
|
||||
* `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`.
|
||||
* For convenience, use the value `GIT_REF_LISTALL` to obtain all
|
||||
* references, including packed ones.
|
||||
*
|
||||
* The string array will be filled with the names of all references; these
|
||||
* values are owned by the user and should be free'd manually when no
|
||||
* longer needed, using `git_strarray_free()`.
|
||||
@ -310,36 +304,27 @@ GIT_EXTERN(int) git_reference_delete(git_reference *ref);
|
||||
* @param array Pointer to a git_strarray structure where
|
||||
* the reference names will be stored
|
||||
* @param repo Repository where to find the refs
|
||||
* @param list_flags Filtering flags for the reference listing
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo, unsigned int list_flags);
|
||||
GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo);
|
||||
|
||||
typedef int (*git_reference_foreach_cb)(const char *refname, void *payload);
|
||||
|
||||
/**
|
||||
* Perform a callback on each reference in the repository.
|
||||
*
|
||||
* Using the `list_flags` parameter, the references may be filtered by
|
||||
* type (`GIT_REF_OID` or `GIT_REF_SYMBOLIC`) or using a bitwise OR of
|
||||
* `git_ref_t` values. To include packed refs, include `GIT_REF_PACKED`.
|
||||
* For convenience, use the value `GIT_REF_LISTALL` to obtain all
|
||||
* references, including packed ones.
|
||||
*
|
||||
* The `callback` function will be called for each reference in the
|
||||
* repository, receiving the name of the reference and the `payload` value
|
||||
* passed to this method. Returning a non-zero value from the callback
|
||||
* will terminate the iteration.
|
||||
*
|
||||
* @param repo Repository where to find the refs
|
||||
* @param list_flags Filtering flags for the reference listing.
|
||||
* @param callback Function which will be called for every listed ref
|
||||
* @param payload Additional data to pass to the callback
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_foreach(
|
||||
git_repository *repo,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload);
|
||||
|
||||
@ -359,6 +344,31 @@ GIT_EXTERN(void) git_reference_free(git_reference *ref);
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2);
|
||||
|
||||
/**
|
||||
* Create an iterator for the repo's references
|
||||
*
|
||||
* @param out pointer in which to store the iterator
|
||||
* @param repo the repository
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_iterator_new(git_reference_iterator **out, git_repository *repo);
|
||||
|
||||
/**
|
||||
* Get the next reference name
|
||||
*
|
||||
* @param out pointer in which to store the string
|
||||
* @param iter the iterator
|
||||
* @param 0, GIT_ITEROVER if there are no more; or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_next(const char **out, git_reference_iterator *iter);
|
||||
|
||||
/**
|
||||
* Free the iterator and its associated resources
|
||||
*
|
||||
* @param iter the iterator to free
|
||||
*/
|
||||
GIT_EXTERN(void) git_reference_iterator_free(git_reference_iterator *iter);
|
||||
|
||||
/**
|
||||
* Perform a callback on each reference in the repository whose name
|
||||
* matches the given pattern.
|
||||
@ -373,7 +383,6 @@ GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2);
|
||||
*
|
||||
* @param repo Repository where to find the refs
|
||||
* @param glob Pattern to match (fnmatch-style) against reference name.
|
||||
* @param list_flags Filtering flags for the reference listing.
|
||||
* @param callback Function which will be called for every listed ref
|
||||
* @param payload Additional data to pass to the callback
|
||||
* @return 0 on success, GIT_EUSER on non-zero callback, or error code
|
||||
@ -381,7 +390,6 @@ GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2);
|
||||
GIT_EXTERN(int) git_reference_foreach_glob(
|
||||
git_repository *repo,
|
||||
const char *glob,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload);
|
||||
|
||||
|
@ -20,6 +20,23 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
|
||||
/**
|
||||
* Every backend's iterator must have a pointer to itself as the first
|
||||
* element, so the API can talk to it. You'd define your iterator as
|
||||
*
|
||||
* struct my_iterator {
|
||||
* git_reference_iterator parent;
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* and assign `iter->parent.backend` to your `git_refdb_backend`.
|
||||
*/
|
||||
struct git_reference_iterator {
|
||||
git_refdb_backend *backend;
|
||||
char *glob;
|
||||
};
|
||||
|
||||
/** An instance for a custom backend */
|
||||
struct git_refdb_backend {
|
||||
unsigned int version;
|
||||
@ -43,29 +60,42 @@ struct git_refdb_backend {
|
||||
const char *ref_name);
|
||||
|
||||
/**
|
||||
* Enumerates each reference in the refdb. A refdb implementation must
|
||||
* provide this function.
|
||||
* Allocate an iterator object for the backend.
|
||||
*
|
||||
* A refdb implementation must provide this function.
|
||||
*/
|
||||
int (*foreach)(
|
||||
git_refdb_backend *backend,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload);
|
||||
int (*iterator)(
|
||||
git_reference_iterator **iter,
|
||||
struct git_refdb_backend *backend);
|
||||
|
||||
/**
|
||||
* Enumerates each reference in the refdb that matches the given
|
||||
* glob string. A refdb implementation may provide this function;
|
||||
* if it is not provided, foreach will be used and the results filtered
|
||||
* against the glob.
|
||||
* 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 (*foreach_glob)(
|
||||
git_refdb_backend *backend,
|
||||
const char *glob,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload);
|
||||
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)(
|
||||
const char **name,
|
||||
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.
|
||||
*/
|
||||
|
@ -165,6 +165,10 @@ typedef struct git_signature {
|
||||
/** In-memory representation of a reference. */
|
||||
typedef struct git_reference git_reference;
|
||||
|
||||
/** Iterator for references */
|
||||
typedef struct git_reference_iterator git_reference_iterator;
|
||||
|
||||
|
||||
/** Basic type of any Git reference. */
|
||||
typedef enum {
|
||||
GIT_REF_INVALID = 0, /** Invalid reference */
|
||||
|
57
src/branch.c
57
src/branch.c
@ -124,40 +124,43 @@ on_error:
|
||||
return error;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
git_branch_foreach_cb branch_cb;
|
||||
void *callback_payload;
|
||||
unsigned int branch_type;
|
||||
} branch_foreach_filter;
|
||||
|
||||
static int branch_foreach_cb(const char *branch_name, void *payload)
|
||||
{
|
||||
branch_foreach_filter *filter = (branch_foreach_filter *)payload;
|
||||
|
||||
if (filter->branch_type & GIT_BRANCH_LOCAL &&
|
||||
git__prefixcmp(branch_name, GIT_REFS_HEADS_DIR) == 0)
|
||||
return filter->branch_cb(branch_name + strlen(GIT_REFS_HEADS_DIR), GIT_BRANCH_LOCAL, filter->callback_payload);
|
||||
|
||||
if (filter->branch_type & GIT_BRANCH_REMOTE &&
|
||||
git__prefixcmp(branch_name, GIT_REFS_REMOTES_DIR) == 0)
|
||||
return filter->branch_cb(branch_name + strlen(GIT_REFS_REMOTES_DIR), GIT_BRANCH_REMOTE, filter->callback_payload);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_branch_foreach(
|
||||
git_repository *repo,
|
||||
unsigned int list_flags,
|
||||
git_branch_foreach_cb branch_cb,
|
||||
git_branch_foreach_cb callback,
|
||||
void *payload)
|
||||
{
|
||||
branch_foreach_filter filter;
|
||||
git_reference_iterator *iter;
|
||||
const char *name;
|
||||
int error;
|
||||
|
||||
filter.branch_cb = branch_cb;
|
||||
filter.branch_type = list_flags;
|
||||
filter.callback_payload = payload;
|
||||
if (git_reference_iterator_new(&iter, repo) < 0)
|
||||
return -1;
|
||||
|
||||
while ((error = git_reference_next(&name, iter)) == 0) {
|
||||
if (list_flags & GIT_BRANCH_LOCAL &&
|
||||
git__prefixcmp(name, GIT_REFS_HEADS_DIR) == 0) {
|
||||
if (callback(name + strlen(GIT_REFS_HEADS_DIR), GIT_BRANCH_LOCAL, payload)) {
|
||||
error = GIT_EUSER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (list_flags & GIT_BRANCH_REMOTE &&
|
||||
git__prefixcmp(name, GIT_REFS_REMOTES_DIR) == 0) {
|
||||
if (callback(name + strlen(GIT_REFS_REMOTES_DIR), GIT_BRANCH_REMOTE, payload)) {
|
||||
error = GIT_EUSER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error == GIT_ITEROVER)
|
||||
error = 0;
|
||||
|
||||
git_reference_iterator_free(iter);
|
||||
return error;
|
||||
|
||||
return git_reference_foreach(repo, GIT_REF_LISTALL, &branch_foreach_cb, (void *)&filter);
|
||||
}
|
||||
|
||||
int git_branch_move(
|
||||
|
@ -243,7 +243,6 @@ static int update_head_to_remote(git_repository *repo, git_remote *remote)
|
||||
/* Not master. Check all the other refs. */
|
||||
if (git_reference_foreach(
|
||||
repo,
|
||||
GIT_REF_LISTALL,
|
||||
reference_matches_remote_head,
|
||||
&head_info) < 0)
|
||||
goto cleanup;
|
||||
|
98
src/refdb.c
98
src/refdb.c
@ -124,15 +124,62 @@ int git_refdb_lookup(git_reference **out, git_refdb *db, const char *ref_name)
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_refdb_foreach(
|
||||
git_refdb *db,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload)
|
||||
int git_refdb_iterator(git_reference_iterator **out, git_refdb *db)
|
||||
{
|
||||
assert(db && db->backend);
|
||||
if (!db->backend || !db->backend->iterator) {
|
||||
giterr_set(GITERR_REFERENCE, "This backend doesn't support iterators");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return db->backend->foreach(db->backend, list_flags, callback, payload);
|
||||
if (db->backend->iterator(out, db->backend) < 0)
|
||||
return -1;
|
||||
|
||||
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(const char **out, git_reference_iterator *iter)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (!iter->glob)
|
||||
return iter->backend->next(out, iter);
|
||||
|
||||
/* If the iterator has a glob, we need to filter */
|
||||
while ((error = iter->backend->next(out, iter)) == 0) {
|
||||
if (!p_fnmatch(iter->glob, *out, 0))
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void git_refdb_iterator_free(git_reference_iterator *iter)
|
||||
{
|
||||
git__free(iter->glob);
|
||||
iter->backend->iterator_free(iter);
|
||||
}
|
||||
|
||||
struct glob_cb_data {
|
||||
@ -141,43 +188,6 @@ struct glob_cb_data {
|
||||
void *payload;
|
||||
};
|
||||
|
||||
static int fromglob_cb(const char *reference_name, void *payload)
|
||||
{
|
||||
struct glob_cb_data *data = (struct glob_cb_data *)payload;
|
||||
|
||||
if (!p_fnmatch(data->glob, reference_name, 0))
|
||||
return data->callback(reference_name, data->payload);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_refdb_foreach_glob(
|
||||
git_refdb *db,
|
||||
const char *glob,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload)
|
||||
{
|
||||
int error;
|
||||
struct glob_cb_data data;
|
||||
|
||||
assert(db && db->backend && glob && callback);
|
||||
|
||||
if(db->backend->foreach_glob != NULL)
|
||||
error = db->backend->foreach_glob(db->backend,
|
||||
glob, list_flags, callback, payload);
|
||||
else {
|
||||
data.glob = glob;
|
||||
data.callback = callback;
|
||||
data.payload = payload;
|
||||
|
||||
error = db->backend->foreach(db->backend,
|
||||
list_flags, fromglob_cb, &data);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_refdb_write(git_refdb *db, const git_reference *ref)
|
||||
{
|
||||
assert(db && db->backend);
|
||||
|
16
src/refdb.h
16
src/refdb.h
@ -26,18 +26,10 @@ int git_refdb_lookup(
|
||||
git_refdb *refdb,
|
||||
const char *ref_name);
|
||||
|
||||
int git_refdb_foreach(
|
||||
git_refdb *refdb,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload);
|
||||
|
||||
int git_refdb_foreach_glob(
|
||||
git_refdb *refdb,
|
||||
const char *glob,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload);
|
||||
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(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);
|
||||
|
||||
|
190
src/refdb_fs.c
190
src/refdb_fs.c
@ -13,6 +13,7 @@
|
||||
#include "reflog.h"
|
||||
#include "refdb.h"
|
||||
#include "refdb_fs.h"
|
||||
#include "iterator.h"
|
||||
|
||||
#include <git2/tag.h>
|
||||
#include <git2/object.h>
|
||||
@ -180,6 +181,9 @@ static int packed_load(refdb_fs_backend *backend)
|
||||
GITERR_CHECK_ALLOC(ref_cache->packfile);
|
||||
}
|
||||
|
||||
if (backend->path == NULL)
|
||||
return 0;
|
||||
|
||||
result = reference_read(&packfile, &ref_cache->packfile_time,
|
||||
backend->path, GIT_PACKEDREFS_FILE, &updated);
|
||||
|
||||
@ -558,65 +562,21 @@ struct dirent_list_data {
|
||||
int callback_error;
|
||||
};
|
||||
|
||||
static git_ref_t loose_guess_rtype(const git_buf *full_path)
|
||||
{
|
||||
git_buf ref_file = GIT_BUF_INIT;
|
||||
git_ref_t type;
|
||||
|
||||
type = GIT_REF_INVALID;
|
||||
|
||||
if (git_futils_readbuffer(&ref_file, full_path->ptr) == 0) {
|
||||
if (git__prefixcmp((const char *)(ref_file.ptr), GIT_SYMREF) == 0)
|
||||
type = GIT_REF_SYMBOLIC;
|
||||
else
|
||||
type = GIT_REF_OID;
|
||||
}
|
||||
|
||||
git_buf_free(&ref_file);
|
||||
return type;
|
||||
}
|
||||
|
||||
static int _dirent_loose_listall(void *_data, git_buf *full_path)
|
||||
{
|
||||
struct dirent_list_data *data = (struct dirent_list_data *)_data;
|
||||
const char *file_path = full_path->ptr + data->repo_path_len;
|
||||
|
||||
if (git_path_isdir(full_path->ptr) == true)
|
||||
return git_path_direach(full_path, _dirent_loose_listall, _data);
|
||||
|
||||
/* do not add twice a reference that exists already in the packfile */
|
||||
if (git_strmap_exists(data->backend->refcache.packfile, file_path))
|
||||
return 0;
|
||||
|
||||
if (data->list_type != GIT_REF_LISTALL) {
|
||||
if ((data->list_type & loose_guess_rtype(full_path)) == 0)
|
||||
return 0; /* we are filtering out this reference */
|
||||
}
|
||||
|
||||
/* Locked references aren't returned */
|
||||
if (!git__suffixcmp(file_path, GIT_FILELOCK_EXTENSION))
|
||||
return 0;
|
||||
|
||||
if (data->callback(file_path, data->callback_payload))
|
||||
data->callback_error = GIT_EUSER;
|
||||
|
||||
return data->callback_error;
|
||||
}
|
||||
|
||||
static int refdb_fs_backend__foreach(
|
||||
git_refdb_backend *_backend,
|
||||
unsigned int list_type,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload)
|
||||
typedef struct {
|
||||
git_reference_iterator parent;
|
||||
unsigned int loose;
|
||||
/* packed */
|
||||
git_strmap *h;
|
||||
khiter_t k;
|
||||
/* loose */
|
||||
git_iterator *fsiter;
|
||||
git_buf buf;
|
||||
} refdb_fs_iter;
|
||||
|
||||
static int refdb_fs_backend__iterator(git_reference_iterator **out, git_refdb_backend *_backend)
|
||||
{
|
||||
refdb_fs_iter *iter;
|
||||
refdb_fs_backend *backend;
|
||||
int result;
|
||||
struct dirent_list_data data;
|
||||
git_buf refs_path = GIT_BUF_INIT;
|
||||
const char *ref_name;
|
||||
void *ref = NULL;
|
||||
|
||||
GIT_UNUSED(ref);
|
||||
|
||||
assert(_backend);
|
||||
backend = (refdb_fs_backend *)_backend;
|
||||
@ -624,32 +584,104 @@ static int refdb_fs_backend__foreach(
|
||||
if (packed_load(backend) < 0)
|
||||
return -1;
|
||||
|
||||
/* list all the packed references first */
|
||||
if (list_type & GIT_REF_OID) {
|
||||
git_strmap_foreach(backend->refcache.packfile, ref_name, ref, {
|
||||
if (callback(ref_name, payload))
|
||||
return GIT_EUSER;
|
||||
});
|
||||
iter = git__calloc(1, sizeof(refdb_fs_iter));
|
||||
GITERR_CHECK_ALLOC(iter);
|
||||
|
||||
iter->parent.backend = _backend;
|
||||
iter->h = backend->refcache.packfile;
|
||||
iter->k = kh_begin(backend->refcache.packfile);
|
||||
|
||||
*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;
|
||||
|
||||
git_buf_free(&iter->buf);
|
||||
git_iterator_free(iter->fsiter);
|
||||
git__free(iter);
|
||||
}
|
||||
|
||||
static int iter_packed(const char **out, refdb_fs_iter *iter)
|
||||
{
|
||||
/* Move forward to the next entry */
|
||||
while (!kh_exist(iter->h, iter->k)) {
|
||||
iter->k++;
|
||||
if (iter->k == kh_end(iter->h))
|
||||
return GIT_ITEROVER;
|
||||
}
|
||||
|
||||
/* now list the loose references, trying not to
|
||||
* duplicate the ref names already in the packed-refs file */
|
||||
*out = kh_key(iter->h, iter->k);
|
||||
iter->k++;
|
||||
|
||||
data.repo_path_len = strlen(backend->path);
|
||||
data.list_type = list_type;
|
||||
data.backend = backend;
|
||||
data.callback = callback;
|
||||
data.callback_payload = payload;
|
||||
data.callback_error = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (git_buf_joinpath(&refs_path, backend->path, GIT_REFS_DIR) < 0)
|
||||
static int iter_loose(const char **out, refdb_fs_iter *iter)
|
||||
{
|
||||
const git_index_entry *entry;
|
||||
int retry;
|
||||
git_strmap *packfile_refs;
|
||||
refdb_fs_backend *backend = (refdb_fs_backend *) iter->parent.backend;
|
||||
|
||||
packfile_refs = backend->refcache.packfile;
|
||||
|
||||
do {
|
||||
khiter_t pos;
|
||||
if (git_iterator_current(&entry, iter->fsiter) < 0)
|
||||
return -1;
|
||||
|
||||
git_buf_clear(&iter->buf);
|
||||
if (!entry)
|
||||
return GIT_ITEROVER;
|
||||
|
||||
if (git_buf_printf(&iter->buf, "refs/%s", entry->path) < 0)
|
||||
return -1;
|
||||
|
||||
git_iterator_advance(NULL, iter->fsiter);
|
||||
|
||||
/* Skip this one if we already listed it in packed */
|
||||
pos = git_strmap_lookup_index(packfile_refs, git_buf_cstr(&iter->buf));
|
||||
retry = 0;
|
||||
if (git_strmap_valid_index(packfile_refs, pos) ||
|
||||
!git_reference_is_valid_name(git_buf_cstr(&iter->buf)))
|
||||
retry = 1;
|
||||
|
||||
*out = git_buf_cstr(&iter->buf);
|
||||
} while (retry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iter_loose_setup(refdb_fs_iter *iter)
|
||||
{
|
||||
refdb_fs_backend *backend = (refdb_fs_backend *) iter->parent.backend;
|
||||
|
||||
git_buf_clear(&iter->buf);
|
||||
if (git_buf_printf(&iter->buf, "%s/refs", backend->path) < 0)
|
||||
return -1;
|
||||
|
||||
result = git_path_direach(&refs_path, _dirent_loose_listall, &data);
|
||||
return git_iterator_for_filesystem(&iter->fsiter, git_buf_cstr(&iter->buf), 0, NULL, NULL);
|
||||
}
|
||||
|
||||
git_buf_free(&refs_path);
|
||||
static int refdb_fs_backend__next(const char **out, git_reference_iterator *_iter)
|
||||
{
|
||||
refdb_fs_iter *iter = (refdb_fs_iter *)_iter;
|
||||
|
||||
return data.callback_error ? GIT_EUSER : result;
|
||||
/* First round of checks to make sure where we are */
|
||||
if (!iter->loose && iter->k == kh_end(iter->h)) {
|
||||
if (iter_loose_setup(iter) < 0)
|
||||
return -1;
|
||||
iter->loose = 1;
|
||||
}
|
||||
|
||||
if (!iter->loose)
|
||||
return iter_packed(out, iter);
|
||||
else
|
||||
return iter_loose(out, iter);
|
||||
}
|
||||
|
||||
static int loose_write(refdb_fs_backend *backend, const git_reference *ref)
|
||||
@ -1027,6 +1059,10 @@ static int setup_namespace(git_buf *path, git_repository *repo)
|
||||
{
|
||||
char *parts, *start, *end;
|
||||
|
||||
/* Not all repositories have a path */
|
||||
if (repo->path_repository == NULL)
|
||||
return 0;
|
||||
|
||||
/* Load the path to the repo first */
|
||||
git_buf_puts(path, repo->path_repository);
|
||||
|
||||
@ -1081,7 +1117,9 @@ int git_refdb_backend_fs(
|
||||
|
||||
backend->parent.exists = &refdb_fs_backend__exists;
|
||||
backend->parent.lookup = &refdb_fs_backend__lookup;
|
||||
backend->parent.foreach = &refdb_fs_backend__foreach;
|
||||
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;
|
||||
|
86
src/refs.c
86
src/refs.c
@ -139,7 +139,7 @@ static int reference_path_available(
|
||||
data.available = 1;
|
||||
|
||||
error = git_reference_foreach(
|
||||
repo, GIT_REF_LISTALL, _reference_available_cb, (void *)&data);
|
||||
repo, _reference_available_cb, (void *)&data);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
@ -619,14 +619,59 @@ int git_reference_resolve(git_reference **ref_out, const git_reference *ref)
|
||||
|
||||
int git_reference_foreach(
|
||||
git_repository *repo,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload)
|
||||
{
|
||||
git_refdb *refdb;
|
||||
git_repository_refdb__weakptr(&refdb, repo);
|
||||
git_reference_iterator *iter;
|
||||
const char *name;
|
||||
int error;
|
||||
|
||||
return git_refdb_foreach(refdb, list_flags, callback, payload);
|
||||
if (git_reference_iterator_new(&iter, repo) < 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_iterator_new(git_reference_iterator **out, git_repository *repo)
|
||||
{
|
||||
git_refdb *refdb;
|
||||
|
||||
if (git_repository_refdb__weakptr(&refdb, repo) < 0)
|
||||
return -1;
|
||||
|
||||
return git_refdb_iterator(out, refdb);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int git_reference_next(const char **out, git_reference_iterator *iter)
|
||||
{
|
||||
return git_refdb_next(out, iter);
|
||||
}
|
||||
|
||||
void git_reference_iterator_free(git_reference_iterator *iter)
|
||||
{
|
||||
git_refdb_iterator_free(iter);
|
||||
}
|
||||
|
||||
static int cb__reflist_add(const char *ref, void *data)
|
||||
@ -636,8 +681,7 @@ static int cb__reflist_add(const char *ref, void *data)
|
||||
|
||||
int git_reference_list(
|
||||
git_strarray *array,
|
||||
git_repository *repo,
|
||||
unsigned int list_flags)
|
||||
git_repository *repo)
|
||||
{
|
||||
git_vector ref_list;
|
||||
|
||||
@ -650,7 +694,7 @@ int git_reference_list(
|
||||
return -1;
|
||||
|
||||
if (git_reference_foreach(
|
||||
repo, list_flags, &cb__reflist_add, (void *)&ref_list) < 0) {
|
||||
repo, &cb__reflist_add, (void *)&ref_list) < 0) {
|
||||
git_vector_free(&ref_list);
|
||||
return -1;
|
||||
}
|
||||
@ -950,19 +994,29 @@ int git_reference__update_terminal(
|
||||
int git_reference_foreach_glob(
|
||||
git_repository *repo,
|
||||
const char *glob,
|
||||
unsigned int list_flags,
|
||||
int (*callback)(
|
||||
const char *reference_name,
|
||||
void *payload),
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload)
|
||||
{
|
||||
git_refdb *refdb;
|
||||
git_reference_iterator *iter;
|
||||
const char *name;
|
||||
int error;
|
||||
|
||||
assert(repo && glob && callback);
|
||||
if (git_reference_iterator_glob_new(&iter, repo, glob) < 0)
|
||||
return -1;
|
||||
|
||||
git_repository_refdb__weakptr(&refdb, repo);
|
||||
while ((error = git_reference_next(&name, iter)) == 0) {
|
||||
if (callback(name, payload)) {
|
||||
error = GIT_EUSER;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
return git_refdb_foreach_glob(refdb, glob, list_flags, callback, payload);
|
||||
if (error == GIT_ITEROVER)
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
git_reference_iterator_free(iter);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_reference_has_log(
|
||||
|
33
src/remote.c
33
src/remote.c
@ -1251,14 +1251,6 @@ static int update_branch_remote_config_entry(
|
||||
update_config_entries_cb, &data);
|
||||
}
|
||||
|
||||
static int rename_cb(const char *ref, void *data)
|
||||
{
|
||||
if (git__prefixcmp(ref, GIT_REFS_REMOTES_DIR))
|
||||
return 0;
|
||||
|
||||
return git_vector_insert((git_vector *)data, git__strdup(ref));
|
||||
}
|
||||
|
||||
static int rename_one_remote_reference(
|
||||
git_repository *repo,
|
||||
const char *reference_name,
|
||||
@ -1298,16 +1290,29 @@ static int rename_remote_references(
|
||||
int error = -1;
|
||||
unsigned int i;
|
||||
char *name;
|
||||
const char *refname;
|
||||
git_reference_iterator *iter;
|
||||
|
||||
if (git_vector_init(&refnames, 8, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_reference_iterator_new(&iter, repo) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_reference_foreach(
|
||||
repo,
|
||||
GIT_REF_LISTALL,
|
||||
rename_cb,
|
||||
&refnames) < 0)
|
||||
goto cleanup;
|
||||
while ((error = git_reference_next(&refname, iter)) == 0) {
|
||||
if (git__prefixcmp(refname, GIT_REFS_REMOTES_DIR))
|
||||
continue;
|
||||
|
||||
if ((error = git_vector_insert(&refnames, git__strdup(refname))) < 0)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
git_reference_iterator_free(iter);
|
||||
if (error == GIT_ITEROVER)
|
||||
error = 0;
|
||||
else
|
||||
goto cleanup;
|
||||
|
||||
git_vector_foreach(&refnames, i, name) {
|
||||
if ((error = rename_one_remote_reference(repo, name, old_name, new_name)) < 0)
|
||||
|
@ -1473,7 +1473,7 @@ 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, GIT_REF_LISTALL, at_least_one_cb, NULL);
|
||||
int error = git_reference_foreach(repo, at_least_one_cb, NULL);
|
||||
|
||||
if (error == GIT_EUSER)
|
||||
return 0;
|
||||
|
@ -186,7 +186,7 @@ static int push_glob(git_revwalk *walk, const char *glob, int hide)
|
||||
data.hide = hide;
|
||||
|
||||
if (git_reference_foreach_glob(
|
||||
walk->repo, git_buf_cstr(&buf), GIT_REF_LISTALL, push_glob_cb, &data) < 0)
|
||||
walk->repo, git_buf_cstr(&buf), push_glob_cb, &data) < 0)
|
||||
goto on_error;
|
||||
|
||||
regfree(&preg);
|
||||
|
@ -427,7 +427,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, GIT_REF_OID, &tags_cb, &data);
|
||||
return git_reference_foreach(repo, &tags_cb, &data);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
@ -124,7 +124,7 @@ static int store_refs(transport_local *t)
|
||||
|
||||
assert(t);
|
||||
|
||||
if (git_reference_list(&ref_names, t->repo, GIT_REF_LISTALL) < 0 ||
|
||||
if (git_reference_list(&ref_names, t->repo) < 0 ||
|
||||
git_vector_init(&t->refs, ref_names.count, NULL) < 0)
|
||||
goto on_error;
|
||||
|
||||
|
@ -193,7 +193,7 @@ static int fetch_setup_walk(git_revwalk **out, git_repository *repo)
|
||||
unsigned int i;
|
||||
git_reference *ref;
|
||||
|
||||
if (git_reference_list(&refs, repo, GIT_REF_LISTALL) < 0)
|
||||
if (git_reference_list(&refs, repo) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_revwalk_new(&walk, repo) < 0)
|
||||
|
@ -34,7 +34,7 @@ void test_network_fetchlocal__complete(void)
|
||||
cl_git_pass(git_remote_download(origin, transfer_cb, &callcount));
|
||||
cl_git_pass(git_remote_update_tips(origin));
|
||||
|
||||
cl_git_pass(git_reference_list(&refnames, repo, GIT_REF_LISTALL));
|
||||
cl_git_pass(git_reference_list(&refnames, repo));
|
||||
cl_assert_equal_i(19, (int)refnames.count);
|
||||
cl_assert(callcount > 0);
|
||||
|
||||
@ -58,7 +58,7 @@ void test_network_fetchlocal__partial(void)
|
||||
const char *url;
|
||||
|
||||
cl_set_cleanup(&cleanup_sandbox, NULL);
|
||||
cl_git_pass(git_reference_list(&refnames, repo, GIT_REF_LISTALL));
|
||||
cl_git_pass(git_reference_list(&refnames, repo));
|
||||
cl_assert_equal_i(1, (int)refnames.count);
|
||||
|
||||
url = cl_git_fixture_url("testrepo.git");
|
||||
@ -69,7 +69,7 @@ void test_network_fetchlocal__partial(void)
|
||||
|
||||
git_strarray_free(&refnames);
|
||||
|
||||
cl_git_pass(git_reference_list(&refnames, repo, GIT_REF_LISTALL));
|
||||
cl_git_pass(git_reference_list(&refnames, repo));
|
||||
cl_assert_equal_i(20, (int)refnames.count); /* 18 remote + 1 local */
|
||||
cl_assert(callcount > 0);
|
||||
|
||||
|
@ -163,7 +163,7 @@ void test_refdb_inmemory__foreach(void)
|
||||
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, GIT_REF_LISTALL, foreach_test, &i));
|
||||
cl_git_pass(git_reference_foreach(repo,foreach_test, &i));
|
||||
cl_assert_equal_i(3, (int)i);
|
||||
|
||||
git_reference_free(write1);
|
||||
@ -210,7 +210,7 @@ void test_refdb_inmemory__delete(void)
|
||||
git_reference_delete(write3);
|
||||
git_reference_free(write3);
|
||||
|
||||
cl_git_pass(git_reference_foreach(repo, GIT_REF_LISTALL, delete_test, &i));
|
||||
cl_git_pass(git_reference_foreach(repo, delete_test, &i));
|
||||
cl_assert_equal_i(1, (int)i);
|
||||
|
||||
git_reference_free(write2);
|
||||
|
@ -112,33 +112,49 @@ static int refdb_test_backend__lookup(
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
static int refdb_test_backend__foreach(
|
||||
git_refdb_backend *_backend,
|
||||
unsigned int list_flags,
|
||||
git_reference_foreach_cb callback,
|
||||
void *payload)
|
||||
{
|
||||
refdb_test_backend *backend;
|
||||
refdb_test_entry *entry;
|
||||
typedef struct {
|
||||
git_reference_iterator parent;
|
||||
size_t i;
|
||||
} refdb_test_iter;
|
||||
|
||||
assert(_backend);
|
||||
backend = (refdb_test_backend *)_backend;
|
||||
static int refdb_test_backend__iterator(git_reference_iterator **out, git_refdb_backend *_backend)
|
||||
{
|
||||
refdb_test_iter *iter;
|
||||
|
||||
git_vector_foreach(&backend->refs, i, entry) {
|
||||
if (entry->type == GIT_REF_OID && (list_flags & GIT_REF_OID) == 0)
|
||||
continue;
|
||||
GIT_UNUSED(_backend);
|
||||
|
||||
if (entry->type == GIT_REF_SYMBOLIC && (list_flags & GIT_REF_SYMBOLIC) == 0)
|
||||
continue;
|
||||
iter = git__calloc(1, sizeof(refdb_test_iter));
|
||||
GITERR_CHECK_ALLOC(iter);
|
||||
|
||||
if (callback(entry->name, payload) != 0)
|
||||
return GIT_EUSER;
|
||||
}
|
||||
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)
|
||||
@ -200,7 +216,9 @@ int refdb_backend_test(
|
||||
|
||||
backend->parent.exists = &refdb_test_backend__exists;
|
||||
backend->parent.lookup = &refdb_test_backend__lookup;
|
||||
backend->parent.foreach = &refdb_test_backend__foreach;
|
||||
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;
|
||||
|
@ -37,11 +37,11 @@ static int count_cb(const char *reference_name, void *payload)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void assert_retrieval(const char *glob, unsigned int flags, int expected_count)
|
||||
static void assert_retrieval(const char *glob, int expected_count)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
cl_git_pass(git_reference_foreach_glob(repo, glob, flags, count_cb, &count));
|
||||
cl_git_pass(git_reference_foreach_glob(repo, glob, count_cb, &count));
|
||||
|
||||
cl_assert_equal_i(expected_count, count);
|
||||
}
|
||||
@ -49,17 +49,17 @@ static void assert_retrieval(const char *glob, unsigned int flags, int expected_
|
||||
void test_refs_foreachglob__retrieve_all_refs(void)
|
||||
{
|
||||
/* 12 heads (including one packed head) + 1 note + 2 remotes + 7 tags */
|
||||
assert_retrieval("*", GIT_REF_LISTALL, 22);
|
||||
assert_retrieval("*", 22);
|
||||
}
|
||||
|
||||
void test_refs_foreachglob__retrieve_remote_branches(void)
|
||||
{
|
||||
assert_retrieval("refs/remotes/*", GIT_REF_LISTALL, 2);
|
||||
assert_retrieval("refs/remotes/*", 2);
|
||||
}
|
||||
|
||||
void test_refs_foreachglob__retrieve_local_branches(void)
|
||||
{
|
||||
assert_retrieval("refs/heads/*", GIT_REF_LISTALL, 12);
|
||||
assert_retrieval("refs/heads/*", 12);
|
||||
}
|
||||
|
||||
void test_refs_foreachglob__retrieve_partially_named_references(void)
|
||||
@ -69,7 +69,7 @@ void test_refs_foreachglob__retrieve_partially_named_references(void)
|
||||
* refs/remotes/test/master, refs/tags/test
|
||||
*/
|
||||
|
||||
assert_retrieval("*test*", GIT_REF_LISTALL, 4);
|
||||
assert_retrieval("*test*", 4);
|
||||
}
|
||||
|
||||
|
||||
@ -89,7 +89,7 @@ void test_refs_foreachglob__can_cancel(void)
|
||||
int count = 0;
|
||||
|
||||
cl_assert_equal_i(GIT_EUSER, git_reference_foreach_glob(
|
||||
repo, "*", GIT_REF_LISTALL, interrupt_cb, &count) );
|
||||
repo, "*", interrupt_cb, &count) );
|
||||
|
||||
cl_assert_equal_i(11, count);
|
||||
}
|
||||
|
94
tests-clar/refs/iterator.c
Normal file
94
tests-clar/refs/iterator.c
Normal file
@ -0,0 +1,94 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "refs.h"
|
||||
#include "vector.h"
|
||||
|
||||
static git_repository *repo;
|
||||
|
||||
void test_refs_iterator__initialize(void)
|
||||
{
|
||||
cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
|
||||
}
|
||||
|
||||
void test_refs_iterator__cleanup(void)
|
||||
{
|
||||
git_repository_free(repo);
|
||||
}
|
||||
|
||||
static const char *refnames[] = {
|
||||
"refs/heads/br2",
|
||||
"refs/heads/cannot-fetch",
|
||||
"refs/heads/chomped",
|
||||
"refs/heads/haacked",
|
||||
"refs/heads/master",
|
||||
"refs/heads/not-good",
|
||||
"refs/heads/packed",
|
||||
"refs/heads/packed-test",
|
||||
"refs/heads/subtrees",
|
||||
"refs/heads/test",
|
||||
"refs/heads/track-local",
|
||||
"refs/heads/trailing",
|
||||
"refs/notes/fanout",
|
||||
"refs/remotes/test/master",
|
||||
"refs/tags/annotated_tag_to_blob",
|
||||
"refs/tags/e90810b",
|
||||
"refs/tags/hard_tag",
|
||||
"refs/tags/point_to_blob",
|
||||
"refs/tags/taggerless",
|
||||
"refs/tags/test",
|
||||
"refs/tags/wrapped_tag",
|
||||
};
|
||||
|
||||
void test_refs_iterator__list(void)
|
||||
{
|
||||
git_reference_iterator *iter;
|
||||
git_vector output;
|
||||
char *refname;
|
||||
int error;
|
||||
size_t i;
|
||||
|
||||
cl_git_pass(git_vector_init(&output, 32, git__strcmp_cb));
|
||||
cl_git_pass(git_reference_iterator_new(&iter, repo));
|
||||
|
||||
do {
|
||||
const char *name;
|
||||
error = git_reference_next(&name, iter);
|
||||
cl_assert(error == 0 || error == GIT_ITEROVER);
|
||||
if (error != GIT_ITEROVER) {
|
||||
char *dup = git__strdup(name);
|
||||
cl_assert(dup != NULL);
|
||||
cl_git_pass(git_vector_insert(&output, dup));
|
||||
}
|
||||
} while (!error);
|
||||
|
||||
cl_assert_equal_i(output.length, ARRAY_SIZE(refnames));
|
||||
|
||||
git_vector_sort(&output);
|
||||
git_vector_foreach(&output, i, refname) {
|
||||
cl_assert_equal_s(refname, refnames[i]);
|
||||
}
|
||||
|
||||
git_reference_iterator_free(iter);
|
||||
|
||||
git_vector_foreach(&output, i, refname) {
|
||||
git__free(refname);
|
||||
}
|
||||
git_vector_free(&output);
|
||||
}
|
||||
|
||||
void test_refs_iterator__empty(void)
|
||||
{
|
||||
git_reference_iterator *iter;
|
||||
git_odb *odb;
|
||||
const char *name;
|
||||
git_repository *empty;
|
||||
|
||||
cl_git_pass(git_odb_new(&odb));
|
||||
cl_git_pass(git_repository_wrap_odb(&empty, odb));
|
||||
|
||||
cl_git_pass(git_reference_iterator_new(&iter, empty));
|
||||
cl_assert_equal_i(GIT_ITEROVER, git_reference_next(&name, iter));
|
||||
|
||||
git_reference_iterator_free(iter);
|
||||
git_odb_free(odb);
|
||||
git_repository_free(empty);
|
||||
}
|
@ -25,7 +25,7 @@ void test_refs_list__all(void)
|
||||
// try to list all the references in our test repo
|
||||
git_strarray ref_list;
|
||||
|
||||
cl_git_pass(git_reference_list(&ref_list, g_repo, GIT_REF_LISTALL));
|
||||
cl_git_pass(git_reference_list(&ref_list, g_repo));
|
||||
|
||||
/*{
|
||||
unsigned short i;
|
||||
@ -41,17 +41,6 @@ void test_refs_list__all(void)
|
||||
git_strarray_free(&ref_list);
|
||||
}
|
||||
|
||||
void test_refs_list__symbolic_only(void)
|
||||
{
|
||||
// try to list only the symbolic references
|
||||
git_strarray ref_list;
|
||||
|
||||
cl_git_pass(git_reference_list(&ref_list, g_repo, GIT_REF_SYMBOLIC));
|
||||
cl_assert(ref_list.count == 0); /* no symrefs in the test repo */
|
||||
|
||||
git_strarray_free(&ref_list);
|
||||
}
|
||||
|
||||
void test_refs_list__do_not_retrieve_references_which_name_end_with_a_lock_extension(void)
|
||||
{
|
||||
git_strarray ref_list;
|
||||
@ -61,7 +50,7 @@ void test_refs_list__do_not_retrieve_references_which_name_end_with_a_lock_exten
|
||||
"./testrepo/.git/refs/heads/hanwen.lock",
|
||||
"144344043ba4d4a405da03de3844aa829ae8be0e\n");
|
||||
|
||||
cl_git_pass(git_reference_list(&ref_list, g_repo, GIT_REF_LISTALL));
|
||||
cl_git_pass(git_reference_list(&ref_list, g_repo));
|
||||
cl_assert_equal_i((int)ref_list.count, 13);
|
||||
|
||||
git_strarray_free(&ref_list);
|
||||
|
@ -9,7 +9,7 @@ static void ensure_no_refname_starts_with_a_forward_slash(const char *path)
|
||||
size_t i;
|
||||
|
||||
cl_git_pass(git_repository_open(&repo, path));
|
||||
cl_git_pass(git_reference_list(&ref_list, repo, GIT_REF_LISTALL));
|
||||
cl_git_pass(git_reference_list(&ref_list, repo));
|
||||
|
||||
cl_assert(ref_list.count > 0);
|
||||
|
||||
@ -38,7 +38,7 @@ void test_refs_listall__from_repository_opened_through_gitdir_path(void)
|
||||
void test_refs_listall__from_repository_with_no_trailing_newline(void)
|
||||
{
|
||||
cl_git_pass(git_repository_open(&repo, cl_fixture("bad_tag.git")));
|
||||
cl_git_pass(git_reference_list(&ref_list, repo, GIT_REF_LISTALL));
|
||||
cl_git_pass(git_reference_list(&ref_list, repo));
|
||||
|
||||
cl_assert(ref_list.count > 0);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user