Switch from merge-recursive to merge-ort. Adjust the following testcases due to the switch: * t6430: most of the test differences here were due to improved D/F conflict handling explained in more detail inef52778708(merge tests: expect improved directory/file conflict handling in ort, 2020-10-26). These changes weren't made to this test back in that commit simply because I had been looking at `git merge` rather than `git merge-recursive`. The final test in this testsuite, though, was expunged because it was looking for specific output, and the calls to output_commit_title() were discarded from merge_ort_internal() in its adaptation from merge_recursive_internal(); see8119214f4e(merge-ort: implement merge_incore_recursive(), 2020-12-16). * t6434: This test is built entirely around rename/delete conflicts, which had a suboptimal handling under merge-recursive. As explained in more detail in commits1f3c9ba707("t6425: be more flexible with rename/delete conflict messages", 2020-08-10) and727c75b23f("t6404, t6423: expect improved rename/delete handling in ort backend", 2020-10-26), rename/delete conflicts should each have two entries in the index rather than just one. Adjust the expectations for all the tests in this testcase to see the two entries per rename/delete conflict. * t6424: merge-recursive had a special check-if-toplevel-trees-match check that it ran at the beginning on both the merge-base and the other side being merged in. In such a case, it exited early and printed an "Already up to date." message. merge-ort got rid of this, and instead checks the merge base tree matching the other side throughout the tree instead of just at the toplevel, allowing it to avoid recursing into various subtrees. As part of that, it got rid of the specialty toplevel message. That message hasn't been missed for years from `git merge`, so I don't think it is necessary to keep it just for `git merge-recursive`, especially since the latter is rarely used. (git itself only references it in the testsuite, whereas it used to power one of the three rebase backends that existed once upon a time.) Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
313 lines
7.5 KiB
Bash
Executable File
313 lines
7.5 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description="merges with unrelated index changes"
|
|
|
|
. ./test-lib.sh
|
|
|
|
# Testcase for some simple merges
|
|
# A
|
|
# o-------o B
|
|
# \
|
|
# \-----o C
|
|
# \
|
|
# \---o D
|
|
# \
|
|
# \-o E
|
|
# \
|
|
# o F
|
|
# Commit A: some file a
|
|
# Commit B: adds file b, modifies end of a
|
|
# Commit C: adds file c
|
|
# Commit D: adds file d, modifies beginning of a
|
|
# Commit E: renames a->subdir/a, adds subdir/e
|
|
# Commit F: empty commit
|
|
|
|
test_expect_success 'setup trivial merges' '
|
|
test_seq 1 10 >a &&
|
|
git add a &&
|
|
test_tick && git commit -m A &&
|
|
|
|
git branch A &&
|
|
git branch B &&
|
|
git branch C &&
|
|
git branch D &&
|
|
git branch E &&
|
|
git branch F &&
|
|
|
|
git checkout B &&
|
|
echo b >b &&
|
|
echo 11 >>a &&
|
|
git add a b &&
|
|
test_tick && git commit -m B &&
|
|
|
|
git checkout C &&
|
|
echo c >c &&
|
|
git add c &&
|
|
test_tick && git commit -m C &&
|
|
|
|
git checkout D &&
|
|
test_seq 2 10 >a &&
|
|
echo d >d &&
|
|
git add a d &&
|
|
test_tick && git commit -m D &&
|
|
|
|
git checkout E &&
|
|
mkdir subdir &&
|
|
git mv a subdir/a &&
|
|
echo e >subdir/e &&
|
|
git add subdir &&
|
|
test_tick && git commit -m E &&
|
|
|
|
git checkout F &&
|
|
test_tick && git commit --allow-empty -m F
|
|
'
|
|
|
|
test_expect_success 'ff update' '
|
|
git reset --hard &&
|
|
git checkout A^0 &&
|
|
|
|
touch random_file && git add random_file &&
|
|
|
|
git merge E^0 &&
|
|
|
|
test_must_fail git rev-parse HEAD:random_file &&
|
|
test "$(git diff --name-only --cached E)" = "random_file" &&
|
|
test_path_is_file random_file &&
|
|
git rev-parse --verify :random_file
|
|
'
|
|
|
|
test_expect_success 'ff update, important file modified' '
|
|
git reset --hard &&
|
|
git checkout A^0 &&
|
|
|
|
mkdir subdir &&
|
|
touch subdir/e &&
|
|
git add subdir/e &&
|
|
|
|
test_must_fail git merge E^0 &&
|
|
test_path_is_file subdir/e &&
|
|
git rev-parse --verify :subdir/e &&
|
|
test_path_is_missing .git/MERGE_HEAD
|
|
'
|
|
|
|
test_expect_success 'resolve, trivial' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
touch random_file && git add random_file &&
|
|
|
|
test_must_fail git merge -s resolve C^0 &&
|
|
test_path_is_file random_file &&
|
|
git rev-parse --verify :random_file &&
|
|
test_path_is_missing .git/MERGE_HEAD
|
|
'
|
|
|
|
test_expect_success 'resolve, non-trivial' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
touch random_file && git add random_file &&
|
|
|
|
test_must_fail git merge -s resolve D^0 &&
|
|
test_path_is_file random_file &&
|
|
git rev-parse --verify :random_file &&
|
|
test_path_is_missing .git/MERGE_HEAD
|
|
'
|
|
|
|
test_expect_success 'resolve, trivial, related file removed' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
git rm a &&
|
|
test_path_is_missing a &&
|
|
|
|
test_must_fail git merge -s resolve C^0 &&
|
|
|
|
test_path_is_missing a &&
|
|
test_path_is_missing .git/MERGE_HEAD
|
|
'
|
|
|
|
test_expect_success 'resolve, non-trivial, related file removed' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
git rm a &&
|
|
test_path_is_missing a &&
|
|
|
|
# We also ask for recursive in order to turn off the "allow_trivial"
|
|
# setting in builtin/merge.c, and ensure that resolve really does
|
|
# correctly fail the merge (I guess this also tests that recursive
|
|
# correctly fails the merge, but the main thing we are attempting
|
|
# to test here is resolve and are just using the side effect of
|
|
# adding recursive to ensure that resolve is actually tested rather
|
|
# than the trivial merge codepath)
|
|
test_must_fail git merge -s resolve -s recursive D^0 &&
|
|
|
|
test_path_is_missing a &&
|
|
test_path_is_missing .git/MERGE_HEAD
|
|
'
|
|
|
|
test_expect_success 'recursive' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
touch random_file && git add random_file &&
|
|
|
|
test_must_fail git merge -s recursive C^0 &&
|
|
test_path_is_file random_file &&
|
|
git rev-parse --verify :random_file &&
|
|
test_path_is_missing .git/MERGE_HEAD
|
|
'
|
|
|
|
test_expect_success 'recursive, when merge branch matches merge base' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
touch random_file && git add random_file &&
|
|
|
|
test_must_fail git merge -s recursive F^0 &&
|
|
test_path_is_missing .git/MERGE_HEAD
|
|
'
|
|
|
|
test_expect_success 'merge-recursive, when index==head but head!=HEAD' '
|
|
git reset --hard &&
|
|
git checkout C^0 &&
|
|
|
|
# Make index match B
|
|
git diff C B -- | git apply --cached &&
|
|
test_when_finished "git clean -fd" && # Do not leave untracked around
|
|
git write-tree >index-before &&
|
|
# Merge B & F, with B as "head"
|
|
git merge-recursive A -- B F > out &&
|
|
git write-tree >index-after &&
|
|
test_cmp index-before index-after
|
|
'
|
|
|
|
test_expect_success 'recursive, when file has staged changes not matching HEAD nor what a merge would give' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
mkdir subdir &&
|
|
test_seq 1 10 >subdir/a &&
|
|
git add subdir/a &&
|
|
git rev-parse --verify :subdir/a >expect &&
|
|
|
|
# We have staged changes; merge should error out
|
|
test_must_fail git merge -s recursive E^0 2>err &&
|
|
git rev-parse --verify :subdir/a >actual &&
|
|
test_cmp expect actual &&
|
|
test_grep "changes to the following files would be overwritten" err
|
|
'
|
|
|
|
test_expect_success 'recursive, when file has staged changes matching what a merge would give' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
mkdir subdir &&
|
|
test_seq 1 11 >subdir/a &&
|
|
git add subdir/a &&
|
|
git rev-parse --verify :subdir/a >expect &&
|
|
|
|
# We have staged changes; merge should error out
|
|
test_must_fail git merge -s recursive E^0 2>err &&
|
|
git rev-parse --verify :subdir/a >actual &&
|
|
test_cmp expect actual &&
|
|
test_grep "changes to the following files would be overwritten" err
|
|
'
|
|
|
|
test_expect_success 'octopus, unrelated file touched' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
touch random_file && git add random_file &&
|
|
|
|
test_must_fail git merge C^0 D^0 &&
|
|
test_path_is_missing .git/MERGE_HEAD &&
|
|
git rev-parse --verify :random_file &&
|
|
test_path_exists random_file
|
|
'
|
|
|
|
test_expect_success 'octopus, related file removed' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
git rm b &&
|
|
|
|
test_must_fail git merge C^0 D^0 &&
|
|
test_path_is_missing b &&
|
|
test_must_fail git rev-parse --verify :b &&
|
|
test_path_is_missing .git/MERGE_HEAD
|
|
'
|
|
|
|
test_expect_success 'octopus, related file modified' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
echo 12 >>a && git add a &&
|
|
git rev-parse --verify :a >expect &&
|
|
|
|
test_must_fail git merge C^0 D^0 &&
|
|
test_path_is_file a &&
|
|
git rev-parse --verify :a >actual &&
|
|
test_cmp expect actual &&
|
|
test_path_is_missing .git/MERGE_HEAD
|
|
'
|
|
|
|
test_expect_success 'ours' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
touch random_file && git add random_file &&
|
|
|
|
test_must_fail git merge -s ours C^0 &&
|
|
test_path_is_file random_file &&
|
|
git rev-parse --verify :random_file &&
|
|
test_path_is_missing .git/MERGE_HEAD
|
|
'
|
|
|
|
test_expect_success 'subtree' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
touch random_file && git add random_file &&
|
|
|
|
test_must_fail git merge -s subtree E^0 &&
|
|
test_path_is_file random_file &&
|
|
git rev-parse --verify :random_file &&
|
|
test_path_is_missing .git/MERGE_HEAD
|
|
'
|
|
|
|
test_expect_success 'avoid failure due to stat-dirty files' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
# Make "a" be stat-dirty
|
|
test-tool chmtime =+1 a &&
|
|
|
|
# stat-dirty file should not prevent stash creation in builtin/merge.c
|
|
git merge -s resolve -s recursive D^0
|
|
'
|
|
|
|
test_expect_success 'with multiple strategies, recursive or ort failure do not early abort' '
|
|
git reset --hard &&
|
|
git checkout B^0 &&
|
|
|
|
test_seq 0 10 >a &&
|
|
git add a &&
|
|
git rev-parse :a >expect &&
|
|
|
|
sane_unset GIT_TEST_MERGE_ALGORITHM &&
|
|
test_must_fail git merge -s recursive -s ort -s octopus C^0 >output 2>&1 &&
|
|
|
|
grep "Trying merge strategy recursive..." output &&
|
|
grep "Trying merge strategy ort..." output &&
|
|
grep "Trying merge strategy octopus..." output &&
|
|
grep "No merge strategy handled the merge." output &&
|
|
|
|
# Changes to "a" should remain staged
|
|
git rev-parse :a >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_done
|