Yes, I've had some discussion about this, but I'd be happy to talk through it again and change things if we can agree on an alternative.

These iterators were written in service of the diff and status code and that code needs to be able to iterate over two (or more) iterators in parallel, only optionally advancing the ones that are actually processed by the diff (i.e. when you have an added or deleted entry, only one of the iterators should advance).

With the file system iterator (or actually, the workdir iterator), the decision to advance *into* a directory is made based on whether the other iterator (the index or tree one) has an item that is contained in the directory. The iterator API distinguishes between advancing over and advancing into (although right now that is only used for the workdir iterators in the diff code). If getting the current value of the filesystem iterator had already advanced past the directory (or into the directory), then it would be too late to do the right thing.

Also, there are a few iterator calls that are only meaningful for specific types of iterators which operate on the current position of the iterator and it is important that we haven't advanced past it. Notably, the `is_ignored` check for workdir iterators is actually deferred until we are sure we need to know (e.g. for a tracked item, there is no need to evaluate the ignore rules). So, even after we have looked up the "current" workdir item, we still want to call `git_iterator_current_is_ignored()` on it. That could be turned into a `git_iterator_last_item_was_ignored()` call, but the implementation would potentially get quite tricky if advancing had traversed into a directory hierarchy, for example.

Regarding `GIT_ITEROVER` to indicate the end of iteration, I think at the time this code was written, that error was only being used in revwalk and I just overlooked it. That can (and should) be changed, I think.

I have two other thoughts on options that could make this easier:

1. We can add a `git_iterator_next()` API that internally just calls `git_iterator_current(&entry, iter)` and `git_iterator_advance(NULL, iter)` for you. That would be a minimal change and it would make this feel more like other iterators.
2. I can modify the iterators so that calling `git_iterator_advance` on an iterator that has never had the current value looked up actually "advances" you to the first value. I don't really want to convert advance from the current `++value` into a `value++` behavior because that involves rewriting a lot of code, but I could at least make it so that the first `++value` call actually takes you to the first result which would simplify the loop structure.

What do you think about those options?

I do also think that an error should either a) automatically move the iterator to the end or b) automatically advance past the item that generated the error so you can continue to iterate if you choose.