Skip to content

Commit 8f240b8

Browse files
newrengitster
authored andcommitted
merge: do not abort early if one strategy fails to handle the merge
builtin/merge is setup to allow multiple strategies to be specified, and it will find the "best" result and use it. This is defeated if some of the merge strategies abort early when they cannot handle the merge. Fix the logic that calls recursive and ort to not do such an early abort, but instead return "2" or "unhandled" so that the next strategy can try to handle the merge. Coming up with a testcase for this is somewhat difficult, since recursive and ort both handle nearly any two-headed merge (there is a separate code path that checks for non-two-headed merges and already returns "2" for them). So use a somewhat synthetic testcase of having the index not match HEAD before the merge starts, since all merge strategies will abort for that. Signed-off-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e4cdfe8 commit 8f240b8

File tree

4 files changed

+22
-3
lines changed

4 files changed

+22
-3
lines changed

builtin/merge.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,10 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
754754
else
755755
clean = merge_recursive(&o, head, remoteheads->item,
756756
reversed, &result);
757-
if (clean < 0)
758-
exit(128);
757+
if (clean < 0) {
758+
rollback_lock_file(&lock);
759+
return 2;
760+
}
759761
if (write_locked_index(&the_index, &lock,
760762
COMMIT_LOCK | SKIP_IF_UNCHANGED))
761763
die(_("unable to write %s"), get_index_file());

t/t6402-merge-rename.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ test_expect_success 'updated working tree file should prevent the merge' '
210210
echo >>M one line addition &&
211211
cat M >M.saved &&
212212
git update-index M &&
213-
test_expect_code 128 git pull --no-rebase . yellow &&
213+
test_expect_code 2 git pull --no-rebase . yellow &&
214214
test_cmp M M.saved &&
215215
rm -f M.saved
216216
'

t/t6424-merge-unrelated-index-changes.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,4 +275,20 @@ test_expect_success 'subtree' '
275275
test_path_is_missing .git/MERGE_HEAD
276276
'
277277

278+
test_expect_success 'with multiple strategies, recursive or ort failure do not early abort' '
279+
git reset --hard &&
280+
git checkout B^0 &&
281+
282+
test_seq 0 10 >a &&
283+
git add a &&
284+
285+
sane_unset GIT_TEST_MERGE_ALGORITHM &&
286+
test_must_fail git merge -s recursive -s ort -s octopus C^0 >output 2>&1 &&
287+
288+
grep "Trying merge strategy recursive..." output &&
289+
grep "Trying merge strategy ort..." output &&
290+
grep "Trying merge strategy octopus..." output &&
291+
grep "No merge strategy handled the merge." output
292+
'
293+
278294
test_done

t/t6439-merge-co-error-msgs.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ test_expect_success 'untracked files overwritten by merge (fast and non-fast for
4747
export GIT_MERGE_VERBOSITY &&
4848
test_must_fail git merge branch 2>out2
4949
) &&
50+
echo "Merge with strategy ${GIT_TEST_MERGE_ALGORITHM:-ort} failed." >>expect &&
5051
test_cmp out2 expect &&
5152
git reset --hard HEAD^
5253
'

0 commit comments

Comments
 (0)