@ -1356,7 +1356,6 @@ static inline void set_commit_tree(struct commit *c, struct tree *t)
@@ -1356,7 +1356,6 @@ static inline void set_commit_tree(struct commit *c, struct tree *t)
c->maybe_tree = t;
}
MAYBE_UNUSED
static struct commit *make_virtual_commit(struct repository *repo,
struct tree *tree,
const char *comment)
@ -1466,6 +1465,89 @@ static void merge_ort_nonrecursive_internal(struct merge_options *opt,
@@ -1466,6 +1465,89 @@ static void merge_ort_nonrecursive_internal(struct merge_options *opt,
}
}
/*
* Originally from merge_recursive_internal(); somewhat adapted, though.
*/
static void merge_ort_internal(struct merge_options *opt,
struct commit_list *merge_bases,
struct commit *h1,
struct commit *h2,
struct merge_result *result)
{
struct commit_list *iter;
struct commit *merged_merge_bases;
const char *ancestor_name;
struct strbuf merge_base_abbrev = STRBUF_INIT;
if (!merge_bases) {
merge_bases = get_merge_bases(h1, h2);
/* See merge-ort.h:merge_incore_recursive() declaration NOTE */
merge_bases = reverse_commit_list(merge_bases);
}
merged_merge_bases = pop_commit(&merge_bases);
if (merged_merge_bases == NULL) {
/* if there is no common ancestor, use an empty tree */
struct tree *tree;
tree = lookup_tree(opt->repo, opt->repo->hash_algo->empty_tree);
merged_merge_bases = make_virtual_commit(opt->repo, tree,
"ancestor");
ancestor_name = "empty tree";
} else if (merge_bases) {
ancestor_name = "merged common ancestors";
} else {
strbuf_add_unique_abbrev(&merge_base_abbrev,
&merged_merge_bases->object.oid,
DEFAULT_ABBREV);
ancestor_name = merge_base_abbrev.buf;
}
for (iter = merge_bases; iter; iter = iter->next) {
const char *saved_b1, *saved_b2;
struct commit *prev = merged_merge_bases;
opt->priv->call_depth++;
/*
* When the merge fails, the result contains files
* with conflict markers. The cleanness flag is
* ignored (unless indicating an error), it was never
* actually used, as result of merge_trees has always
* overwritten it: the committed "conflicts" were
* already resolved.
*/
saved_b1 = opt->branch1;
saved_b2 = opt->branch2;
opt->branch1 = "Temporary merge branch 1";
opt->branch2 = "Temporary merge branch 2";
merge_ort_internal(opt, NULL, prev, iter->item, result);
if (result->clean < 0)
return;
opt->branch1 = saved_b1;
opt->branch2 = saved_b2;
opt->priv->call_depth--;
merged_merge_bases = make_virtual_commit(opt->repo,
result->tree,
"merged tree");
commit_list_insert(prev, &merged_merge_bases->parents);
commit_list_insert(iter->item,
&merged_merge_bases->parents->next);
clear_or_reinit_internal_opts(opt->priv, 1);
}
opt->ancestor = ancestor_name;
merge_ort_nonrecursive_internal(opt,
repo_get_commit_tree(opt->repo,
merged_merge_bases),
repo_get_commit_tree(opt->repo, h1),
repo_get_commit_tree(opt->repo, h2),
result);
strbuf_release(&merge_base_abbrev);
opt->ancestor = NULL; /* avoid accidental re-use of opt->ancestor */
}
void merge_incore_nonrecursive(struct merge_options *opt,
struct tree *merge_base,
struct tree *side1,
@ -1483,5 +1565,9 @@ void merge_incore_recursive(struct merge_options *opt,
@@ -1483,5 +1565,9 @@ void merge_incore_recursive(struct merge_options *opt,
struct commit *side2,
struct merge_result *result)
{
die("Not yet implemented");
/* We set the ancestor label based on the merge_bases */
assert(opt->ancestor == NULL);
merge_start(opt, result);
merge_ort_internal(opt, merge_bases, side1, side2, result);
}