diff options
author | Jeff King <peff@peff.net> | 2012-03-22 14:53:49 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2012-03-22 14:53:37 -0700 |
commit | 536caca5ce0d88e4c54e9e7376ed182807702c58 (patch) | |
tree | db0bda3b2815049ce7c015344341245ad10cbf57 | |
parent | 480dd8b8365406bfa47fed87ed59ca5df672e716 (diff) | |
download | git-jk/maint-1.7.7-merge-recursive-no-rename-empty.tar.gz |
merge-recursive: don't detect renames from empty filesjk/maint-1.7.7-merge-recursive-no-rename-empty
Merge-recursive detects renames so that if one side modifies
"foo" and the other side moves it to "bar", the modification
is applied to "bar". However, our rename detection is based
on content analysis, it can be wrong (i.e., two files were
not intended as a rename, but just happen to have the same
or similar content).
This is quite rare if the files actually contain content,
since two unrelated files are unlikely to have exactly the
same content. However, empty files present a problem, in
that there is nothing to analyze. An uninteresting
placeholder file with zero bytes may or may not be related
to a placeholder file with another name.
The result is that adding content to an empty file may cause
confusion if the other side of a merge removed it; your
content may end up in another random placeholder file that
was added.
Let's err on the side of caution and not consider empty
files as renames. This will cause a modify/delete conflict
on the merge, which will let the user sort it out
themselves.
We could do the same thing for general diff rename
detection. However, the stakes are much less high there, as
we are explicitly reporting the rename to the user. It's
only the automatic nature of merge-recursive that makes the
result confusing. So there's not as much need for caution
when just showing a diff.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | merge-recursive.c | 2 | ||||
-rwxr-xr-x | t/t6022-merge-rename.sh | 16 |
2 files changed, 17 insertions, 1 deletions
diff --git a/merge-recursive.c b/merge-recursive.c index 5e2bc4fbd2..833b65536f 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -503,7 +503,7 @@ static struct string_list *get_renames(struct merge_options *o, struct string_list_item *item; struct rename *re; struct diff_filepair *pair = diff_queued_diff.queue[i]; - if (pair->status != 'R') { + if (pair->status != 'R' || is_empty_blob_sha1(pair->one->sha1)) { diff_free_filepair(pair); continue; } diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index 9d8584e957..1104249182 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -884,4 +884,20 @@ test_expect_success 'no spurious "refusing to lose untracked" message' ' ! grep "refusing to lose untracked file" errors.txt ' +test_expect_success 'do not follow renames for empty files' ' + git checkout -f -b empty-base && + >empty1 && + git add empty1 && + git commit -m base && + echo content >empty1 && + git add empty1 && + git commit -m fill && + git checkout -b empty-topic HEAD^ && + git mv empty1 empty2 && + git commit -m rename && + test_must_fail git merge empty-base && + >expect && + test_cmp expect empty2 +' + test_done |