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.schinde...@gmx.de>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to