Skip to content

Commit 9c53de7

Browse files
committed
Merge branch 'jc/am-3-fallback-regression-fix'
"git am -3" had a small regression where it is aborted in its error handling codepath when underlying merge-recursive failed in certain ways, as it assumed that the internal call to merge-recursive will never die, which is not the case (yet). * jc/am-3-fallback-regression-fix: am -3: do not let failed merge from completing the error codepath
2 parents 74301d6 + c63d4b2 commit 9c53de7

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)