Sorry about the lagging replies.  I've had more code review requests than I know what to do with, when you sum up all of the projects that I'm working on.  Some stuff just slips through the cracks, and unfortunately you lost time for it.

I think you are right, most compares don't require that 4th working tree iterator.  But a handful do.  Its probably better to keep that 4th working tree iterator running in parallel so that those compares are cheaper.  Unfortunately, we may wind up doing a stat() of each path to determine if its a file or a directory, and that stat is wasted if you later don't need to look at that particular path name.  However, I would rather the code be correct and easy to follow (it really is a 4-way join) than fast and obtuse.  We can always try to improve the working tree performance later.

WorkDirCheckout predates the WorkingTreeIterator class, so it couldn't use it.  However, it does still have to hit the filesystem to figure out what is going, on and do that 4th join.

Anyway, let me try to reply to [2] in context, rather than here.