diff options
author | Russell Belfer <rb@github.com> | 2012-12-27 22:25:52 -0800 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2012-12-27 22:25:52 -0800 |
commit | f616a36bdd9b1a0f26f399414bbccb434595edff (patch) | |
tree | 43094256b9615370e3a7945932601c0671117933 /src/diff.c | |
parent | 83261a449f76147c1ebb3ebe592821f7d69bb6f6 (diff) | |
download | libgit2-f616a36bdd9b1a0f26f399414bbccb434595edff.tar.gz |
Make spoolandsort a pushable iterator behavior
An earlier change to `git_diff_from_iterators` introduced a
memory leak where the allocated spoolandsort iterator was not
returned to the caller and thus not freed.
One proposal changes all iterator APIs to use git_iterator** so
we can reallocate the iterator at will, but that seems unexpected.
This commit makes it so that an iterator can be changed in place.
The callbacks are isolated in a separate structure and a pointer
to that structure can be reassigned by the spoolandsort extension.
This means that spoolandsort doesn't create a new iterator; it
just allocates a new block of callbacks (along with space for its
own extra data) and swaps that into the iterator.
Additionally, since spoolandsort is only needed to switch the
case sensitivity of an iterator, this simplifies the API to only
take the ignore_case boolean and to be a no-op if the iterator
already matches the requested case sensitivity.
Diffstat (limited to 'src/diff.c')
-rw-r--r-- | src/diff.c | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/src/diff.c b/src/diff.c index 9c0b45f8e..83e73cd03 100644 --- a/src/diff.c +++ b/src/diff.c @@ -589,18 +589,13 @@ int git_diff__from_iterators( goto fail; if (diff->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) { - /* If one of the iterators doesn't have ignore_case set, - * then that's unfortunate because we'll have to spool - * its data, sort it icase, and then use that for our - * merge join to the other iterator that is icase sorted */ - if (!old_iter->ignore_case && - git_iterator_spoolandsort( - &old_iter, old_iter, diff->entrycomp, true) < 0) - goto fail; - - if (!new_iter->ignore_case && - git_iterator_spoolandsort( - &new_iter, new_iter, diff->entrycomp, true) < 0) + /* 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) goto fail; } |