merge-recursive: Provide more info in conflict markers with file renames

Whenever there are merge conflicts in file contents, we would mark the
different sides of the conflict with the two branches being merged.
However, when there is a rename involved as well, the branchname is not
sufficient to specify where the conflicting content came from.  In such
cases, mark the two sides of the conflict with branchname:filename rather
than just branchname.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Elijah Newren 2011-08-11 23:20:09 -06:00 коммит произвёл Junio C Hamano
Родитель 4f66dade81
Коммит 3c217c077a
3 изменённых файлов: 97 добавлений и 8 удалений

Просмотреть файл

@ -1353,6 +1353,7 @@ static int merge_content(struct merge_options *o,
struct rename_conflict_info *rename_conflict_info)
{
const char *reason = "content";
char *side1 = NULL, *side2 = NULL;
struct merge_file_info mfi;
struct diff_filespec one, a, b;
unsigned df_conflict_remains = 0;
@ -1369,10 +1370,31 @@ static int merge_content(struct merge_options *o,
hashcpy(b.sha1, b_sha);
b.mode = b_mode;
mfi = merge_file(o, &one, &a, &b, o->branch1, o->branch2);
if (rename_conflict_info && dir_in_way(path, !o->call_depth)) {
df_conflict_remains = 1;
if (rename_conflict_info) {
const char *path1, *path2;
struct diff_filepair *pair1 = rename_conflict_info->pair1;
path1 = (o->branch1 == rename_conflict_info->branch1) ?
pair1->two->path : pair1->one->path;
/* If rename_conflict_info->pair2 != NULL, we are in
* RENAME_ONE_FILE_TO_ONE case. Otherwise, we have a
* normal rename.
*/
path2 = (rename_conflict_info->pair2 ||
o->branch2 == rename_conflict_info->branch1) ?
pair1->two->path : pair1->one->path;
side1 = xmalloc(strlen(o->branch1) + strlen(path1) + 2);
side2 = xmalloc(strlen(o->branch2) + strlen(path2) + 2);
sprintf(side1, "%s:%s", o->branch1, path1);
sprintf(side2, "%s:%s", o->branch2, path2);
if (dir_in_way(path, !o->call_depth))
df_conflict_remains = 1;
}
mfi = merge_file(o, &one, &a, &b,
side1 ? side1 : o->branch1, side2 ? side2 : o->branch2);
free(side1);
free(side2);
if (mfi.clean && !df_conflict_remains &&
sha_eq(mfi.sha, a_sha) && mfi.mode == a.mode)

Просмотреть файл

@ -351,11 +351,11 @@ cat >expected <<\EOF &&
8
9
10
<<<<<<< HEAD
<<<<<<< HEAD:dir
12
=======
11
>>>>>>> dir-not-in-way
>>>>>>> dir-not-in-way:sub/file
EOF
test_expect_success 'Rename+D/F conflict; renamed file cannot merge, dir not in way' '
@ -405,11 +405,11 @@ cat >expected <<\EOF &&
8
9
10
<<<<<<< HEAD
<<<<<<< HEAD:sub/file
11
=======
12
>>>>>>> renamed-file-has-conflicts
>>>>>>> renamed-file-has-conflicts:dir
EOF
test_expect_success 'Same as previous, but merged other way' '
@ -700,4 +700,71 @@ test_expect_success 'merge rename + small change' '
test $(git rev-parse HEAD:renamed_file) = $(git rev-parse HEAD~1:file)
'
test_expect_success 'setup for use of extended merge markers' '
git rm -rf . &&
git clean -fdqx &&
rm -rf .git &&
git init &&
printf "1\n2\n3\n4\n5\n6\n7\n8\n" >original_file &&
git add original_file &&
git commit -mA &&
git checkout -b rename &&
echo 9 >>original_file &&
git add original_file &&
git mv original_file renamed_file &&
git commit -mB &&
git checkout master &&
echo 8.5 >>original_file &&
git add original_file &&
git commit -mC
'
cat >expected <<\EOF &&
1
2
3
4
5
6
7
8
<<<<<<< HEAD:renamed_file
9
=======
8.5
>>>>>>> master^0:original_file
EOF
test_expect_success 'merge master into rename has correct extended markers' '
git checkout rename^0 &&
test_must_fail git merge -s recursive master^0 &&
test_cmp expected renamed_file
'
cat >expected <<\EOF &&
1
2
3
4
5
6
7
8
<<<<<<< HEAD:original_file
8.5
=======
9
>>>>>>> rename^0:renamed_file
EOF
test_expect_success 'merge rename into master has correct extended markers' '
git reset --hard &&
git checkout master^0 &&
test_must_fail git merge -s recursive rename^0 &&
test_cmp expected renamed_file
'
test_done

Просмотреть файл

@ -258,7 +258,7 @@ test_expect_success 'rename/directory conflict + clean content merge' '
test -f newfile~HEAD
'
test_expect_failure 'rename/directory conflict + content merge conflict' '
test_expect_success 'rename/directory conflict + content merge conflict' '
git reset --hard &&
git reset --hard &&
git clean -fdqx &&