Skip to content

Commit c63d4b2

Browse files
committed
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 <[email protected]>
1 parent 22f698c commit c63d4b2

File tree

1 file changed

+33
-16
lines changed

1 file changed

+33
-16
lines changed

builtin/am.c

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,17 +1589,45 @@ static int build_fake_ancestor(const struct am_state *state, const char *index_f
15891589
return 0;
15901590
}
15911591

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+
15921624
/**
15931625
* Attempt a threeway merge, using index_path as the temporary index.
15941626
*/
15951627
static int fall_back_threeway(const struct am_state *state, const char *index_path)
15961628
{
15971629
unsigned char orig_tree[GIT_SHA1_RAWSZ], his_tree[GIT_SHA1_RAWSZ],
15981630
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;
16031631

16041632
if (get_sha1("HEAD", our_tree) < 0)
16051633
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
16511679
* changes.
16521680
*/
16531681

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)) {
16641683
rerere(state->allow_rerere_autoupdate);
1665-
free(his_tree_name);
16661684
return error(_("Failed to merge in the changes."));
16671685
}
16681686

1669-
free(his_tree_name);
16701687
return 0;
16711688
}
16721689

0 commit comments

Comments
 (0)