libgit2/libgit2 — pull request #1408 by arrbee (2013-03-11 19:03:44+00:00)
Title: Refactor iterators

This PR is an alternative to #1326 and #1377.

There are three main things in this PR:

1. Update the internal iterator APIs to use libgit2 standard ordering for parameters, etc. and make them have the same behavior across all types of iterators (previous workdir iterators behaved differently).
2. Extend the iterator APIs with two new flags: `GIT_ITERATOR_INCLUDE_TREES` to include tree entries in the output, and `GIT_ITERATOR_DONT_AUTOEXPAND` to require an explicit `advance_into()` call for iteration to return the contents of tree entries.
3. Fix the tree iterator when case-insensitive ordering is used, so that multiple entries which case-fold on top of one another are properly blended (i.e. "A/B/1", "A/B/3", "a/b/2" should iterate as "A/B/1", "a/b/2", "A/B/3" when case insensitive iteration is on).

Why would we want each change? Well, 1 makes the APIs easier to use because they are consistent, and 3 fixes a bug with the tree iterator. 2 is part of making the iterators behave consistently (because workdir used to behave as if those flags were set), and it also lays the groundwork for cleaner diff and checkout code in the future (regarding TYPECHANGE records and efficiently skipping trees that are known to match exactly).

This PR includes a number of other small housekeeping changes that I think are all for the best.

* Add `const` to some `git_buf` functions and improve `git_buf_find()`
* Add `git__qsort_r()` to officially wrap `qsort()` in a portable manner. This isolates the crappy CDECL stuff that I had to put into hashsig. (I did this because I needed a sort function for the case-insensitive tree iterator frames.)
* Remove minimally useful iterator helper functions
* Remove the spoolandsort iterator since it is not used
* Remove unused and broken `git_index_read_tree_match` (from old checkout code)

There are a bunch of tests for the new behavior in a new test file `tests-clar/repo/iterator.c` which is dedicated to just testing the iterators in isolation as opposed to within the framework of testing diffs.