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