merge-recursive: Structure process_df_entry() to handle more cases
authorElijah Newren <newren@gmail.com>
Mon, 20 Sep 2010 08:28:56 +0000 (02:28 -0600)
committerJunio C Hamano <gitster@pobox.com>
Thu, 30 Sep 2010 00:37:03 +0000 (17:37 -0700)
Modify process_df_entry() (mostly just indentation level changes) to
get it ready for handling more D/F conflict type cases.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
merge-recursive.c
index 319780458e50e1cd3c925a808668086cf02a12f3..aa496cd3601ddad933d07481d454258029863d48 100644 (file)
@@ -1336,13 +1336,19 @@ static int process_entry(struct merge_options *o,
 }
 
 /*
- * Per entry merge function for D/F conflicts, to be called only after
- * all files below dir have been processed.  We do this because in the
- * cases we can cleanly resolve D/F conflicts, process_entry() can clean
- * out all the files below the directory for us.
+ * Per entry merge function for D/F (and/or rename) conflicts.  In the
+ * cases we can cleanly resolve D/F conflicts, process_entry() can
+ * clean out all the files below the directory for us.  All D/F
+ * conflict cases must be handled here at the end to make sure any
+ * directories that can be cleaned out, are.
+ *
+ * Some rename conflicts may also be handled here that don't necessarily
+ * involve D/F conflicts, since the code to handle them is generic enough
+ * to handle those rename conflicts with or without D/F conflicts also
+ * being involved.
  */
 static int process_df_entry(struct merge_options *o,
-                        const char *path, struct stage_data *entry)
+                           const char *path, struct stage_data *entry)
 {
        int clean_merge = 1;
        unsigned o_mode = entry->stages[1].mode;
@@ -1351,42 +1357,47 @@ static int process_df_entry(struct merge_options *o,
        unsigned char *o_sha = stage_sha(entry->stages[1].sha, o_mode);
        unsigned char *a_sha = stage_sha(entry->stages[2].sha, a_mode);
        unsigned char *b_sha = stage_sha(entry->stages[3].sha, b_mode);
-       const char *add_branch;
-       const char *other_branch;
-       unsigned mode;
-       const unsigned char *sha;
-       const char *conf;
        struct stat st;
 
-       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;
+       if (entry->rename_df_conflict_info) {
+               die("Not yet implemented.");
+       } else if (!o_sha && !!a_sha != !!b_sha) {
+               /* directory -> (directory, file) */
+               const char *add_branch;
+               const char *other_branch;
+               unsigned mode;
+               const unsigned char *sha;
+               const char *conf;
 
-       if (a_sha) {
-               add_branch = o->branch1;
-               other_branch = o->branch2;
-               mode = a_mode;
-               sha = a_sha;
-               conf = "file/directory";
-       } else {
-               add_branch = o->branch2;
-               other_branch = o->branch1;
-               mode = b_mode;
-               sha = b_sha;
-               conf = "directory/file";
-       }
-       if (lstat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
-               const char *new_path = unique_path(o, path, add_branch);
-               clean_merge = 0;
-               output(o, 1, "CONFLICT (%s): There is a directory with name %s in %s. "
-                      "Adding %s as %s",
-                      conf, path, other_branch, path, new_path);
-               remove_file(o, 0, path, 0);
-               update_file(o, 0, sha, mode, new_path);
+               if (a_sha) {
+                       add_branch = o->branch1;
+                       other_branch = o->branch2;
+                       mode = a_mode;
+                       sha = a_sha;
+                       conf = "file/directory";
+               } else {
+                       add_branch = o->branch2;
+                       other_branch = o->branch1;
+                       mode = b_mode;
+                       sha = b_sha;
+                       conf = "directory/file";
+               }
+               if (lstat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
+                       const char *new_path = unique_path(o, path, add_branch);
+                       clean_merge = 0;
+                       output(o, 1, "CONFLICT (%s): There is a directory with name %s in %s. "
+                              "Adding %s as %s",
+                              conf, path, other_branch, path, new_path);
+                       remove_file(o, 0, path, 0);
+                       update_file(o, 0, sha, mode, new_path);
+               } else {
+                       output(o, 2, "Adding %s", path);
+                       update_file(o, 1, sha, mode, path);
+               }
        } else {
-               output(o, 2, "Adding %s", path);
-               update_file(o, 1, sha, mode, path);
+               entry->processed = 0;
+               return 1; /* not handled; assume clean until processed */
        }
 
        return clean_merge;