Commit 3dbee456 by Russell Belfer

Some index internals refactoring

Again, laying groundwork for some index iterator changes, this
contains a bunch of code refactorings for index internals that
should make it easier down the line to add locking around index
modifications.  Also this removes the redundant prefix_position
function and fixes some potential memory leaks.
parent c67fd4c9
......@@ -77,7 +77,12 @@ typedef struct git_index_entry {
#define GIT_IDXENTRY_VALID (0x8000)
#define GIT_IDXENTRY_STAGESHIFT 12
#define GIT_IDXENTRY_STAGE(E) (((E)->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT)
#define GIT_IDXENTRY_STAGE(E) \
(((E)->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT)
#define GIT_IDXENTRY_STAGE_SET(E,S) do { \
(E)->flags = ((E)->flags & ~GIT_IDXENTRY_STAGEMASK) | \
(((S) & 0x03) << GIT_IDXENTRY_STAGESHIFT); } while (0)
/**
* Bitmasks for on-disk fields of `git_index_entry`'s `flags_extended`
......@@ -327,12 +332,14 @@ GIT_EXTERN(size_t) git_index_entrycount(const git_index *index);
/**
* Clear the contents (all the entries) of an index object.
* This clears the index object in memory; changes must be manually
* written to disk for them to take effect.
*
* This clears the index object in memory; changes must be explicitly
* written to disk for them to take effect persistently.
*
* @param index an existing index object
* @return 0 on success, error code < 0 on failure
*/
GIT_EXTERN(void) git_index_clear(git_index *index);
GIT_EXTERN(int) git_index_clear(git_index *index);
/**
* Get a pointer to one of the entries in the index
......
......@@ -277,19 +277,23 @@ static int checkout_action_wd_only(
/* check if item is tracked in the index but not in the checkout diff */
if (data->index != NULL) {
size_t pos;
error = git_index__find(
&pos, data->index, wd->path, 0, GIT_INDEX_STAGE_ANY);
if (wd->mode != GIT_FILEMODE_TREE) {
if (!(error = git_index_find(NULL, data->index, wd->path))) {
if (!error) { /* found by git_index__find call */
notify = GIT_CHECKOUT_NOTIFY_DIRTY;
remove = ((data->strategy & GIT_CHECKOUT_FORCE) != 0);
} else if (error != GIT_ENOTFOUND)
return error;
else
giterr_clear();
error = 0; /* git_index__find does not set error msg */
} else {
/* for tree entries, we have to see if there are any index
* entries that are contained inside that tree
*/
size_t pos = git_index__prefix_position(data->index, wd->path);
const git_index_entry *e = git_index_get_byindex(data->index, pos);
if (e != NULL && data->diff->pfxcomp(e->path, wd->path) == 0) {
......
......@@ -50,11 +50,13 @@ struct git_index_conflict_iterator {
extern void git_index_entry__init_from_stat(
git_index_entry *entry, struct stat *st, bool trust_mode);
extern size_t git_index__prefix_position(git_index *index, const char *path);
extern int git_index_entry__cmp(const void *a, const void *b);
extern int git_index_entry__cmp_icase(const void *a, const void *b);
/* Search index for `path`, returning GIT_ENOTFOUND if it does not exist.
* `at_pos` is set to the position where it is or would be inserted.
* Pass `path_len` as strlen of path or 0 to call strlen internally.
*/
extern int git_index__find(
size_t *at_pos, git_index *index, const char *path, size_t path_len, int stage);
......
......@@ -815,8 +815,10 @@ static int index_iterator__reset(
if (iterator__reset_range(self, start, end) < 0)
return -1;
ii->current = ii->base.start ?
git_index__prefix_position(ii->index, ii->base.start) : 0;
ii->current = 0;
if (ii->base.start)
git_index__find(&ii->current, ii->index, ii->base.start, 0, 0);
if ((ie = index_iterator__skip_conflicts(ii)) == NULL)
return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment