diff --git a/src/checkout.c b/src/checkout.c index 0be87b4a3..41de0d7d4 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -1248,10 +1248,8 @@ int git_checkout_iterator( &baseline, data.opts.baseline, iterflags, data.pfx, data.pfx)) < 0) goto cleanup; - /* Handle case insensitivity for baseline if necessary */ - if (git_iterator_ignore_case(workdir) != git_iterator_ignore_case(baseline)) - if ((error = git_iterator_spoolandsort_push(baseline, true)) < 0) - goto cleanup; + /* Should not have case insensitivity mismatch */ + assert(git_iterator_ignore_case(workdir) == git_iterator_ignore_case(baseline)); /* Generate baseline-to-target diff which will include an entry for * every possible update that might need to be made. diff --git a/src/diff.c b/src/diff.c index c0f8ee689..766361938 100644 --- a/src/diff.c +++ b/src/diff.c @@ -620,13 +620,8 @@ int git_diff__from_iterators( goto fail; if (diff->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) { - /* If either iterator does not have ignore_case set, then we will - * spool its data, sort it icase, and use that for the merge join - * with the other iterator which was icase sorted. This call is - * a no-op on an iterator that already matches "ignore_case". - */ - if (git_iterator_spoolandsort_push(old_iter, true) < 0 || - git_iterator_spoolandsort_push(new_iter, true) < 0) + if (git_iterator_set_ignore_case(old_iter, true) < 0 || + git_iterator_set_ignore_case(new_iter, true) < 0) goto fail; } diff --git a/src/iterator.c b/src/iterator.c index 2832e4ac2..e28f20e12 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -960,161 +960,6 @@ fail: } -typedef struct { - /* replacement callbacks */ - git_iterator_callbacks cb; - /* original iterator values */ - git_iterator_callbacks *orig; - git_iterator_type_t orig_type; - /* spoolandsort data */ - git_vector entries; - git_pool entry_pool; - git_pool string_pool; - size_t position; -} spoolandsort_callbacks; - -static int spoolandsort_iterator__current( - const git_index_entry **entry, git_iterator *self) -{ - spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb; - - *entry = (const git_index_entry *) - git_vector_get(&scb->entries, scb->position); - - return 0; -} - -static int spoolandsort_iterator__at_end(git_iterator *self) -{ - spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb; - - return 0 == scb->entries.length || scb->entries.length - 1 <= scb->position; -} - -static int spoolandsort_iterator__advance( - const git_index_entry **entry, git_iterator *self) -{ - spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb; - - *entry = (const git_index_entry *) - git_vector_get(&scb->entries, ++scb->position); - - return 0; -} - -static int spoolandsort_iterator__seek(git_iterator *self, const char *prefix) -{ - GIT_UNUSED(self); - GIT_UNUSED(prefix); - - return -1; -} - -static int spoolandsort_iterator__reset( - git_iterator *self, const char *start, const char *end) -{ - spoolandsort_callbacks *scb = (spoolandsort_callbacks *)self->cb; - - GIT_UNUSED(start); GIT_UNUSED(end); - - scb->position = 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_TYPE_SPOOLANDSORT) - return; - - self->cb = scb->orig; - self->type = scb->orig_type; - self->flags ^= GIT_ITERATOR_IGNORE_CASE; - - spoolandsort_iterator__free_callbacks(scb); -} - -static void spoolandsort_iterator__free(git_iterator *self) -{ - git_iterator_spoolandsort_pop(self); - self->cb->free(self); -} - -int git_iterator_spoolandsort_push(git_iterator *iter, bool ignore_case) -{ - const git_index_entry *item; - spoolandsort_callbacks *scb; - int (*entrycomp)(const void *a, const void *b); - - if (((iter->flags & GIT_ITERATOR_IGNORE_CASE) != 0) == (ignore_case != 0)) - return 0; - - if (iter->type == GIT_ITERATOR_TYPE_EMPTY) { - iter->flags = (iter->flags ^ GIT_ITERATOR_IGNORE_CASE); - return 0; - } - - scb = git__calloc(1, sizeof(spoolandsort_callbacks)); - GITERR_CHECK_ALLOC(scb); - - ITERATOR_SET_CB(scb,spoolandsort); - - scb->orig = iter->cb; - scb->orig_type = iter->type; - scb->position = 0; - - 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(&item, iter) < 0) - goto fail; - - while (item) { - git_index_entry *clone = git_pool_malloc(&scb->entry_pool, 1); - if (!clone) - goto fail; - - memcpy(clone, item, sizeof(git_index_entry)); - - if (item->path) { - clone->path = git_pool_strdup(&scb->string_pool, item->path); - if (!clone->path) - goto fail; - } - - if (git_vector_insert(&scb->entries, clone) < 0) - goto fail; - - if (git_iterator_advance(&item, iter) < 0) - goto fail; - } - - git_vector_sort(&scb->entries); - - iter->cb = (git_iterator_callbacks *)scb; - iter->type = GIT_ITERATOR_TYPE_SPOOLANDSORT; - iter->flags ^= GIT_ITERATOR_IGNORE_CASE; - - return 0; - -fail: - spoolandsort_iterator__free_callbacks(scb); - return -1; -} - - void git_iterator_free(git_iterator *iter) { if (iter == NULL) @@ -1130,26 +975,35 @@ void git_iterator_free(git_iterator *iter) git__free(iter); } +int git_iterator_set_ignore_case(git_iterator *iter, bool ignore_case) +{ + bool desire_ignore_case = (ignore_case != 0); + + if (iterator__ignore_case(iter) == desire_ignore_case) + return 0; + + if (iter->type == GIT_ITERATOR_TYPE_EMPTY) { + if (desire_ignore_case) + iter->flags |= GIT_ITERATOR_IGNORE_CASE; + else + iter->flags &= ~GIT_ITERATOR_IGNORE_CASE; + } else { + giterr_set(GITERR_INVALID, + "Cannot currently set ignore case on non-empty iterators"); + return -1; + } + + return 0; +} + git_index *git_iterator_get_index(git_iterator *iter) { if (iter->type == GIT_ITERATOR_TYPE_INDEX) return ((index_iterator *)iter)->index; - if (iter->type == GIT_ITERATOR_TYPE_SPOOLANDSORT && - ((spoolandsort_callbacks *)iter->cb)->orig_type == GIT_ITERATOR_TYPE_INDEX) - return ((index_iterator *)iter)->index; - return NULL; } -git_iterator_type_t git_iterator_inner_type(git_iterator *iter) -{ - if (iter->type == GIT_ITERATOR_TYPE_SPOOLANDSORT) - return ((spoolandsort_callbacks *)iter->cb)->orig_type; - - return iter->type; -} - int git_iterator_current_tree_entry( const git_tree_entry **tree_entry, git_iterator *iter) { @@ -1263,4 +1117,3 @@ int git_iterator_current_workdir_path(git_buf **path, git_iterator *iter) return 0; } - diff --git a/src/iterator.h b/src/iterator.h index feb0c2271..24c7b7765 100644 --- a/src/iterator.h +++ b/src/iterator.h @@ -19,7 +19,6 @@ typedef enum { GIT_ITERATOR_TYPE_TREE = 1, GIT_ITERATOR_TYPE_INDEX = 2, GIT_ITERATOR_TYPE_WORKDIR = 3, - GIT_ITERATOR_TYPE_SPOOLANDSORT = 4 } git_iterator_type_t; typedef enum { @@ -86,14 +85,6 @@ extern int git_iterator_for_workdir( extern void git_iterator_free(git_iterator *iter); -/* Spool all iterator values, resort with alternative ignore_case value - * and replace callbacks with spoolandsort alternates. - */ -extern int git_iterator_spoolandsort_push(git_iterator *iter, bool ignore_case); - -/* Restore original callbacks - not required in most circumstances */ -extern void git_iterator_spoolandsort_pop(git_iterator *iter); - /* Return a git_index_entry structure for the current value the iterator * is looking at or NULL if the iterator is at the end. * @@ -154,6 +145,8 @@ GIT_INLINE(bool) git_iterator_ignore_case(git_iterator *iter) return ((iter->flags & GIT_ITERATOR_IGNORE_CASE) != 0); } +extern int git_iterator_set_ignore_case(git_iterator *iter, bool ignore_case); + extern int git_iterator_current_tree_entry( const git_tree_entry **tree_entry, git_iterator *iter); @@ -196,6 +189,4 @@ extern int git_iterator_current_workdir_path( /* Return index pointer if index iterator, else NULL */ extern git_index *git_iterator_get_index(git_iterator *iter); -extern git_iterator_type_t git_iterator_inner_type(git_iterator *iter); - #endif