libgit2/libgit2 — pull request #1659 by arrbee (2013-06-18 23:25:22+00:00)
Title: Diff rename detection cycle fixes

As @ethomson has pointed out in #1656, diff rename detection has problems when you introduce a cycle of renames (a->b, b->c, c->a) because processing the earlier rename of a->b would alter the diff records so that when it was time process b->c, the b record was no longer the appropriate match.

Instead of making huge changes, this PR fixes this by tweaking a few details:

1. When looking for the closest match to a given record, if we displace an earlier located match, then note that we "bumped" a record and repeat the initial phase of finding closest matches until no records get bumped.
2. When updating records in place, always make the target record into the RENAME record (i.e. make this a true reverse mapping, even for data updates) so we always preserve records that are sources if possible.
3. If we are forced to overwrite a source record (which now only happens when we have two split MODIFIED records), update the best match mappings to point the unprocessed mapping at the new record location.

This PR includes @ethomson's previously failing tests from #1656 and contains my fixes for the issue. Hopefully he will look this over and give it his blessing.