traverse_trees(): handle D/F conflict case sanely
commit5adde4cb0384bc9c24f07cdb9956b5b4148dd8b0
authorJunio C Hamano <gitster@pobox.com>
Sat, 19 Sep 2009 21:07:14 +0000 (19 14:07 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Tue, 29 Sep 2009 17:06:47 +0000 (29 10:06 -0700)
treee90034048f8a029bb33c077c47bbb771ccc3e53d
parentb03068bb8c5e2f82a3b632564fa5ec61c80adf75
traverse_trees(): handle D/F conflict case sanely

traverse_trees() is supposed to call its callback with all the matching
entries from the given trees.  The current algorithm keeps a pointer to
each of the tree being traversed, and feeds the entry with the earliest
name to the callback.

This breaks down if the trees being traversed looks like this:

    A    B
    t-1  t
    t-2  u
    t/a  v

When we are currently looking at an entry "t-1" in tree A, and tree B has
returned "t", feeding "t" from the B and not feeding anything from A, only
because "t-1" sorts later than "t", will miss an entry for a subtree "t"
behind the current entry in tree A.

This introduces extended_entry_extract() helper function that gives what
name is expected from the tree, and implements a mechanism to look-ahead
in the tree object using it, to make sure such a case is handled sanely.
Traversal in tree A in the above example will first return "t" to match
that of B, and then the next request for an entry to A then returns "t-1".

This roughly corresponds to what Linus's "prepare for one-entry lookahead"
wanted to do, but because this does implement look ahead, t6035 and one more
test in t1012 reveal that the approach would not work without adjusting the
side that walks the index in unpack_trees() as well.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/t1012-read-tree-df.sh
t/t6035-merge-dir-to-symlink.sh
tree-walk.c