merge-ort: ensure we consult df_conflict and path_conflicts

Path conflicts (typically rename path conflicts, e.g. rename/rename(1to2) or rename/add/delete), and directory/file conflicts should obviously result in files not being marked as clean in the merge. We had a codepath where we missed consulting the path_conflict and df_conflict flags, based on match_mask. Granted, it requires an unusual setup to trigger this codepath (directory rename causing rename-to-self is the only case I can think of), but we still need to handle it. To make it clear that we have audited the other codepaths that do not explicitly mention these flags, add some assertions that the flags are not set. Reported-by: Anders Kaseorg <andersk@mit.edu> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Jun 30, 2021 at 17:29 UTC a492d5331cb93d8293e72741b4fb9e1ec4ff294b
2 files changed +8 -4
merge-ort.c
+5 -1
@@ -3002,7 +3002,7 @@ static void process_entry(struct merge_options *opt,
3002 * above.
3003 */
3004 if (ci->match_mask) {
3005 - ci->merged.clean = 1;
3005 + ci->merged.clean = !ci->df_conflict && !ci->path_conflict;
3006 if (ci->match_mask == 6) {
3007 /* stages[1] == stages[2] */
3008 ci->merged.result.mode = ci->stages[1].mode;
@@ -3014,6 +3014,8 @@ static void process_entry(struct merge_options *opt,
3014
3015 ci->merged.result.mode = ci->stages[side].mode;
3016 ci->merged.is_null = !ci->merged.result.mode;
3017 + if (ci->merged.is_null)
3018 + ci->merged.clean = 1;
3019 oidcpy(&ci->merged.result.oid, &ci->stages[side].oid);
3020
3021 assert(othermask == 2 || othermask == 4);
@@ -3186,6 +3188,7 @@ static void process_entry(struct merge_options *opt,
3188 path)) {
3189 ci->merged.is_null = 1;
3190 ci->merged.clean = 1;
3191 + assert(!ci->df_conflict && !ci->path_conflict);
3192 } else if (ci->path_conflict &&
3193 oideq(&ci->stages[0].oid, &ci->stages[side].oid)) {
3194 /*
@@ -3212,6 +3215,7 @@ static void process_entry(struct merge_options *opt,
3215 ci->merged.is_null = 1;
3216 ci->merged.result.mode = 0;
3217 oidcpy(&ci->merged.result.oid, null_oid());
3218 + assert(!ci->df_conflict);
3219 ci->merged.clean = !ci->path_conflict;
3220 }
3221
t/t6423-merge-rename-directories.sh
+3 -3
@@ -5000,7 +5000,7 @@ test_setup_12i () {
5000 )
5001 }
5002
5003 -test_expect_merge_algorithm failure failure '12i: Directory rename causes rename-to-self' '
5003 +test_expect_merge_algorithm failure success '12i: Directory rename causes rename-to-self' '
5004 test_setup_12i &&
5005 (
5006 cd 12i &&
@@ -5058,7 +5058,7 @@ test_setup_12j () {
5058 )
5059 }
5060
5061 -test_expect_merge_algorithm failure failure '12j: Directory rename to root causes rename-to-self' '
5061 +test_expect_merge_algorithm failure success '12j: Directory rename to root causes rename-to-self' '
5062 test_setup_12j &&
5063 (
5064 cd 12j &&
@@ -5116,7 +5116,7 @@ test_setup_12k () {
5116 )
5117 }
5118
5119 -test_expect_merge_algorithm failure failure '12k: Directory rename with sibling causes rename-to-self' '
5119 +test_expect_merge_algorithm failure success '12k: Directory rename with sibling causes rename-to-self' '
5120 test_setup_12k &&
5121 (
5122 cd 12k &&