Skip to content

Commit ae352c7

Browse files
dturner-twgitster
authored andcommitted
merge-recursive.c: fix case-changing merge bug
On a case-insensitive filesystem, when merging, a file would be wrongly deleted from the working tree if an incoming commit had renamed it changing only its case. When merging a rename, the file with the old name would be deleted -- but since the filesystem considers the old name to be the same as the new name, the new file would in fact be deleted. We avoid this by not deleting files that have a case-clone in the index at stage 0. Signed-off-by: David Turner <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0bc85ab commit ae352c7

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

merge-recursive.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,12 @@ static int remove_file(struct merge_options *o, int clean,
589589
return -1;
590590
}
591591
if (update_working_directory) {
592+
if (ignore_case) {
593+
struct cache_entry *ce;
594+
ce = cache_file_exists(path, strlen(path), ignore_case);
595+
if (ce && ce_stage(ce) == 0)
596+
return 0;
597+
}
592598
if (remove_path(path))
593599
return -1;
594600
}

t/t6039-merge-ignorecase.sh

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/bin/sh
2+
3+
test_description='git-merge with case-changing rename on case-insensitive file system'
4+
5+
. ./test-lib.sh
6+
7+
if ! test_have_prereq CASE_INSENSITIVE_FS
8+
then
9+
skip_all='skipping case insensitive tests - case sensitive file system'
10+
test_done
11+
fi
12+
13+
test_expect_success 'merge with case-changing rename' '
14+
test $(git config core.ignorecase) = true &&
15+
>TestCase &&
16+
git add TestCase &&
17+
git commit -m "add TestCase" &&
18+
git tag baseline
19+
git checkout -b with-camel &&
20+
>foo &&
21+
git add foo &&
22+
git commit -m "intervening commit" &&
23+
git checkout master &&
24+
git rm TestCase &&
25+
>testcase &&
26+
git add testcase &&
27+
git commit -m "rename to testcase" &&
28+
git checkout with-camel &&
29+
git merge master -m "merge" &&
30+
test_path_is_file testcase
31+
'
32+
33+
test_expect_success 'merge with case-changing rename on both sides' '
34+
git checkout master &&
35+
git reset --hard baseline &&
36+
git branch -D with-camel &&
37+
git checkout -b with-camel &&
38+
git mv --force TestCase testcase &&
39+
git commit -m "recase on branch" &&
40+
>foo &&
41+
git add foo &&
42+
git commit -m "intervening commit" &&
43+
git checkout master &&
44+
git rm TestCase &&
45+
>testcase &&
46+
git add testcase &&
47+
git commit -m "rename to testcase" &&
48+
git checkout with-camel &&
49+
git merge master -m "merge" &&
50+
test_path_is_file testcase
51+
'
52+
53+
test_done

0 commit comments

Comments
 (0)