merge_recursive: Fix renames across paths below D/F conflicts
authorElijah Newren <newren@gmail.com>
Fri, 9 Jul 2010 13:10:54 +0000 (07:10 -0600)
committerJunio C Hamano <gitster@pobox.com>
Fri, 9 Jul 2010 23:13:00 +0000 (16:13 -0700)
The rename logic in process_renames() handles renames and merging of file
contents and then marks files as processed.  However, there may be higher
stage entries left in the index for other reasons (e.g., due to D/F
conflicts).  By checking for such cases and marking the entry as not
processed, it allows process_entry() later to look at it and handle those
higher stages.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
merge-recursive.c
t/t3509-cherry-pick-merge-df.sh
t/t6020-merge-df.sh

index c8d5362191151bf6b2fb418277b761b5cc6dbeee..b0f055ecd49f215dd5fb5b8432247ca9504d1b47 100644 (file)
@@ -1019,14 +1019,25 @@ static int process_renames(struct merge_options *o,
 
                                if (mfi.clean &&
                                    sha_eq(mfi.sha, ren1->pair->two->sha1) &&
-                                   mfi.mode == ren1->pair->two->mode)
+                                   mfi.mode == ren1->pair->two->mode) {
                                        /*
                                         * This messaged is part of
                                         * t6022 test. If you change
                                         * it update the test too.
                                         */
                                        output(o, 3, "Skipped %s (merged same as existing)", ren1_dst);
-                               else {
+
+                                       /* There may be higher stage entries left
+                                        * in the index (e.g. due to a D/F
+                                        * conflict) that need to be resolved.
+                                        */
+                                       for (i = 1; i <= 3; i++) {
+                                               if (!ren1->dst_entry->stages[i].mode)
+                                                       continue;
+                                               ren1->dst_entry->processed = 0;
+                                               break;
+                                       }
+                               } else {
                                        if (mfi.merge || !mfi.clean)
                                                output(o, 1, "Renaming %s => %s", ren1_src, ren1_dst);
                                        if (mfi.merge)
index 7c05e168437232855837f69371ec6a0e6fb2202d..6e7ef8483f5c62ed61515613bca6c4816523e91d 100755 (executable)
@@ -26,7 +26,7 @@ test_expect_success 'Setup rename across paths each below D/F conflicts' '
        git commit -m f1
 '
 
-test_expect_failure 'Cherry-pick succeeds with rename across D/F conflicts' '
+test_expect_success 'Cherry-pick succeeds with rename across D/F conflicts' '
        git reset --hard &&
        git checkout master^0 &&
        git cherry-pick branch
index e71c687f2b9473842684fae1a1b4b013c721497f..490d3971142a87e940f3d27e7e7f068b276ff602 100755 (executable)
@@ -22,7 +22,7 @@ git commit -m "File: dir"'
 
 test_expect_code 1 'Merge with d/f conflicts' 'git merge "merge msg" B master'
 
-test_expect_failure 'F/D conflict' '
+test_expect_success 'F/D conflict' '
        git reset --hard &&
        git checkout master &&
        rm .git/index &&