traverse_trees(): handle D/F conflict case sanely
authorJunio C Hamano <gitster@pobox.com>
Sat, 19 Sep 2009 21:07:14 +0000 (14:07 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 4 Jan 2010 07:21:32 +0000 (23:21 -0800)
commit1ee26571e97c64bccecfd26d1a1c1c631412a1b7
tree43d9288921970f36ac079f824857e34291b8d9f3
parent934f930b3144d03cacd16bc5117ef2afe3b1d04d
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