Skip to content

Commit

Permalink
am -3: do not let failed merge from completing the error codepath
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Junio C Hamano committed Oct 9, 2015
1 parent 22f698c commit c63d4b2
Showing 1 changed file with 33 additions and 16 deletions.
49 changes: 33 additions & 16 deletions builtin/am.c
Original file line number Diff line number Diff line change
Expand Up @@ -1589,17 +1589,45 @@ static int build_fake_ancestor(const struct am_state *state, const char *index_f
return 0;
}

/**
* Do the three-way merge using fake ancestor, his 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 *his_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(his_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(his_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], his_tree[GIT_SHA1_RAWSZ],
our_tree[GIT_SHA1_RAWSZ];
const unsigned char *bases[1] = {orig_tree};
struct merge_options o;
struct commit *result;
char *his_tree_name;

if (get_sha1("HEAD", our_tree) < 0)
hashcpy(our_tree, EMPTY_TREE_SHA1_BIN);
Expand Down Expand Up @@ -1651,22 +1679,11 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
* changes.
*/

init_merge_options(&o);

o.branch1 = "HEAD";
his_tree_name = xstrfmt("%.*s", linelen(state->msg), state->msg);
o.branch2 = his_tree_name;

if (state->quiet)
o.verbosity = 0;

if (merge_recursive_generic(&o, our_tree, his_tree, 1, bases, &result)) {
if (run_fallback_merge_recursive(state, orig_tree, our_tree, his_tree)) {
rerere(state->allow_rerere_autoupdate);
free(his_tree_name);
return error(_("Failed to merge in the changes."));
}

free(his_tree_name);
return 0;
}

Expand Down

0 comments on commit c63d4b2

Please sign in to comment.