Skip to content

diff_tform: fix rename detection with rewrite/delete pair#4539

Merged
ethomson merged 3 commits into
libgit2:masterfrom
pks-t:pks/diff_renames_with_rewrites
Feb 20, 2018
Merged

diff_tform: fix rename detection with rewrite/delete pair#4539
ethomson merged 3 commits into
libgit2:masterfrom
pks-t:pks/diff_renames_with_rewrites

Conversation

@pks-t
Copy link
Copy Markdown
Member

@pks-t pks-t commented Feb 20, 2018

A rewritten file can either be classified as a modification of its
contents or of a delete of the complete file followed by an addition of
the new content. This distinction becomes important when we want to
detect renames for rewrites. Given a scenario where a file "a" has been
deleted and another file "b" has been renamed to "a", this should be
detected as a deletion of "a" followed by a rename of "a" -> "b". Thus,
splitting of the original rewrite into a delete/add pair is important
here.

This splitting is represented by a flag we can set at the current delta.
While the flag is already being set in case we want to break rewrites,
we do not do so in case where the GIT_DIFF_FIND_RENAMES_FROM_REWRITES
flag is set. This can trigger an assert when we try to match the source
and target deltas.

Fix the issue by setting the GIT_DIFF_FLAG__TO_SPLIT flag at the delta
when it is a rename target and GIT_DIFF_FIND_RENAMES_FROM_REWRITES is
set.


As this fixes hitting an assert, we should definitly include this in v0.27.0. So I will hold off v0.27.0-rc1 until this is merged.

While we frequently reuse commit OIDs throughout the file, we do not
have any constants to refer to these commits. Make this a bit easier to
read by giving the commit OIDs somewhat descriptive names of what kind
of commit they refer to.
Add two more scenarios to the "renames" repository. The first scenario
has a major rewrite of a file and a delete of another file, the second
scenario has a deletion of a file and rename of another file to the
deleted file. Both scenarios will be used in the following commit.
A rewritten file can either be classified as a modification of its
contents or of a delete of the complete file followed by an addition of
the new content. This distinction becomes important when we want to
detect renames for rewrites. Given a scenario where a file "a" has been
deleted and another file "b" has been renamed to "a", this should be
detected as a deletion of "a" followed by a rename of "a" -> "b". Thus,
splitting of the original rewrite into a delete/add pair is important
here.

This splitting is represented by a flag we can set at the current delta.
While the flag is already being set in case we want to break rewrites,
we do not do so in case where the `GIT_DIFF_FIND_RENAMES_FROM_REWRITES`
flag is set. This can trigger an assert when we try to match the source
and target deltas.

Fix the issue by setting the `GIT_DIFF_FLAG__TO_SPLIT` flag at the delta
when it is a rename target and `GIT_DIFF_FIND_RENAMES_FROM_REWRITES` is
set.
@pks-t pks-t added the backport label Feb 20, 2018
@ethomson
Copy link
Copy Markdown
Member

I'll wait for the CI to finish in case there's some subtlety, but this looks good to me.

@pks-t
Copy link
Copy Markdown
Member Author

pks-t commented Feb 20, 2018

Fixes #4538

@ethomson ethomson merged commit afc5124 into libgit2:master Feb 20, 2018
@pks-t pks-t mentioned this pull request Feb 20, 2018
@wchargin
Copy link
Copy Markdown

Thanks for investigating and fixing!

@pks-t pks-t deleted the pks/diff_renames_with_rewrites branch July 11, 2019 19:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants