Re: [PATCH] diffcore: fix iteration order of identical files during rename detection
From: Junio C Hamano <hidden>
Date: 2016-06-15 23:09:07
SZEDER Gábor [off-list ref] writes:
Fill the hashmap with source entries in reverse order to restore the original exact rename detection behavior.
Thanks for digging out and fixing this unintended regression that happened long time ago. Will queue.
quoted hunk
Reported-by: Bill Okara <redacted> Signed-off-by: SZEDER Gábor <redacted> --- Resend of the patch, with a slightly updated commit message, included in http://thread.gmane.org/gmane.comp.version-control.git/287281/focus=287570 Being embedded with scissors in an email without Junio among the recipients on the day the first -rc was tagged... no wonder it flew below the radar. diffcore-rename.c | 6 ++++-- t/t4001-diff-rename.sh | 11 +++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-)diff --git a/diffcore-rename.c b/diffcore-rename.c index 3b3c1ed535e7..7f03eb5a0404 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c@@ -340,9 +340,11 @@ static int find_exact_renames(struct diff_options *options) int i, renames = 0; struct hashmap file_table; - /* Add all sources to the hash table */ + /* Add all sources to the hash table in reverse order, because + * later on they will be retrieved in LIFO order. + */ hashmap_init(&file_table, NULL, rename_src_nr); - for (i = 0; i < rename_src_nr; i++) + for (i = rename_src_nr-1; i >= 0; i--) insert_file_table(&file_table, i, rename_src[i].p->one); /* Walk the destinations and find best source match */diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh index 2f327b749588..ed90c6c6f984 100755 --- a/t/t4001-diff-rename.sh +++ b/t/t4001-diff-rename.sh@@ -77,6 +77,17 @@ test_expect_success 'favour same basenames even with minor differences' ' git show HEAD:path1 | sed "s/15/16/" > subdir/path1 && git status | test_i18ngrep "renamed: .*path1 -> subdir/path1"' +test_expect_success 'two files with same basename and same content' ' + git reset --hard && + mkdir -p dir/A dir/B && + cp path1 dir/A/file && + cp path1 dir/B/file && + git add dir && + git commit -m 2 && + git mv dir other-dir && + git status | test_i18ngrep "renamed: .*dir/A/file -> other-dir/A/file" +' + test_expect_success 'setup for many rename source candidates' ' git reset --hard && for i in 0 1 2 3 4 5 6 7 8 9;