intersect_paths: respect mode in git's tree-sort
commite09867f0605702c2d4e65b99e178cdaa215a7370
authorJeff King <peff@peff.net>
Wed, 20 Aug 2014 02:14:30 +0000 (19 22:14 -0400)
committerJunio C Hamano <gitster@pobox.com>
Wed, 20 Aug 2014 20:38:37 +0000 (20 13:38 -0700)
tree8e4d20014a8be2fbe2d4e7c0c4b094713df89369
parentfce135c4ffc87f85e1c3b5c57a6d9e1abdbd074d
intersect_paths: respect mode in git's tree-sort

When we do a combined diff, we individually diff against
each parent, and then use intersect_paths to do a parallel
walk through the sorted results and come up with a final
list of interesting paths.

The sort order here is that returned by the diffs, which
means it is in git's tree-order which sorts sub-trees as if
their paths have "/" at the end. When we do our parallel
walk, we need to use a comparison function which provides
the same order.

Since 8518ff8 (combine-diff: optimize combine_diff_path sets
intersection, 2014-01-20), we use a simple strcmp to
compare the pathnames, and get this wrong. It's somewhat
hard to trigger because normally a diff does not produce
tree entries at all, and therefore the sort order is the
same as a strcmp. However, if the "-t" option is used with
the diff, then we will produce diff_filepairs for both trees
and files.

We can use base_name_compare to do the comparison, just as
the tree-diff code does. Even though what we have are not
technically base names (they are full paths within the
tree), the end result is the same (we do not care about
interior slashes at all, only about the final character).

However, since we do not have the length of each path
stored, we take a slight shortcut: if neither of the entries
is a sub-tree then the comparison is equivalent to a strcmp.
This lets us skip the extra strlen calls in the common case
without having to reimplement base_name_compare from
scratch.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
combine-diff.c
t/t4038-diff-combined.sh