merge-recursive: Small code clarification -- variable name and comments
[gitweb.git] / merge-recursive.c
index 20e1779428ee553a940592c09bbabe9ca9800a39..f9531c8069632e98f8bcd3f9e607ec3c0257ea97 100644 (file)
@@ -924,25 +924,26 @@ static int process_renames(struct merge_options *o,
                        struct string_list_item *item;
                        /* we only use sha1 and mode of these */
                        struct diff_filespec src_other, dst_other;
-                       int try_merge, stage = a_renames == renames1 ? 3: 2;
+                       int try_merge;
 
-                       remove_file(o, 1, ren1_src, o->call_depth || stage == 3);
+                       /*
+                        * unpack_trees loads entries from common-commit
+                        * into stage 1, from head-commit into stage 2, and
+                        * from merge-commit into stage 3.  We keep track
+                        * of which side corresponds to the rename.
+                        */
+                       int renamed_stage = a_renames == renames1 ? 2 : 3;
+                       int other_stage =   a_renames == renames1 ? 3 : 2;
 
-                       hashcpy(src_other.sha1, ren1->src_entry->stages[stage].sha);
-                       src_other.mode = ren1->src_entry->stages[stage].mode;
-                       hashcpy(dst_other.sha1, ren1->dst_entry->stages[stage].sha);
-                       dst_other.mode = ren1->dst_entry->stages[stage].mode;
+                       remove_file(o, 1, ren1_src, o->call_depth || renamed_stage == 2);
 
+                       hashcpy(src_other.sha1, ren1->src_entry->stages[other_stage].sha);
+                       src_other.mode = ren1->src_entry->stages[other_stage].mode;
+                       hashcpy(dst_other.sha1, ren1->dst_entry->stages[other_stage].sha);
+                       dst_other.mode = ren1->dst_entry->stages[other_stage].mode;
                        try_merge = 0;
 
-                       if (string_list_has_string(&o->current_directory_set, ren1_dst)) {
-                               clean_merge = 0;
-                               output(o, 1, "CONFLICT (rename/directory): Rename %s->%s in %s "
-                                      " directory %s added in %s",
-                                      ren1_src, ren1_dst, branch1,
-                                      ren1_dst, branch2);
-                               conflict_rename_dir(o, ren1, branch1);
-                       } else if (sha_eq(src_other.sha1, null_sha1)) {
+                       if (sha_eq(src_other.sha1, null_sha1)) {
                                clean_merge = 0;
                                output(o, 1, "CONFLICT (rename/delete): Rename %s->%s in %s "
                                       "and deleted in %s",
@@ -955,6 +956,12 @@ static int process_renames(struct merge_options *o,
                                                        ren1->pair->two : NULL,
                                                        branch1 == o->branch1 ?
                                                        NULL : ren1->pair->two, 1);
+                       } else if ((dst_other.mode == ren1->pair->two->mode) &&
+                                  sha_eq(dst_other.sha1, ren1->pair->two->sha1)) {
+                               /* Added file on the other side
+                                  identical to the file being
+                                  renamed: clean merge */
+                               update_file(o, 1, ren1->pair->two->sha1, ren1->pair->two->mode, ren1_dst);
                        } else if (!sha_eq(dst_other.sha1, null_sha1)) {
                                const char *new_path;
                                clean_merge = 0;
@@ -1034,6 +1041,13 @@ static int process_renames(struct merge_options *o,
                                        if (!ren1->dst_entry->stages[2].mode !=
                                            !ren1->dst_entry->stages[3].mode)
                                                ren1->dst_entry->processed = 0;
+                               } else if (string_list_has_string(&o->current_directory_set, ren1_dst)) {
+                                       clean_merge = 0;
+                                       output(o, 1, "CONFLICT (rename/directory): Rename %s->%s in %s "
+                                              " directory %s added in %s",
+                                              ren1_src, ren1_dst, branch1,
+                                              ren1_dst, branch2);
+                                       conflict_rename_dir(o, ren1, branch1);
                                } else {
                                        if (mfi.merge || !mfi.clean)
                                                output(o, 1, "Renaming %s => %s", ren1_src, ren1_dst);
@@ -1253,9 +1267,8 @@ static int process_df_entry(struct merge_options *o,
        const char *conf;
        struct stat st;
 
-       /* We currently only handle D->F cases */
-       assert((!o_sha && a_sha && !b_sha) ||
-              (!o_sha && !a_sha && b_sha));
+       if (!((!o_sha && a_sha && !b_sha) || (!o_sha && !a_sha && b_sha)))
+               return 1; /* we don't handle non D-F cases */
 
        entry->processed = 1;
 
@@ -1344,6 +1357,12 @@ int merge_trees(struct merge_options *o,
                                && !process_df_entry(o, path, e))
                                clean = 0;
                }
+               for (i = 0; i < entries->nr; i++) {
+                       struct stage_data *e = entries->items[i].util;
+                       if (!e->processed)
+                               die("Unprocessed path??? %s",
+                                   entries->items[i].string);
+               }
 
                string_list_clear(re_merge, 0);
                string_list_clear(re_head, 0);