am -3: do not let failed merge from completing the error codepath

When "am" was rewritten in C, the codepath for falling back to three-way merge was mistakenly made to make an internal call to merge-recursive, disabling the error reporting code for certain types of errors merge-recursive detects and reports by calling die(). This is a quick-fix for correctness. The ideal endgame would be to replace run_command() in run_fallback_merge_recursive() with a direct call after making sure that internal call to merge-recursive does not die(). Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Oct 9, 2015 at 13:38 UTC c63d4b2fe86876cc210d8bf22bd84d617f7815b7
1 file changed +33 -16
builtin/am.c
+33 -16
@@ -1589,6 +1589,38 @@ static int build_fake_ancestor(const struct am_state *state, const char *index_f
1589 return 0;
1590 }
1591
1592 +/**
1593 + * Do the three-way merge using fake ancestor, his tree constructed
1594 + * from the fake ancestor and the postimage of the patch, and our
1595 + * state.
1596 + */
1597 +static int run_fallback_merge_recursive(const struct am_state *state,
1598 + unsigned char *orig_tree,
1599 + unsigned char *our_tree,
1600 + unsigned char *his_tree)
1601 +{
1602 + struct child_process cp = CHILD_PROCESS_INIT;
1603 + int status;
1604 +
1605 + cp.git_cmd = 1;
1606 +
1607 + argv_array_pushf(&cp.env_array, "GITHEAD_%s=%.*s",
1608 + sha1_to_hex(his_tree), linelen(state->msg), state->msg);
1609 + if (state->quiet)
1610 + argv_array_push(&cp.env_array, "GIT_MERGE_VERBOSITY=0");
1611 +
1612 + argv_array_push(&cp.args, "merge-recursive");
1613 + argv_array_push(&cp.args, sha1_to_hex(orig_tree));
1614 + argv_array_push(&cp.args, "--");
1615 + argv_array_push(&cp.args, sha1_to_hex(our_tree));
1616 + argv_array_push(&cp.args, sha1_to_hex(his_tree));
1617 +
1618 + status = run_command(&cp) ? (-1) : 0;
1619 + discard_cache();
1620 + read_cache();
1621 + return status;
1622 +}
1623 +
1624 /**
1625 * Attempt a threeway merge, using index_path as the temporary index.
1626 */
@@ -1596,10 +1628,6 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
1628 {
1629 unsigned char orig_tree[GIT_SHA1_RAWSZ], his_tree[GIT_SHA1_RAWSZ],
1630 our_tree[GIT_SHA1_RAWSZ];
1599 - const unsigned char *bases[1] = {orig_tree};
1600 - struct merge_options o;
1601 - struct commit *result;
1602 - char *his_tree_name;
1631
1632 if (get_sha1("HEAD", our_tree) < 0)
1633 hashcpy(our_tree, EMPTY_TREE_SHA1_BIN);
@@ -1651,22 +1679,11 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
1679 * changes.
1680 */
1681
1654 - init_merge_options(&o);
1655 -
1656 - o.branch1 = "HEAD";
1657 - his_tree_name = xstrfmt("%.*s", linelen(state->msg), state->msg);
1658 - o.branch2 = his_tree_name;
1659 -
1660 - if (state->quiet)
1661 - o.verbosity = 0;
1662 -
1663 - if (merge_recursive_generic(&o, our_tree, his_tree, 1, bases, &result)) {
1682 + if (run_fallback_merge_recursive(state, orig_tree, our_tree, his_tree)) {
1683 rerere(state->allow_rerere_autoupdate);
1665 - free(his_tree_name);
1684 return error(_("Failed to merge in the changes."));
1685 }
1686
1669 - free(his_tree_name);
1687 return 0;
1688 }
1689