From: Junio C Hamano Date: Wed, 13 Apr 2016 21:12:32 +0000 (-0700) Subject: Merge branch 'sg/diff-multiple-identical-renames' X-Git-Tag: v2.9.0-rc0~130 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/26effb8487386e431990905d4eba7e81f1018eda?ds=inline;hp=-c Merge branch 'sg/diff-multiple-identical-renames' "git diff -M" used to work better when two originally identical files A and B got renamed to X/A and X/B by pairing A to X/A and B to X/B, but this was broken in the 2.0 timeframe. * sg/diff-multiple-identical-renames: diffcore: fix iteration order of identical files during rename detection --- 26effb8487386e431990905d4eba7e81f1018eda diff --combined diffcore-rename.c index 3b3c1ed535,69fcf77be0..7f03eb5a04 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@@ -340,9 -340,11 +340,11 @@@ static int find_exact_renames(struct di 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 */ @@@ -537,7 -539,7 +539,7 @@@ void diffcore_rename(struct diff_option rename_dst_nr * rename_src_nr, 50, 1); } - mx = xcalloc(num_create * NUM_CANDIDATE_PER_DST, sizeof(*mx)); + mx = xcalloc(st_mult(num_create, NUM_CANDIDATE_PER_DST), sizeof(*mx)); for (dst_cnt = i = 0; i < rename_dst_nr; i++) { struct diff_filespec *two = rename_dst[i].two; struct diff_score *m; diff --combined t/t4001-diff-rename.sh index c7e58b69a9,ed90c6c6f9..0d1fa45d25 --- a/t/t4001-diff-rename.sh +++ b/t/t4001-diff-rename.sh @@@ -9,84 -9,21 +9,84 @@@ test_description='Test rename detectio . ./test-lib.sh . "$TEST_DIRECTORY"/diff-lib.sh -echo >path0 'Line 1 -Line 2 -Line 3 -Line 4 -Line 5 -Line 6 -Line 7 -Line 8 -Line 9 -Line 10 -line 11 -Line 12 -Line 13 -Line 14 -Line 15 +test_expect_success 'setup' ' + cat >path0 <<-\EOF && + Line 1 + Line 2 + Line 3 + Line 4 + Line 5 + Line 6 + Line 7 + Line 8 + Line 9 + Line 10 + line 11 + Line 12 + Line 13 + Line 14 + Line 15 + EOF + cat >expected <<-\EOF && + diff --git a/path0 b/path1 + rename from path0 + rename to path1 + --- a/path0 + +++ b/path1 + @@ -8,7 +8,7 @@ Line 7 + Line 8 + Line 9 + Line 10 + -line 11 + +Line 11 + Line 12 + Line 13 + Line 14 + EOF + cat >no-rename <<-\EOF + diff --git a/path0 b/path0 + deleted file mode 100644 + index fdbec44..0000000 + --- a/path0 + +++ /dev/null + @@ -1,15 +0,0 @@ + -Line 1 + -Line 2 + -Line 3 + -Line 4 + -Line 5 + -Line 6 + -Line 7 + -Line 8 + -Line 9 + -Line 10 + -line 11 + -Line 12 + -Line 13 + -Line 14 + -Line 15 + diff --git a/path1 b/path1 + new file mode 100644 + index 0000000..752c50e + --- /dev/null + +++ b/path1 + @@ -0,0 +1,15 @@ + +Line 1 + +Line 2 + +Line 3 + +Line 4 + +Line 5 + +Line 6 + +Line 7 + +Line 8 + +Line 9 + +Line 10 + +Line 11 + +Line 12 + +Line 13 + +Line 14 + +Line 15 + EOF ' test_expect_success \ @@@ -106,27 -43,27 +106,27 @@@ test_expect_success test_expect_success \ 'git diff-index -p -M after rename and editing.' \ 'git diff-index -p -M $tree >current' -cat >expected <<\EOF -diff --git a/path0 b/path1 -rename from path0 -rename to path1 ---- a/path0 -+++ b/path1 -@@ -8,7 +8,7 @@ Line 7 - Line 8 - Line 9 - Line 10 --line 11 -+Line 11 - Line 12 - Line 13 - Line 14 -EOF + test_expect_success \ 'validate the output.' \ 'compare_diff_patch current expected' +test_expect_success 'test diff.renames=true' ' + git -c diff.renames=true diff --cached $tree >current && + compare_diff_patch current expected +' + +test_expect_success 'test diff.renames=false' ' + git -c diff.renames=false diff --cached $tree >current && + compare_diff_patch current no-rename +' + +test_expect_success 'test diff.renames unset' ' + git diff --cached $tree >current && + compare_diff_patch current expected +' + test_expect_success 'favour same basenames over different ones' ' cp path1 another-path && git add another-path && @@@ -140,6 -77,17 +140,17 @@@ test_expect_success 'favour same basena 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;