diff options
-rw-r--r-- | src/checkout.c | 6 | ||||
-rw-r--r-- | src/index.c | 86 | ||||
-rw-r--r-- | src/index.h | 16 | ||||
-rw-r--r-- | src/iterator.c | 7 | ||||
-rw-r--r-- | src/pathspec.c | 2 |
5 files changed, 63 insertions, 54 deletions
diff --git a/src/checkout.c b/src/checkout.c index a251c08c0..0b385226b 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -279,17 +279,17 @@ static int checkout_action_wd_only( if (data->index != NULL) { size_t pos; - error = git_index__find( + error = git_index__find_pos( &pos, data->index, wd->path, 0, GIT_INDEX_STAGE_ANY); if (wd->mode != GIT_FILEMODE_TREE) { - if (!error) { /* found by git_index__find call */ + if (!error) { /* found by git_index__find_pos call */ notify = GIT_CHECKOUT_NOTIFY_DIRTY; remove = ((data->strategy & GIT_CHECKOUT_FORCE) != 0); } else if (error != GIT_ENOTFOUND) return error; else - error = 0; /* git_index__find does not set error msg */ + error = 0; /* git_index__find_pos 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 diff --git a/src/index.c b/src/index.c index 094328b95..10fb1fea7 100644 --- a/src/index.c +++ b/src/index.c @@ -342,6 +342,28 @@ static int index_sort_if_needed(git_index *index, bool need_lock) return 0; } +GIT_INLINE(int) index_find_in_entries( + size_t *out, git_vector *entries, git_vector_cmp entry_srch, + const char *path, size_t path_len, int stage) +{ + struct entry_srch_key srch_key; + srch_key.path = path; + srch_key.pathlen = !path_len ? strlen(path) : path_len; + srch_key.stage = stage; + return git_vector_bsearch2(out, entries, entry_srch, &srch_key); +} + +GIT_INLINE(int) index_find( + size_t *out, git_index *index, + const char *path, size_t path_len, int stage, bool need_lock) +{ + if (index_sort_if_needed(index, need_lock) < 0) + return -1; + + return index_find_in_entries( + out, &index->entries, index->entries_search, path, path_len, stage); +} + void git_index__set_ignore_case(git_index *index, bool ignore_case) { index->ignore_case = ignore_case; @@ -687,16 +709,6 @@ size_t git_index_entrycount(const git_index *index) return index->entries.length; } -GIT_INLINE(int) git_index__find_internal( - size_t *out, git_index *index, const char *path, size_t path_len, int stage, - bool need_lock) -{ - if (index_sort_if_needed(index, need_lock) < 0) - return -1; - return git_index__find_in_entries( - out, &index->entries, index->entries_search, path, path_len, stage); -} - const git_index_entry *git_index_get_byindex( git_index *index, size_t n) { @@ -713,7 +725,7 @@ const git_index_entry *git_index_get_bypath( assert(index); - if (git_index__find_internal(&pos, index, path, 0, stage, true) < 0) { + if (index_find(&pos, index, path, 0, stage, true) < 0) { giterr_set(GITERR_INDEX, "Index does not contain %s", path); return NULL; } @@ -896,7 +908,7 @@ static int has_dir_name(git_index *index, } len = slash - name; - if (!git_index__find_internal(&pos, index, name, len, stage, false)) { + if (!index_find(&pos, index, name, len, stage, false)) { retval = -1; if (!ok_to_replace) break; @@ -976,7 +988,7 @@ static int index_insert( git_vector_sort(&index->entries); /* look if an entry with this path already exists */ - if (!git_index__find_internal( + if (!index_find( &position, index, entry->path, 0, GIT_IDXENTRY_STAGE(entry), false)) { existing = index->entries.contents[position]; /* update filemode to existing values if stat is not trusted */ @@ -1098,7 +1110,7 @@ int git_index_remove(git_index *index, const char *path, int stage) return -1; } - if (git_index__find_internal(&position, index, path, 0, stage, false) < 0) { + if (index_find(&position, index, path, 0, stage, false) < 0) { giterr_set( GITERR_INDEX, "Index does not contain %s at stage %d", path, stage); error = GIT_ENOTFOUND; @@ -1124,8 +1136,7 @@ int git_index_remove_directory(git_index *index, const char *dir, int stage) if (!(error = git_buf_sets(&pfx, dir)) && !(error = git_path_to_dir(&pfx))) - git_index__find_internal( - &pos, index, pfx.ptr, pfx.size, GIT_INDEX_STAGE_ANY, false); + index_find(&pos, index, pfx.ptr, pfx.size, GIT_INDEX_STAGE_ANY, false); while (!error) { entry = git_vector_get(&index->entries, pos); @@ -1148,22 +1159,11 @@ int git_index_remove_directory(git_index *index, const char *dir, int stage) return error; } -int git_index__find_in_entries( - size_t *out, git_vector *entries, git_vector_cmp entry_srch, - const char *path, size_t path_len, int stage) -{ - struct entry_srch_key srch_key; - srch_key.path = path; - srch_key.pathlen = !path_len ? strlen(path) : path_len; - srch_key.stage = stage; - return git_vector_bsearch2(out, entries, entry_srch, &srch_key); -} - -int git_index__find( +int git_index__find_pos( size_t *out, git_index *index, const char *path, size_t path_len, int stage) { assert(index && path); - return git_index__find_internal(out, index, path, path_len, stage, true); + return index_find(out, index, path, path_len, stage, true); } int git_index_find(size_t *at_pos, git_index *index, const char *path) @@ -1177,7 +1177,8 @@ int git_index_find(size_t *at_pos, git_index *index, const char *path) return -1; } - if (git_vector_bsearch2(&pos, &index->entries, index->entries_search_path, path) < 0) { + if (git_vector_bsearch2( + &pos, &index->entries, index->entries_search_path, path) < 0) { git_mutex_unlock(&index->lock); giterr_set(GITERR_INDEX, "Index does not contain %s", path); return GIT_ENOTFOUND; @@ -1186,13 +1187,11 @@ int git_index_find(size_t *at_pos, git_index *index, const char *path) /* Since our binary search only looked at path, we may be in the * middle of a list of stages. */ - while (pos > 0) { - const git_index_entry *prev = git_vector_get(&index->entries, pos-1); + for (; pos > 0; --pos) { + const git_index_entry *prev = git_vector_get(&index->entries, pos - 1); if (index->entries_cmp_path(prev->path, path) != 0) break; - - --pos; } if (at_pos) @@ -2269,7 +2268,7 @@ static int read_tree_cb( /* look for corresponding old entry and copy data to new entry */ if (data->old_entries != NULL && - !git_index__find_in_entries( + !index_find_in_entries( &pos, data->old_entries, data->entry_cmp, path.ptr, 0, 0) && (old_entry = git_vector_get(data->old_entries, pos)) != NULL && entry->mode == old_entry->mode && @@ -2394,7 +2393,7 @@ int git_index_add_all( /* skip ignored items that are not already in the index */ if ((flags & GIT_INDEX_ADD_FORCE) == 0 && git_iterator_current_is_ignored(wditer) && - git_index__find(&existing, index, wd->path, 0, 0) < 0) + index_find(&existing, index, wd->path, 0, 0, true) < 0) continue; /* issue notification callback if requested */ @@ -2556,7 +2555,7 @@ int git_index_update_all( return error; } -int git_index__snapshot(git_vector *entries, git_index *index) +int git_index_snapshot_new(git_vector *snap, git_index *index) { int error; @@ -2570,7 +2569,7 @@ int git_index__snapshot(git_vector *entries, git_index *index) git_atomic_inc(&index->readers); git_vector_sort(&index->entries); - error = git_vector_dup(entries, &index->entries, index->entries._cmp); + error = git_vector_dup(snap, &index->entries, index->entries._cmp); git_mutex_unlock(&index->lock); @@ -2580,8 +2579,10 @@ int git_index__snapshot(git_vector *entries, git_index *index) return error; } -void git_index__release_snapshot(git_index *index) +void git_index_snapshot_release(git_vector *snap, git_index *index) { + git_vector_free(snap); + git_atomic_dec(&index->readers); if (!git_mutex_lock(&index->lock)) { @@ -2591,3 +2592,10 @@ void git_index__release_snapshot(git_index *index) git_index_free(index); } + +int git_index_snapshot_find( + size_t *out, git_vector *entries, git_vector_cmp entry_srch, + const char *path, size_t path_len, int stage) +{ + return index_find_in_entries(out, entries, entry_srch, path, path_len, stage); +} diff --git a/src/index.h b/src/index.h index cb4425885..50a0b4b6c 100644 --- a/src/index.h +++ b/src/index.h @@ -61,11 +61,13 @@ extern int git_index_entry_icmp(const void *a, const void *b); extern int git_index_entry_srch(const void *a, const void *b); extern int git_index_entry_isrch(const void *a, const void *b); -/* Search index for `path`, returning GIT_ENOTFOUND if it does not exist. +/* Search index for `path`, returning GIT_ENOTFOUND if it does not exist + * (but not setting an error message). + * * `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( +extern int git_index__find_pos( size_t *at_pos, git_index *index, const char *path, size_t path_len, int stage); extern void git_index__set_ignore_case(git_index *index, bool ignore_case); @@ -82,13 +84,13 @@ extern int git_index__changed_relative_to(git_index *index, const git_futils_fil /* Copy the current entries vector *and* increment the index refcount. * Call `git_index__release_snapshot` when done. */ -extern int git_index__snapshot(git_vector *entries, git_index *index); -extern void git_index__release_snapshot(git_index *index); +extern int git_index_snapshot_new(git_vector *snap, git_index *index); +extern void git_index_snapshot_release(git_vector *snap, git_index *index); /* Allow searching in a snapshot; entries must already be sorted! */ -extern int git_index__find_in_entries( - size_t *at_pos, - git_vector *entries, git_vector_cmp entry_srch, +extern int git_index_snapshot_find( + size_t *at_pos, git_vector *snap, git_vector_cmp entry_srch, const char *path, size_t path_len, int stage); + #endif diff --git a/src/iterator.c b/src/iterator.c index 53ef278d1..63c14f962 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -820,7 +820,7 @@ static int index_iterator__reset( ii->current = 0; if (ii->base.start) - git_index__find_in_entries( + git_index_snapshot_find( &ii->current, &ii->entries, ii->entry_srch, ii->base.start, 0, 0); if ((ie = index_iterator__skip_conflicts(ii)) == NULL) @@ -846,9 +846,8 @@ static int index_iterator__reset( static void index_iterator__free(git_iterator *self) { index_iterator *ii = (index_iterator *)self; - git_index__release_snapshot(ii->index); + git_index_snapshot_release(&ii->entries, ii->index); ii->index = NULL; - git_vector_free(&ii->entries); git_buf_free(&ii->partial); } @@ -863,7 +862,7 @@ int git_iterator_for_index( index_iterator *ii = git__calloc(1, sizeof(index_iterator)); GITERR_CHECK_ALLOC(ii); - if ((error = git_index__snapshot(&ii->entries, index)) < 0) { + if ((error = git_index_snapshot_new(&ii->entries, index)) < 0) { git__free(ii); return error; } diff --git a/src/pathspec.c b/src/pathspec.c index 471488495..09650de7c 100644 --- a/src/pathspec.c +++ b/src/pathspec.c @@ -445,7 +445,7 @@ static int pathspec_match_from_iterator( /* check if path is ignored and untracked */ if (index != NULL && git_iterator_current_is_ignored(iter) && - git_index__find(NULL, index, entry->path, 0, GIT_INDEX_STAGE_ANY) < 0) + git_index__find_pos(NULL, index, entry->path, 0, GIT_INDEX_STAGE_ANY) < 0) continue; /* mark the matched pattern as used */ |