Merge branch 'jz/apply-run-3way-first'

"git apply --3way" has always been "to fall back to 3-way merge
only when straight application fails". Swap the order of falling
back so that 3-way is always attempted first (only when the option
is given, of course) and then straight patch application is used as
a fallback when it fails.

* jz/apply-run-3way-first:
  git-apply: try threeway first when "--3way" is used
This commit is contained in:
Junio C Hamano 2021-04-15 13:36:00 -07:00
Родитель 54a3917115 923cd87ac8
Коммит 771c758e8a
3 изменённых файлов: 28 добавлений и 10 удалений

Просмотреть файл

@ -84,9 +84,8 @@ OPTIONS
-3::
--3way::
When the patch does not apply cleanly, fall back on 3-way merge if
the patch records the identity of blobs it is supposed to apply to,
and we have those blobs available locally, possibly leaving the
Attempt 3-way merge if the patch records the identity of blobs it is supposed
to apply to and we have those blobs available locally, possibly leaving the
conflict markers in the files in the working tree for the user to
resolve. This option implies the `--index` option, and is incompatible
with the `--reject` and the `--cached` options.

13
apply.c
Просмотреть файл

@ -3570,10 +3570,10 @@ static int try_threeway(struct apply_state *state,
write_object_file("", 0, blob_type, &pre_oid);
else if (get_oid(patch->old_oid_prefix, &pre_oid) ||
read_blob_object(&buf, &pre_oid, patch->old_mode))
return error(_("repository lacks the necessary blob to fall back on 3-way merge."));
return error(_("repository lacks the necessary blob to perform 3-way merge."));
if (state->apply_verbosity > verbosity_silent)
fprintf(stderr, _("Falling back to three-way merge...\n"));
fprintf(stderr, _("Performing three-way merge...\n"));
img = strbuf_detach(&buf, &len);
prepare_image(&tmp_image, img, len, 1);
@ -3605,7 +3605,7 @@ static int try_threeway(struct apply_state *state,
if (status < 0) {
if (state->apply_verbosity > verbosity_silent)
fprintf(stderr,
_("Failed to fall back on three-way merge...\n"));
_("Failed to perform three-way merge...\n"));
return status;
}
@ -3638,10 +3638,9 @@ static int apply_data(struct apply_state *state, struct patch *patch,
if (load_preimage(state, &image, patch, st, ce) < 0)
return -1;
if (patch->direct_to_threeway ||
apply_fragments(state, &image, patch) < 0) {
if (!state->threeway || try_threeway(state, &image, patch, st, ce) < 0) {
/* Note: with --reject, apply_fragments() returns 0 */
if (!state->threeway || try_threeway(state, &image, patch, st, ce) < 0)
if (patch->direct_to_threeway || apply_fragments(state, &image, patch) < 0)
return -1;
}
patch->result = image.buf;
@ -5018,7 +5017,7 @@ int apply_parse_options(int argc, const char **argv,
OPT_BOOL(0, "apply", force_apply,
N_("also apply the patch (use with --stat/--summary/--check)")),
OPT_BOOL('3', "3way", &state->threeway,
N_( "attempt three-way merge if a patch does not apply")),
N_( "attempt three-way merge, fall back on normal patch if that fails")),
OPT_FILENAME(0, "build-fake-ancestor", &state->fake_ancestor,
N_("build a temporary index based on embedded index information")),
/* Think twice before adding "--nul" synonym to this */

Просмотреть файл

@ -160,4 +160,24 @@ test_expect_success 'apply -3 with add/add conflict (dirty working tree)' '
test_cmp three.save three
'
test_expect_success 'apply -3 with ambiguous repeating file' '
git reset --hard &&
test_write_lines 1 2 1 2 1 2 1 2 1 2 1 >one_two_repeat &&
git add one_two_repeat &&
git commit -m "init one" &&
test_write_lines 1 2 1 2 1 2 1 2 one 2 1 >one_two_repeat &&
git commit -a -m "change one" &&
git diff HEAD~ >Repeat.diff &&
git reset --hard HEAD~ &&
test_write_lines 1 2 1 2 1 2 one 2 1 2 one >one_two_repeat &&
git commit -a -m "change surrounding one" &&
git apply --index --3way Repeat.diff &&
test_write_lines 1 2 1 2 1 2 one 2 one 2 one >expect &&
test_cmp expect one_two_repeat
'
test_done