From: Elijah Newren Date: Mon, 20 Sep 2010 08:28:56 +0000 (-0600) Subject: merge-recursive: Structure process_df_entry() to handle more cases X-Git-Tag: v1.7.4-rc0~101^2~16 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/9c0bbb50f0dd916fe1684991d10d93f3c67311ba merge-recursive: Structure process_df_entry() to handle more cases 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 Signed-off-by: Junio C Hamano --- diff --git a/merge-recursive.c b/merge-recursive.c index 319780458e..aa496cd360 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -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;