diff options
-rw-r--r-- | merge-recursive.c | 32 | ||||
-rwxr-xr-x | t/t6036-recursive-corner-cases.sh | 8 |
2 files changed, 35 insertions, 5 deletions
diff --git a/merge-recursive.c b/merge-recursive.c index 8a47e54e2f..73b5710386 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -228,7 +228,26 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type, struct stage_data *src_entry1, struct stage_data *src_entry2) { - struct rename_conflict_info *ci = xcalloc(1, sizeof(struct rename_conflict_info)); + struct rename_conflict_info *ci; + + /* + * When we have two renames involved, it's easiest to get the + * correct things into stage 2 and 3, and to make sure that the + * content merge puts HEAD before the other branch if we just + * ensure that branch1 == o->branch1. So, simply flip arguments + * around if we don't have that. + */ + if (dst_entry2 && branch1 != o->branch1) { + setup_rename_conflict_info(rename_type, + pair2, pair1, + branch2, branch1, + dst_entry2, dst_entry1, + o, + src_entry2, src_entry1); + return; + } + + ci = xcalloc(1, sizeof(struct rename_conflict_info)); ci->rename_type = rename_type; ci->pair1 = pair1; ci->branch1 = branch1; @@ -1283,6 +1302,17 @@ static int merge_mode_and_contents(struct merge_options *o, const char *branch2, struct merge_file_info *result) { + if (o->branch1 != branch1) { + /* + * It's weird getting a reverse merge with HEAD on the bottom + * side of the conflict markers and the other branch on the + * top. Fix that. + */ + return merge_mode_and_contents(o, one, b, a, + filename, + branch2, branch1, result); + } + result->merge = 0; result->clean = 1; diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh index 59e52c5a09..e1cef58f2a 100755 --- a/t/t6036-recursive-corner-cases.sh +++ b/t/t6036-recursive-corner-cases.sh @@ -230,13 +230,13 @@ test_expect_success 'git detects differently handled merges conflict' ' :2:new_a :3:new_a && test_cmp expect actual && - git cat-file -p B:new_a >ours && - git cat-file -p C:new_a >theirs && + git cat-file -p C:new_a >ours && + git cat-file -p B:new_a >theirs && >empty && test_must_fail git merge-file \ - -L "Temporary merge branch 2" \ - -L "" \ -L "Temporary merge branch 1" \ + -L "" \ + -L "Temporary merge branch 2" \ ours empty theirs && sed -e "s/^\([<=>]\)/\1\1\1/" ours >expect && git cat-file -p :1:new_a >actual && |