mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-03 14:12:22 +00:00
Merge pull request #1176 from arrbee/fix-iter-memleak
Alternative fix for iterator memory leak
This commit is contained in:
commit
3d4064a2cb
@ -452,9 +452,7 @@ static int checkout_get_actions(
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if ((diff->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0 &&
|
if ((diff->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0 &&
|
||||||
!hiter->ignore_case &&
|
(error = git_iterator_spoolandsort_push(hiter, true)) < 0)
|
||||||
(error = git_iterator_spoolandsort(
|
|
||||||
&hiter, hiter, diff->entrycomp, true)) < 0)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if ((error = git_iterator_current(hiter, &he)) < 0)
|
if ((error = git_iterator_current(hiter, &he)) < 0)
|
||||||
|
19
src/diff.c
19
src/diff.c
@ -589,18 +589,13 @@ int git_diff__from_iterators(
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (diff->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) {
|
if (diff->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) {
|
||||||
/* If one of the iterators doesn't have ignore_case set,
|
/* If either iterator does not have ignore_case set, then we will
|
||||||
* then that's unfortunate because we'll have to spool
|
* spool its data, sort it icase, and use that for the merge join
|
||||||
* its data, sort it icase, and then use that for our
|
* with the other iterator which was icase sorted. This call is
|
||||||
* merge join to the other iterator that is icase sorted */
|
* a no-op on an iterator that already matches "ignore_case".
|
||||||
if (!old_iter->ignore_case &&
|
*/
|
||||||
git_iterator_spoolandsort(
|
if (git_iterator_spoolandsort_push(old_iter, true) < 0 ||
|
||||||
&old_iter, old_iter, diff->entrycomp, true) < 0)
|
git_iterator_spoolandsort_push(new_iter, true) < 0)
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (!new_iter->ignore_case &&
|
|
||||||
git_iterator_spoolandsort(
|
|
||||||
&new_iter, new_iter, diff->entrycomp, true) < 0)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
206
src/iterator.c
206
src/iterator.c
@ -12,19 +12,24 @@
|
|||||||
#include "git2/submodule.h"
|
#include "git2/submodule.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#define ITERATOR_SET_CB(P,NAME_LC) do { \
|
||||||
|
(P)->cb.current = NAME_LC ## _iterator__current; \
|
||||||
|
(P)->cb.at_end = NAME_LC ## _iterator__at_end; \
|
||||||
|
(P)->cb.advance = NAME_LC ## _iterator__advance; \
|
||||||
|
(P)->cb.seek = NAME_LC ## _iterator__seek; \
|
||||||
|
(P)->cb.reset = NAME_LC ## _iterator__reset; \
|
||||||
|
(P)->cb.free = NAME_LC ## _iterator__free; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define ITERATOR_BASE_INIT(P,NAME_LC,NAME_UC) do { \
|
#define ITERATOR_BASE_INIT(P,NAME_LC,NAME_UC) do { \
|
||||||
(P) = git__calloc(1, sizeof(NAME_LC ## _iterator)); \
|
(P) = git__calloc(1, sizeof(NAME_LC ## _iterator)); \
|
||||||
GITERR_CHECK_ALLOC(P); \
|
GITERR_CHECK_ALLOC(P); \
|
||||||
(P)->base.type = GIT_ITERATOR_ ## NAME_UC; \
|
(P)->base.type = GIT_ITERATOR_ ## NAME_UC; \
|
||||||
|
(P)->base.cb = &(P)->cb; \
|
||||||
|
ITERATOR_SET_CB(P,NAME_LC); \
|
||||||
(P)->base.start = start ? git__strdup(start) : NULL; \
|
(P)->base.start = start ? git__strdup(start) : NULL; \
|
||||||
(P)->base.end = end ? git__strdup(end) : NULL; \
|
(P)->base.end = end ? git__strdup(end) : NULL; \
|
||||||
(P)->base.ignore_case = false; \
|
(P)->base.ignore_case = false; \
|
||||||
(P)->base.current = NAME_LC ## _iterator__current; \
|
|
||||||
(P)->base.at_end = NAME_LC ## _iterator__at_end; \
|
|
||||||
(P)->base.advance = NAME_LC ## _iterator__advance; \
|
|
||||||
(P)->base.seek = NAME_LC ## _iterator__seek; \
|
|
||||||
(P)->base.reset = NAME_LC ## _iterator__reset; \
|
|
||||||
(P)->base.free = NAME_LC ## _iterator__free; \
|
|
||||||
if ((start && !(P)->base.start) || (end && !(P)->base.end)) \
|
if ((start && !(P)->base.start) || (end && !(P)->base.end)) \
|
||||||
return -1; \
|
return -1; \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -81,20 +86,26 @@ static void empty_iterator__free(git_iterator *iter)
|
|||||||
GIT_UNUSED(iter);
|
GIT_UNUSED(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
git_iterator base;
|
||||||
|
git_iterator_callbacks cb;
|
||||||
|
} empty_iterator;
|
||||||
|
|
||||||
int git_iterator_for_nothing(git_iterator **iter)
|
int git_iterator_for_nothing(git_iterator **iter)
|
||||||
{
|
{
|
||||||
git_iterator *i = git__calloc(1, sizeof(git_iterator));
|
empty_iterator *i = git__calloc(1, sizeof(empty_iterator));
|
||||||
GITERR_CHECK_ALLOC(i);
|
GITERR_CHECK_ALLOC(i);
|
||||||
|
|
||||||
i->type = GIT_ITERATOR_EMPTY;
|
i->base.type = GIT_ITERATOR_EMPTY;
|
||||||
i->current = empty_iterator__no_item;
|
i->base.cb = &i->cb;
|
||||||
i->at_end = empty_iterator__at_end;
|
i->cb.current = empty_iterator__no_item;
|
||||||
i->advance = empty_iterator__no_item;
|
i->cb.at_end = empty_iterator__at_end;
|
||||||
i->seek = empty_iterator__seek;
|
i->cb.advance = empty_iterator__no_item;
|
||||||
i->reset = empty_iterator__reset;
|
i->cb.seek = empty_iterator__seek;
|
||||||
i->free = empty_iterator__free;
|
i->cb.reset = empty_iterator__reset;
|
||||||
|
i->cb.free = empty_iterator__free;
|
||||||
|
|
||||||
*iter = i;
|
*iter = (git_iterator *)i;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -110,6 +121,7 @@ struct tree_iterator_frame {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
git_iterator base;
|
git_iterator base;
|
||||||
|
git_iterator_callbacks cb;
|
||||||
tree_iterator_frame *stack, *tail;
|
tree_iterator_frame *stack, *tail;
|
||||||
git_index_entry entry;
|
git_index_entry entry;
|
||||||
git_buf path;
|
git_buf path;
|
||||||
@ -365,9 +377,9 @@ int git_iterator_for_tree_range(
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
git_iterator base;
|
git_iterator base;
|
||||||
|
git_iterator_callbacks cb;
|
||||||
git_index *index;
|
git_index *index;
|
||||||
size_t current;
|
size_t current;
|
||||||
bool free_index;
|
|
||||||
} index_iterator;
|
} index_iterator;
|
||||||
|
|
||||||
static int index_iterator__current(
|
static int index_iterator__current(
|
||||||
@ -447,8 +459,7 @@ static int index_iterator__reset(
|
|||||||
static void index_iterator__free(git_iterator *self)
|
static void index_iterator__free(git_iterator *self)
|
||||||
{
|
{
|
||||||
index_iterator *ii = (index_iterator *)self;
|
index_iterator *ii = (index_iterator *)self;
|
||||||
if (ii->free_index)
|
git_index_free(ii->index);
|
||||||
git_index_free(ii->index);
|
|
||||||
ii->index = NULL;
|
ii->index = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,9 +473,10 @@ int git_iterator_for_index_range(
|
|||||||
|
|
||||||
ITERATOR_BASE_INIT(ii, index, INDEX);
|
ITERATOR_BASE_INIT(ii, index, INDEX);
|
||||||
|
|
||||||
ii->index = index;
|
|
||||||
ii->base.repo = git_index_owner(index);
|
ii->base.repo = git_index_owner(index);
|
||||||
ii->base.ignore_case = ii->index->ignore_case;
|
ii->base.ignore_case = index->ignore_case;
|
||||||
|
ii->index = index;
|
||||||
|
GIT_REFCOUNT_INC(index);
|
||||||
|
|
||||||
index_iterator__reset((git_iterator *)ii, NULL, NULL);
|
index_iterator__reset((git_iterator *)ii, NULL, NULL);
|
||||||
|
|
||||||
@ -482,13 +494,10 @@ int git_iterator_for_repo_index_range(
|
|||||||
int error;
|
int error;
|
||||||
git_index *index;
|
git_index *index;
|
||||||
|
|
||||||
if ((error = git_repository_index(&index, repo)) < 0)
|
if ((error = git_repository_index__weakptr(&index, repo)) < 0)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
if (!(error = git_iterator_for_index_range(iter, index, start, end)))
|
return git_iterator_for_index_range(iter, index, start, end);
|
||||||
((index_iterator *)(*iter))->free_index = true;
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct workdir_iterator_frame workdir_iterator_frame;
|
typedef struct workdir_iterator_frame workdir_iterator_frame;
|
||||||
@ -500,6 +509,7 @@ struct workdir_iterator_frame {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
git_iterator base;
|
git_iterator base;
|
||||||
|
git_iterator_callbacks cb;
|
||||||
workdir_iterator_frame *stack;
|
workdir_iterator_frame *stack;
|
||||||
int (*entrycmp)(const void *pfx, const void *item);
|
int (*entrycmp)(const void *pfx, const void *item);
|
||||||
git_ignores ignores;
|
git_ignores ignores;
|
||||||
@ -830,46 +840,43 @@ int git_iterator_for_workdir_range(
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
git_iterator base;
|
/* replacement callbacks */
|
||||||
git_iterator *wrapped;
|
git_iterator_callbacks cb;
|
||||||
|
/* original iterator values */
|
||||||
|
git_iterator_callbacks *orig;
|
||||||
|
git_iterator_type_t orig_type;
|
||||||
|
/* spoolandsort data */
|
||||||
git_vector entries;
|
git_vector entries;
|
||||||
git_vector_cmp comparer;
|
|
||||||
git_pool entry_pool;
|
git_pool entry_pool;
|
||||||
git_pool string_pool;
|
git_pool string_pool;
|
||||||
unsigned int position;
|
size_t position;
|
||||||
} spoolandsort_iterator;
|
} spoolandsort_callbacks;
|
||||||
|
|
||||||
static int spoolandsort_iterator__current(
|
static int spoolandsort_iterator__current(
|
||||||
git_iterator *self, const git_index_entry **entry)
|
git_iterator *self, const git_index_entry **entry)
|
||||||
{
|
{
|
||||||
spoolandsort_iterator *si = (spoolandsort_iterator *)self;
|
spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb;
|
||||||
|
|
||||||
if (si->position < si->entries.length)
|
*entry = (const git_index_entry *)
|
||||||
*entry = (const git_index_entry *)git_vector_get(
|
git_vector_get(&scb->entries, scb->position);
|
||||||
&si->entries, si->position);
|
|
||||||
else
|
|
||||||
*entry = NULL;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spoolandsort_iterator__at_end(git_iterator *self)
|
static int spoolandsort_iterator__at_end(git_iterator *self)
|
||||||
{
|
{
|
||||||
spoolandsort_iterator *si = (spoolandsort_iterator *)self;
|
spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb;
|
||||||
|
|
||||||
return 0 == si->entries.length || si->entries.length - 1 <= si->position;
|
return 0 == scb->entries.length || scb->entries.length - 1 <= scb->position;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spoolandsort_iterator__advance(
|
static int spoolandsort_iterator__advance(
|
||||||
git_iterator *self, const git_index_entry **entry)
|
git_iterator *self, const git_index_entry **entry)
|
||||||
{
|
{
|
||||||
spoolandsort_iterator *si = (spoolandsort_iterator *)self;
|
spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb;
|
||||||
|
|
||||||
if (si->position < si->entries.length)
|
*entry = (const git_index_entry *)
|
||||||
*entry = (const git_index_entry *)git_vector_get(
|
git_vector_get(&scb->entries, ++scb->position);
|
||||||
&si->entries, ++si->position);
|
|
||||||
else
|
|
||||||
*entry = NULL;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -885,77 +892,100 @@ static int spoolandsort_iterator__seek(git_iterator *self, const char *prefix)
|
|||||||
static int spoolandsort_iterator__reset(
|
static int spoolandsort_iterator__reset(
|
||||||
git_iterator *self, const char *start, const char *end)
|
git_iterator *self, const char *start, const char *end)
|
||||||
{
|
{
|
||||||
spoolandsort_iterator *si = (spoolandsort_iterator *)self;
|
spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb;
|
||||||
|
|
||||||
GIT_UNUSED(start); GIT_UNUSED(end);
|
GIT_UNUSED(start); GIT_UNUSED(end);
|
||||||
|
|
||||||
si->position = 0;
|
scb->position = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void spoolandsort_iterator__free_callbacks(spoolandsort_callbacks *scb)
|
||||||
|
{
|
||||||
|
git_pool_clear(&scb->string_pool);
|
||||||
|
git_pool_clear(&scb->entry_pool);
|
||||||
|
git_vector_free(&scb->entries);
|
||||||
|
git__free(scb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void git_iterator_spoolandsort_pop(git_iterator *self)
|
||||||
|
{
|
||||||
|
spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb;
|
||||||
|
|
||||||
|
if (self->type != GIT_ITERATOR_SPOOLANDSORT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self->cb = scb->orig;
|
||||||
|
self->type = scb->orig_type;
|
||||||
|
self->ignore_case = !self->ignore_case;
|
||||||
|
|
||||||
|
spoolandsort_iterator__free_callbacks(scb);
|
||||||
|
}
|
||||||
|
|
||||||
static void spoolandsort_iterator__free(git_iterator *self)
|
static void spoolandsort_iterator__free(git_iterator *self)
|
||||||
{
|
{
|
||||||
spoolandsort_iterator *si = (spoolandsort_iterator *)self;
|
git_iterator_spoolandsort_pop(self);
|
||||||
|
self->cb->free(self);
|
||||||
git_pool_clear(&si->string_pool);
|
|
||||||
git_pool_clear(&si->entry_pool);
|
|
||||||
git_vector_free(&si->entries);
|
|
||||||
git_iterator_free(si->wrapped);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_iterator_spoolandsort_range(
|
int git_iterator_spoolandsort_push(git_iterator *iter, bool ignore_case)
|
||||||
git_iterator **iter,
|
|
||||||
git_iterator *towrap,
|
|
||||||
git_vector_cmp comparer,
|
|
||||||
bool ignore_case,
|
|
||||||
const char *start,
|
|
||||||
const char *end)
|
|
||||||
{
|
{
|
||||||
spoolandsort_iterator *si;
|
|
||||||
const git_index_entry *item;
|
const git_index_entry *item;
|
||||||
|
spoolandsort_callbacks *scb;
|
||||||
|
int (*entrycomp)(const void *a, const void *b);
|
||||||
|
|
||||||
assert(iter && towrap && comparer);
|
if (iter->ignore_case == ignore_case)
|
||||||
|
return 0;
|
||||||
|
|
||||||
ITERATOR_BASE_INIT(si, spoolandsort, SPOOLANDSORT);
|
scb = git__calloc(1, sizeof(spoolandsort_callbacks));
|
||||||
si->base.ignore_case = ignore_case;
|
GITERR_CHECK_ALLOC(scb);
|
||||||
si->wrapped = towrap;
|
|
||||||
si->comparer = comparer;
|
|
||||||
si->position = 0;
|
|
||||||
|
|
||||||
if (git_vector_init(&si->entries, 16, si->comparer) < 0 ||
|
ITERATOR_SET_CB(scb,spoolandsort);
|
||||||
git_iterator_current(towrap, &item) < 0 ||
|
|
||||||
git_pool_init(&si->entry_pool, sizeof(git_index_entry), 0) ||
|
scb->orig = iter->cb;
|
||||||
git_pool_init(&si->string_pool, 1, 0))
|
scb->orig_type = iter->type;
|
||||||
{
|
scb->position = 0;
|
||||||
git__free(si);
|
|
||||||
return -1;
|
entrycomp = ignore_case ? git_index_entry__cmp_icase : git_index_entry__cmp;
|
||||||
}
|
|
||||||
|
if (git_vector_init(&scb->entries, 16, entrycomp) < 0 ||
|
||||||
|
git_pool_init(&scb->entry_pool, sizeof(git_index_entry), 0) < 0 ||
|
||||||
|
git_pool_init(&scb->string_pool, 1, 0) < 0 ||
|
||||||
|
git_iterator_current(iter, &item) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
while (item) {
|
||||||
|
git_index_entry *clone = git_pool_malloc(&scb->entry_pool, 1);
|
||||||
|
if (!clone)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
while (item)
|
|
||||||
{
|
|
||||||
git_index_entry *clone = git_pool_malloc(&si->entry_pool, 1);
|
|
||||||
memcpy(clone, item, sizeof(git_index_entry));
|
memcpy(clone, item, sizeof(git_index_entry));
|
||||||
|
|
||||||
if (item->path)
|
if (item->path) {
|
||||||
{
|
clone->path = git_pool_strdup(&scb->string_pool, item->path);
|
||||||
clone->path = git_pool_strdup(&si->string_pool, item->path);
|
if (!clone->path)
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
git_vector_insert(&si->entries, clone);
|
if (git_vector_insert(&scb->entries, clone) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
if (git_iterator_advance(towrap, &item) < 0)
|
if (git_iterator_advance(iter, &item) < 0)
|
||||||
{
|
goto fail;
|
||||||
git__free(si);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
git_vector_sort(&si->entries);
|
git_vector_sort(&scb->entries);
|
||||||
|
|
||||||
*iter = (git_iterator *)si;
|
iter->cb = (git_iterator_callbacks *)scb;
|
||||||
|
iter->type = GIT_ITERATOR_SPOOLANDSORT;
|
||||||
|
iter->ignore_case = !iter->ignore_case;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
spoolandsort_iterator__free_callbacks(scb);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_iterator_current_tree_entry(
|
int git_iterator_current_tree_entry(
|
||||||
|
@ -26,19 +26,22 @@ typedef enum {
|
|||||||
GIT_ITERATOR_SPOOLANDSORT = 4
|
GIT_ITERATOR_SPOOLANDSORT = 4
|
||||||
} git_iterator_type_t;
|
} git_iterator_type_t;
|
||||||
|
|
||||||
struct git_iterator {
|
typedef struct {
|
||||||
git_iterator_type_t type;
|
|
||||||
git_repository *repo;
|
|
||||||
char *start;
|
|
||||||
char *end;
|
|
||||||
bool ignore_case;
|
|
||||||
|
|
||||||
int (*current)(git_iterator *, const git_index_entry **);
|
int (*current)(git_iterator *, const git_index_entry **);
|
||||||
int (*at_end)(git_iterator *);
|
int (*at_end)(git_iterator *);
|
||||||
int (*advance)(git_iterator *, const git_index_entry **);
|
int (*advance)(git_iterator *, const git_index_entry **);
|
||||||
int (*seek)(git_iterator *, const char *prefix);
|
int (*seek)(git_iterator *, const char *prefix);
|
||||||
int (*reset)(git_iterator *, const char *start, const char *end);
|
int (*reset)(git_iterator *, const char *start, const char *end);
|
||||||
void (*free)(git_iterator *);
|
void (*free)(git_iterator *);
|
||||||
|
} git_iterator_callbacks;
|
||||||
|
|
||||||
|
struct git_iterator {
|
||||||
|
git_iterator_type_t type;
|
||||||
|
git_iterator_callbacks *cb;
|
||||||
|
git_repository *repo;
|
||||||
|
char *start;
|
||||||
|
char *end;
|
||||||
|
bool ignore_case;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int git_iterator_for_nothing(git_iterator **iter);
|
extern int git_iterator_for_nothing(git_iterator **iter);
|
||||||
@ -82,18 +85,13 @@ GIT_INLINE(int) git_iterator_for_workdir(
|
|||||||
return git_iterator_for_workdir_range(iter, repo, NULL, NULL);
|
return git_iterator_for_workdir_range(iter, repo, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int git_iterator_spoolandsort_range(
|
/* Spool all iterator values, resort with alternative ignore_case value
|
||||||
git_iterator **iter, git_iterator *towrap,
|
* and replace callbacks with spoolandsort alternates.
|
||||||
git_vector_cmp comparer, bool ignore_case,
|
*/
|
||||||
const char *start, const char *end);
|
extern int git_iterator_spoolandsort_push(git_iterator *iter, bool ignore_case);
|
||||||
|
|
||||||
GIT_INLINE(int) git_iterator_spoolandsort(
|
/* Restore original callbacks - not required in most circumstances */
|
||||||
git_iterator **iter, git_iterator *towrap,
|
extern void git_iterator_spoolandsort_pop(git_iterator *iter);
|
||||||
git_vector_cmp comparer, bool ignore_case)
|
|
||||||
{
|
|
||||||
return git_iterator_spoolandsort_range(
|
|
||||||
iter, towrap, comparer, ignore_case, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Entry is not guaranteed to be fully populated. For a tree iterator,
|
/* Entry is not guaranteed to be fully populated. For a tree iterator,
|
||||||
* we will only populate the mode, oid and path, for example. For a workdir
|
* we will only populate the mode, oid and path, for example. For a workdir
|
||||||
@ -106,30 +104,30 @@ GIT_INLINE(int) git_iterator_spoolandsort(
|
|||||||
GIT_INLINE(int) git_iterator_current(
|
GIT_INLINE(int) git_iterator_current(
|
||||||
git_iterator *iter, const git_index_entry **entry)
|
git_iterator *iter, const git_index_entry **entry)
|
||||||
{
|
{
|
||||||
return iter->current(iter, entry);
|
return iter->cb->current(iter, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
GIT_INLINE(int) git_iterator_at_end(git_iterator *iter)
|
GIT_INLINE(int) git_iterator_at_end(git_iterator *iter)
|
||||||
{
|
{
|
||||||
return iter->at_end(iter);
|
return iter->cb->at_end(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
GIT_INLINE(int) git_iterator_advance(
|
GIT_INLINE(int) git_iterator_advance(
|
||||||
git_iterator *iter, const git_index_entry **entry)
|
git_iterator *iter, const git_index_entry **entry)
|
||||||
{
|
{
|
||||||
return iter->advance(iter, entry);
|
return iter->cb->advance(iter, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
GIT_INLINE(int) git_iterator_seek(
|
GIT_INLINE(int) git_iterator_seek(
|
||||||
git_iterator *iter, const char *prefix)
|
git_iterator *iter, const char *prefix)
|
||||||
{
|
{
|
||||||
return iter->seek(iter, prefix);
|
return iter->cb->seek(iter, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
GIT_INLINE(int) git_iterator_reset(
|
GIT_INLINE(int) git_iterator_reset(
|
||||||
git_iterator *iter, const char *start, const char *end)
|
git_iterator *iter, const char *start, const char *end)
|
||||||
{
|
{
|
||||||
return iter->reset(iter, start, end);
|
return iter->cb->reset(iter, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
GIT_INLINE(void) git_iterator_free(git_iterator *iter)
|
GIT_INLINE(void) git_iterator_free(git_iterator *iter)
|
||||||
@ -137,7 +135,7 @@ GIT_INLINE(void) git_iterator_free(git_iterator *iter)
|
|||||||
if (iter == NULL)
|
if (iter == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
iter->free(iter);
|
iter->cb->free(iter);
|
||||||
|
|
||||||
git__free(iter->start);
|
git__free(iter->start);
|
||||||
git__free(iter->end);
|
git__free(iter->end);
|
||||||
|
@ -1729,6 +1729,9 @@ cleanup:
|
|||||||
GITERR_REFERENCE,
|
GITERR_REFERENCE,
|
||||||
"The given reference name '%s' is not valid", name);
|
"The given reference name '%s' is not valid", name);
|
||||||
|
|
||||||
|
if (error && normalize)
|
||||||
|
git_buf_free(buf);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user