mirror of
https://github.com/git/git.git
synced 2025-12-12 20:36:24 +01:00
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>
336 lines
8.8 KiB
Bash
Executable File
336 lines
8.8 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='merge-recursive rename options
|
|
|
|
Test rename detection by examining rename/delete conflicts.
|
|
|
|
* (HEAD -> rename) rename
|
|
| * (main) delete
|
|
|/
|
|
* base
|
|
|
|
git diff --name-status base main
|
|
D 0-old
|
|
D 1-old
|
|
D 2-old
|
|
D 3-old
|
|
|
|
git diff --name-status -M01 base rename
|
|
R025 0-old 0-new
|
|
R050 1-old 1-new
|
|
R075 2-old 2-new
|
|
R100 3-old 3-new
|
|
|
|
Actual similarity indices are parsed from diff output. We rely on the fact that
|
|
they are rounded down (see, e.g., Documentation/diff-generate-patch.adoc, which
|
|
mentions this in a different context).
|
|
'
|
|
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
. ./test-lib.sh
|
|
|
|
get_expected_stages () {
|
|
git checkout rename -- $1-new &&
|
|
git ls-files --stage $1-new >expected-stages-undetected-$1 &&
|
|
git ls-tree HEAD^ $1-old >tmp &&
|
|
git ls-tree HEAD $1-new >>tmp &&
|
|
cat tmp | awk '{print $1 " " $3 " " NR "\t" '$1'"-new"}' \
|
|
>expected-stages-detected-$1 &&
|
|
git read-tree -u --reset HEAD
|
|
}
|
|
|
|
rename_detected () {
|
|
git ls-files --stage $1-old $1-new >stages-actual-$1 &&
|
|
test_cmp expected-stages-detected-$1 stages-actual-$1
|
|
}
|
|
|
|
rename_undetected () {
|
|
git ls-files --stage $1-old $1-new >stages-actual-$1 &&
|
|
test_cmp expected-stages-undetected-$1 stages-actual-$1
|
|
}
|
|
|
|
check_common () {
|
|
git ls-files --stage >stages-actual &&
|
|
test_line_count = $1 stages-actual
|
|
}
|
|
|
|
check_threshold_0 () {
|
|
check_common 8 &&
|
|
rename_detected 0 &&
|
|
rename_detected 1 &&
|
|
rename_detected 2 &&
|
|
rename_detected 3
|
|
}
|
|
|
|
check_threshold_1 () {
|
|
check_common 7 &&
|
|
rename_undetected 0 &&
|
|
rename_detected 1 &&
|
|
rename_detected 2 &&
|
|
rename_detected 3
|
|
}
|
|
|
|
check_threshold_2 () {
|
|
check_common 6 &&
|
|
rename_undetected 0 &&
|
|
rename_undetected 1 &&
|
|
rename_detected 2 &&
|
|
rename_detected 3
|
|
}
|
|
|
|
check_exact_renames () {
|
|
check_common 5 &&
|
|
rename_undetected 0 &&
|
|
rename_undetected 1 &&
|
|
rename_undetected 2 &&
|
|
rename_detected 3
|
|
}
|
|
|
|
check_no_renames () {
|
|
check_common 4 &&
|
|
rename_undetected 0 &&
|
|
rename_undetected 1 &&
|
|
rename_undetected 2 &&
|
|
rename_undetected 3
|
|
}
|
|
|
|
test_expect_success 'setup repo' '
|
|
cat <<-\EOF >3-old &&
|
|
33a
|
|
33b
|
|
33c
|
|
33d
|
|
EOF
|
|
sed s/33/22/ <3-old >2-old &&
|
|
sed s/33/11/ <3-old >1-old &&
|
|
sed s/33/00/ <3-old >0-old &&
|
|
git add [0-3]-old &&
|
|
git commit -m base &&
|
|
git rm [0-3]-old &&
|
|
git commit -m delete &&
|
|
git checkout -b rename HEAD^ &&
|
|
cp 3-old 3-new &&
|
|
sed 1,1s/./x/ <2-old >2-new &&
|
|
sed 1,2s/./x/ <1-old >1-new &&
|
|
sed 1,3s/./x/ <0-old >0-new &&
|
|
git add [0-3]-new &&
|
|
git rm [0-3]-old &&
|
|
git commit -m rename &&
|
|
get_expected_stages 0 &&
|
|
get_expected_stages 1 &&
|
|
get_expected_stages 2 &&
|
|
get_expected_stages 3 &&
|
|
check_50="false" &&
|
|
tail="HEAD^ -- HEAD main"
|
|
'
|
|
|
|
test_expect_success 'setup thresholds' '
|
|
git diff --name-status -M01 HEAD^ HEAD >diff-output &&
|
|
test_debug "cat diff-output" &&
|
|
test_line_count = 4 diff-output &&
|
|
grep "R[0-9][0-9][0-9] \([0-3]\)-old \1-new" diff-output \
|
|
>grep-output &&
|
|
test_cmp diff-output grep-output &&
|
|
th0=$(sed -n "s/R\(...\) 0-old 0-new/\1/p" <diff-output) &&
|
|
th1=$(sed -n "s/R\(...\) 1-old 1-new/\1/p" <diff-output) &&
|
|
th2=$(sed -n "s/R\(...\) 2-old 2-new/\1/p" <diff-output) &&
|
|
th3=$(sed -n "s/R\(...\) 3-old 3-new/\1/p" <diff-output) &&
|
|
test "$th0" -lt "$th1" &&
|
|
test "$th1" -lt "$th2" &&
|
|
test "$th2" -lt "$th3" &&
|
|
test "$th3" = 100 &&
|
|
if test 50 -le "$th0"
|
|
then
|
|
check_50=check_threshold_0
|
|
elif test 50 -le "$th1"
|
|
then
|
|
check_50=check_threshold_1
|
|
elif test 50 -le "$th2"
|
|
then
|
|
check_50=check_threshold_2
|
|
fi &&
|
|
th0="$th0%" &&
|
|
th1="$th1%" &&
|
|
th2="$th2%" &&
|
|
th3="$th3%"
|
|
'
|
|
|
|
test_expect_success 'assumption for tests: rename detection with diff' '
|
|
git diff --name-status -M$th0 --diff-filter=R HEAD^ HEAD \
|
|
>diff-output-0 &&
|
|
git diff --name-status -M$th1 --diff-filter=R HEAD^ HEAD \
|
|
>diff-output-1 &&
|
|
git diff --name-status -M$th2 --diff-filter=R HEAD^ HEAD \
|
|
>diff-output-2 &&
|
|
git diff --name-status -M100% --diff-filter=R HEAD^ HEAD \
|
|
>diff-output-3 &&
|
|
test_line_count = 4 diff-output-0 &&
|
|
test_line_count = 3 diff-output-1 &&
|
|
test_line_count = 2 diff-output-2 &&
|
|
test_line_count = 1 diff-output-3
|
|
'
|
|
|
|
test_expect_success 'default similarity threshold is 50%' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive $tail &&
|
|
$check_50
|
|
'
|
|
|
|
test_expect_success 'low rename threshold' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive --find-renames=$th0 $tail &&
|
|
check_threshold_0
|
|
'
|
|
|
|
test_expect_success 'medium rename threshold' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive --find-renames=$th1 $tail &&
|
|
check_threshold_1
|
|
'
|
|
|
|
test_expect_success 'high rename threshold' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive --find-renames=$th2 $tail &&
|
|
check_threshold_2
|
|
'
|
|
|
|
test_expect_success 'exact renames only' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive --find-renames=100% $tail &&
|
|
check_exact_renames
|
|
'
|
|
|
|
test_expect_success 'rename threshold is truncated' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive --find-renames=200% $tail &&
|
|
check_exact_renames
|
|
'
|
|
|
|
test_expect_success 'disabled rename detection' '
|
|
git read-tree --reset -u HEAD &&
|
|
git merge-recursive --no-renames $tail &&
|
|
check_no_renames
|
|
'
|
|
|
|
test_expect_success 'last wins in --find-renames=<m> --find-renames=<n>' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive \
|
|
--find-renames=$th0 --find-renames=$th2 $tail &&
|
|
check_threshold_2
|
|
'
|
|
|
|
test_expect_success '--find-renames resets threshold' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive \
|
|
--find-renames=$th0 --find-renames $tail &&
|
|
$check_50
|
|
'
|
|
|
|
test_expect_success 'last wins in --no-renames --find-renames' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive --no-renames --find-renames $tail &&
|
|
$check_50
|
|
'
|
|
|
|
test_expect_success 'last wins in --find-renames --no-renames' '
|
|
git read-tree --reset -u HEAD &&
|
|
git merge-recursive --find-renames --no-renames $tail &&
|
|
check_no_renames
|
|
'
|
|
|
|
test_expect_success 'assumption for further tests: trivial merge succeeds' '
|
|
git read-tree --reset -u HEAD &&
|
|
git merge-recursive HEAD -- HEAD HEAD &&
|
|
git diff --quiet --cached &&
|
|
git merge-recursive --find-renames=$th0 HEAD -- HEAD HEAD &&
|
|
git diff --quiet --cached &&
|
|
git merge-recursive --find-renames=$th2 HEAD -- HEAD HEAD &&
|
|
git diff --quiet --cached &&
|
|
git merge-recursive --find-renames=100% HEAD -- HEAD HEAD &&
|
|
git diff --quiet --cached &&
|
|
git merge-recursive --no-renames HEAD -- HEAD HEAD &&
|
|
git diff --quiet --cached
|
|
'
|
|
|
|
test_expect_success '--find-renames rejects negative argument' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive --find-renames=-25 \
|
|
HEAD -- HEAD HEAD &&
|
|
git diff --quiet --cached
|
|
'
|
|
|
|
test_expect_success '--find-renames rejects non-numbers' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive --find-renames=0xf \
|
|
HEAD -- HEAD HEAD &&
|
|
git diff --quiet --cached
|
|
'
|
|
|
|
test_expect_success 'rename-threshold=<n> is a synonym for find-renames=<n>' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive --rename-threshold=$th0 $tail &&
|
|
check_threshold_0
|
|
'
|
|
|
|
test_expect_success 'last wins in --no-renames --rename-threshold=<n>' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive --no-renames --rename-threshold=$th0 $tail &&
|
|
check_threshold_0
|
|
'
|
|
|
|
test_expect_success 'last wins in --rename-threshold=<n> --no-renames' '
|
|
git read-tree --reset -u HEAD &&
|
|
git merge-recursive --rename-threshold=$th0 --no-renames $tail &&
|
|
check_no_renames
|
|
'
|
|
|
|
test_expect_success '--rename-threshold=<n> rejects negative argument' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive --rename-threshold=-25 \
|
|
HEAD -- HEAD HEAD &&
|
|
git diff --quiet --cached
|
|
'
|
|
|
|
test_expect_success '--rename-threshold=<n> rejects non-numbers' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive --rename-threshold=0xf \
|
|
HEAD -- HEAD HEAD &&
|
|
git diff --quiet --cached
|
|
'
|
|
|
|
test_expect_success 'last wins in --rename-threshold=<m> --find-renames=<n>' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive \
|
|
--rename-threshold=$th0 --find-renames=$th2 $tail &&
|
|
check_threshold_2
|
|
'
|
|
|
|
test_expect_success 'last wins in --find-renames=<m> --rename-threshold=<n>' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git merge-recursive \
|
|
--find-renames=$th2 --rename-threshold=$th0 $tail &&
|
|
check_threshold_0
|
|
'
|
|
|
|
test_expect_success 'merge.renames disables rename detection' '
|
|
git read-tree --reset -u HEAD &&
|
|
git -c merge.renames=false merge-recursive $tail &&
|
|
check_no_renames
|
|
'
|
|
|
|
test_expect_success 'merge.renames defaults to diff.renames' '
|
|
git read-tree --reset -u HEAD &&
|
|
git -c diff.renames=false merge-recursive $tail &&
|
|
check_no_renames
|
|
'
|
|
|
|
test_expect_success 'merge.renames overrides diff.renames' '
|
|
git read-tree --reset -u HEAD &&
|
|
test_must_fail git -c diff.renames=false -c merge.renames=true merge-recursive $tail &&
|
|
$check_50
|
|
'
|
|
|
|
test_done
|