get_renames() would look up stage data that already existed (populated in get_unmerged(), taken from whatever unpack_trees() created), and if it didn't exist, would call insert_stage_data() to create the necessary entry for the given file. The insert_stage_data() fallback becomes much more important for directory rename detection, because that creates a mechanism to have a file in the resulting merge that didn't exist on either side of history. However, insert_stage_data(), due to calling get_tree_entry() loaded up trees as readily as files. We aren't interested in comparing trees to files; the D/F conflict handling is done elsewhere. This code is just concerned with what entries existed for a given path on the different sides of the merge, so create a get_tree_entry_if_blob() helper function and use it. Signed-off-by: Elijah Newren <newren@xxxxxxxxx> --- merge-recursive.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index 7c2c29bb51..2a7258f6bb 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -407,6 +407,21 @@ static void get_files_dirs(struct merge_options *o, struct tree *tree) read_tree_recursive(tree, "", 0, 0, &match_all, save_files_dirs, o); } +static int get_tree_entry_if_blob(const unsigned char *tree, + const char *path, + unsigned char *hashy, + unsigned *mode_o) +{ + int ret; + + ret = get_tree_entry(tree, path, hashy, mode_o); + if (S_ISDIR(*mode_o)) { + hashcpy(hashy, null_sha1); + *mode_o = 0; + } + return ret; +} + /* * Returns an index_entry instance which doesn't have to correspond to * a real cache entry in Git's index. @@ -417,12 +432,12 @@ static struct stage_data *insert_stage_data(const char *path, { struct string_list_item *item; struct stage_data *e = xcalloc(1, sizeof(struct stage_data)); - get_tree_entry(o->object.oid.hash, path, - e->stages[1].oid.hash, &e->stages[1].mode); - get_tree_entry(a->object.oid.hash, path, - e->stages[2].oid.hash, &e->stages[2].mode); - get_tree_entry(b->object.oid.hash, path, - e->stages[3].oid.hash, &e->stages[3].mode); + get_tree_entry_if_blob(o->object.oid.hash, path, + e->stages[1].oid.hash, &e->stages[1].mode); + get_tree_entry_if_blob(a->object.oid.hash, path, + e->stages[2].oid.hash, &e->stages[2].mode); + get_tree_entry_if_blob(b->object.oid.hash, path, + e->stages[3].oid.hash, &e->stages[3].mode); item = string_list_insert(entries, path); item->util = e; return e; -- 2.15.0.5.g9567be9905