Last October, we had to change this code to run `git merge-recursive` in a child process: git-am wants to print some helpful advice when the merge failed, but the code in question was not prepared to return, it die()d instead. We are finally at a point when the code *is* prepared to return errors, and can avoid the child process again. This reverts commit c63d4b2 (am -3: do not let failed merge from completing the error codepath, 2015-10-09). Note: the code now calls merge_recursive_generic() again. Unlike merge_trees() and merge_recursive(), this function returns 0 upon success, as most of Git's functions. Therefore, the error value -1 naturally is handled correctly, and we do not have to take care of it specifically. Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx> --- builtin/am.c | 49 ++++++++++++++++--------------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index f07f89a..be652f9 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1578,44 +1578,16 @@ static int build_fake_ancestor(const struct am_state *state, const char *index_f } /** - * Do the three-way merge using fake ancestor, her tree constructed - * from the fake ancestor and the postimage of the patch, and our - * state. - */ -static int run_fallback_merge_recursive(const struct am_state *state, - unsigned char *orig_tree, - unsigned char *our_tree, - unsigned char *her_tree) -{ - struct child_process cp = CHILD_PROCESS_INIT; - int status; - - cp.git_cmd = 1; - - argv_array_pushf(&cp.env_array, "GITHEAD_%s=%.*s", - sha1_to_hex(her_tree), linelen(state->msg), state->msg); - if (state->quiet) - argv_array_push(&cp.env_array, "GIT_MERGE_VERBOSITY=0"); - - argv_array_push(&cp.args, "merge-recursive"); - argv_array_push(&cp.args, sha1_to_hex(orig_tree)); - argv_array_push(&cp.args, "--"); - argv_array_push(&cp.args, sha1_to_hex(our_tree)); - argv_array_push(&cp.args, sha1_to_hex(her_tree)); - - status = run_command(&cp) ? (-1) : 0; - discard_cache(); - read_cache(); - return status; -} - -/** * Attempt a threeway merge, using index_path as the temporary index. */ static int fall_back_threeway(const struct am_state *state, const char *index_path) { unsigned char orig_tree[GIT_SHA1_RAWSZ], her_tree[GIT_SHA1_RAWSZ], our_tree[GIT_SHA1_RAWSZ]; + const unsigned char *bases[1] = {orig_tree}; + struct merge_options o; + struct commit *result; + char *her_tree_name; if (get_sha1("HEAD", our_tree) < 0) hashcpy(our_tree, EMPTY_TREE_SHA1_BIN); @@ -1667,11 +1639,22 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa * changes. */ - if (run_fallback_merge_recursive(state, orig_tree, our_tree, her_tree)) { + init_merge_options(&o); + + o.branch1 = "HEAD"; + her_tree_name = xstrfmt("%.*s", linelen(state->msg), state->msg); + o.branch2 = her_tree_name; + + if (state->quiet) + o.verbosity = 0; + + if (merge_recursive_generic(&o, our_tree, her_tree, 1, bases, &result)) { rerere(state->allow_rerere_autoupdate); + free(her_tree_name); return error(_("Failed to merge in the changes.")); } + free(her_tree_name); return 0; } -- 2.9.0.280.g32e2a70 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html