]> git.ipfire.org Git - thirdparty/git.git/commitdiff
merge-ort: ensure we consult df_conflict and path_conflicts
authorElijah Newren <newren@gmail.com>
Wed, 30 Jun 2021 17:29:59 +0000 (17:29 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 30 Jun 2021 21:40:10 +0000 (14:40 -0700)
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>
merge-ort.c
t/t6423-merge-rename-directories.sh

index 4a9ce2a822bd617b0a6766b55f4a5b929b21823d..8b0f2448f0fe1b1248ff970f5fee5eab5ff86780 100644 (file)
@@ -3002,7 +3002,7 @@ static void process_entry(struct merge_options *opt,
         *       above.
         */
        if (ci->match_mask) {
-               ci->merged.clean = 1;
+               ci->merged.clean = !ci->df_conflict && !ci->path_conflict;
                if (ci->match_mask == 6) {
                        /* stages[1] == stages[2] */
                        ci->merged.result.mode = ci->stages[1].mode;
@@ -3014,6 +3014,8 @@ static void process_entry(struct merge_options *opt,
 
                        ci->merged.result.mode = ci->stages[side].mode;
                        ci->merged.is_null = !ci->merged.result.mode;
+                       if (ci->merged.is_null)
+                               ci->merged.clean = 1;
                        oidcpy(&ci->merged.result.oid, &ci->stages[side].oid);
 
                        assert(othermask == 2 || othermask == 4);
@@ -3186,6 +3188,7 @@ static void process_entry(struct merge_options *opt,
                                   path)) {
                        ci->merged.is_null = 1;
                        ci->merged.clean = 1;
+                       assert(!ci->df_conflict && !ci->path_conflict);
                } else if (ci->path_conflict &&
                           oideq(&ci->stages[0].oid, &ci->stages[side].oid)) {
                        /*
@@ -3212,6 +3215,7 @@ static void process_entry(struct merge_options *opt,
                ci->merged.is_null = 1;
                ci->merged.result.mode = 0;
                oidcpy(&ci->merged.result.oid, null_oid());
+               assert(!ci->df_conflict);
                ci->merged.clean = !ci->path_conflict;
        }
 
index afb88c347fc9011bbe9be623a6a8ec11ad7350fa..316339cb6c93d98dd7d8aed39ffeb6f0293de360 100755 (executable)
@@ -5000,7 +5000,7 @@ test_setup_12i () {
        )
 }
 
-test_expect_merge_algorithm failure failure '12i: Directory rename causes rename-to-self' '
+test_expect_merge_algorithm failure success '12i: Directory rename causes rename-to-self' '
        test_setup_12i &&
        (
                cd 12i &&
@@ -5058,7 +5058,7 @@ test_setup_12j () {
        )
 }
 
-test_expect_merge_algorithm failure failure '12j: Directory rename to root causes rename-to-self' '
+test_expect_merge_algorithm failure success '12j: Directory rename to root causes rename-to-self' '
        test_setup_12j &&
        (
                cd 12j &&
@@ -5116,7 +5116,7 @@ test_setup_12k () {
        )
 }
 
-test_expect_merge_algorithm failure failure '12k: Directory rename with sibling causes rename-to-self' '
+test_expect_merge_algorithm failure success '12k: Directory rename with sibling causes rename-to-self' '
        test_setup_12k &&
        (
                cd 12k &&