提交 ac193e0e 编写于 作者: J Junio C Hamano

Merge branch 'en/merge-path-collision'

Updates for corner cases in merge-recursive.

* en/merge-path-collision:
  t6036: avoid non-portable "cp -a"
  merge-recursive: combine error handling
  t6036, t6043: increase code coverage for file collision handling
  merge-recursive: improve rename/rename(1to2)/add[/add] handling
  merge-recursive: use handle_file_collision for add/add conflicts
  merge-recursive: improve handling for rename/rename(2to1) conflicts
  merge-recursive: fix rename/add conflict handling
  merge-recursive: new function for better colliding conflict resolutions
  merge-recursive: increase marker length with depth of recursion
  t6036, t6042: testcases for rename collision of already conflicting files
  t6042: add tests for consistency in file collision conflict handling
......@@ -384,7 +384,9 @@ int ll_merge(mmbuffer_t *result_buf,
if (opts->virtual_ancestor) {
if (driver->recursive)
driver = find_ll_merge_driver(driver->recursive);
marker_size += 2;
}
if (opts->extra_marker_size) {
marker_size += opts->extra_marker_size;
}
return driver->fn(driver, result_buf, path, ancestor, ancestor_label,
ours, our_label, theirs, their_label,
......
......@@ -13,6 +13,7 @@ struct ll_merge_options {
unsigned virtual_ancestor : 1;
unsigned variant : 2; /* favor ours, favor theirs, or union merge */
unsigned renormalize : 1;
unsigned extra_marker_size;
long xdl_opts;
};
......
此差异已折叠。
......@@ -64,15 +64,12 @@ test_expect_success 'merge simple rename+criss-cross with no modifications' '
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 3 out &&
test_line_count = 1 out &&
git rev-parse >expect \
L2:three R2:three \
L2:three R2:three &&
git rev-parse >actual \
:2:three :3:three &&
git hash-object >>actual \
three~HEAD three~R2^0 &&
test_cmp expect actual
)
'
......@@ -140,15 +137,12 @@ test_expect_success 'merge criss-cross + rename merges with basic modification'
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 3 out &&
test_line_count = 1 out &&
git rev-parse >expect \
L2:three R2:three \
L2:three R2:three &&
git rev-parse >actual \
:2:three :3:three &&
git hash-object >>actual \
three~HEAD three~R2^0 &&
test_cmp expect actual
)
'
......@@ -185,7 +179,7 @@ test_expect_success 'setup differently handled merges of rename/add conflict' '
git branch B &&
git checkout -b C &&
echo 10 >>a &&
echo "other content" >>new_a &&
test_write_lines 0 1 2 3 4 5 6 7 foobar >new_a &&
git add a new_a &&
test_tick && git commit -m C &&
......@@ -195,14 +189,14 @@ test_expect_success 'setup differently handled merges of rename/add conflict' '
git checkout B^0 &&
test_must_fail git merge C &&
git clean -f &&
git show :2:new_a >new_a &&
git add new_a &&
test_tick && git commit -m D &&
git tag D &&
git checkout C^0 &&
test_must_fail git merge B &&
rm new_a~HEAD new_a &&
printf "Incorrectly merged content" >>new_a &&
test_write_lines 0 1 2 3 4 5 6 7 bad_merge >new_a &&
git add -u &&
test_tick && git commit -m E &&
git tag E
......@@ -225,21 +219,74 @@ test_expect_success 'git detects differently handled merges conflict' '
test_line_count = 1 out &&
git rev-parse >expect \
D:new_a E:new_a &&
C:new_a D:new_a E:new_a &&
git rev-parse >actual \
:2:new_a :3:new_a &&
:1:new_a :2:new_a :3:new_a &&
test_cmp expect actual &&
git cat-file -p C:new_a >ours &&
git cat-file -p B:new_a >theirs &&
# Test that the two-way merge in new_a is as expected
git cat-file -p D:new_a >ours &&
git cat-file -p E:new_a >theirs &&
>empty &&
test_must_fail git merge-file \
-L "Temporary merge branch 1" \
-L "HEAD" \
-L "" \
-L "Temporary merge branch 2" \
-L "E^0" \
ours empty theirs &&
sed -e "s/^\([<=>]\)/\1\1\1/" ours >expect &&
git cat-file -p :1:new_a >actual &&
git hash-object new_a >actual &&
git hash-object ours >expect &&
test_cmp expect actual
)
'
# Repeat the above testcase with precisely the same setup, other than with
# the two merge bases having different orderings of commit timestamps so
# that they are reversed in the order they are provided to merge-recursive,
# so that we can improve code coverage.
test_expect_success 'git detects differently handled merges conflict, swapped' '
(
cd rename-add &&
# Difference #1: Do cleanup from previous testrun
git reset --hard &&
git clean -fdqx &&
# Difference #2: Change commit timestamps
btime=$(git log --no-walk --date=raw --format=%cd B | awk "{print \$1}") &&
ctime=$(git log --no-walk --date=raw --format=%cd C | awk "{print \$1}") &&
newctime=$(($btime+1)) &&
git fast-export --no-data --all | sed -e s/$ctime/$newctime/ | git fast-import --force --quiet &&
# End of differences; rest is copy-paste of last test
git checkout D^0 &&
test_must_fail git merge -s recursive E^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git ls-files -u >out &&
test_line_count = 3 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >expect \
C:new_a D:new_a E:new_a &&
git rev-parse >actual \
:1:new_a :2:new_a :3:new_a &&
test_cmp expect actual &&
# Test that the two-way merge in new_a is as expected
git cat-file -p D:new_a >ours &&
git cat-file -p E:new_a >theirs &&
>empty &&
test_must_fail git merge-file \
-L "HEAD" \
-L "" \
-L "E^0" \
ours empty theirs &&
sed -e "s/^\([<=>]\)/\1\1\1/" ours >expect &&
git hash-object new_a >actual &&
git hash-object ours >expect &&
test_cmp expect actual
)
'
......@@ -1402,4 +1449,349 @@ test_expect_failure 'check conflicting modes for regular file' '
)
'
# Setup:
# L1---L2
# / \ / \
# master X ?
# \ / \ /
# R1---R2
#
# Where:
# master has two files, named 'b' and 'a'
# branches L1 and R1 both modify each of the two files in conflicting ways
#
# L2 is a merge of R1 into L1; more on it later.
# R2 is a merge of L1 into R1; more on it later.
#
# X is an auto-generated merge-base used when merging L2 and R2.
# since X is a merge of L1 and R1, it has conflicting versions of each file
#
# More about L2 and R2:
# - both resolve the conflicts in 'b' and 'a' differently
# - L2 renames 'b' to 'm'
# - R2 renames 'a' to 'm'
#
# In the end, in file 'm' we have four different conflicting files (from
# two versions of 'b' and two of 'a'). In addition, if
# merge.conflictstyle is diff3, then the base version also has
# conflict markers of its own, leading to a total of three levels of
# conflict markers. This is a pretty weird corner case, but we just want
# to ensure that we handle it as well as practical.
test_expect_success 'setup nested conflicts' '
test_create_repo nested_conflicts &&
(
cd nested_conflicts &&
# Create some related files now
for i in $(test_seq 1 10)
do
echo Random base content line $i
done >initial &&
cp initial b_L1 &&
cp initial b_R1 &&
cp initial b_L2 &&
cp initial b_R2 &&
cp initial a_L1 &&
cp initial a_R1 &&
cp initial a_L2 &&
cp initial a_R2 &&
test_write_lines b b_L1 >>b_L1 &&
test_write_lines b b_R1 >>b_R1 &&
test_write_lines b b_L2 >>b_L2 &&
test_write_lines b b_R2 >>b_R2 &&
test_write_lines a a_L1 >>a_L1 &&
test_write_lines a a_R1 >>a_R1 &&
test_write_lines a a_L2 >>a_L2 &&
test_write_lines a a_R2 >>a_R2 &&
# Setup original commit (or merge-base), consisting of
# files named "b" and "a"
cp initial b &&
cp initial a &&
echo b >>b &&
echo a >>a &&
git add b a &&
test_tick && git commit -m initial &&
git branch L &&
git branch R &&
# Handle the left side
git checkout L &&
mv -f b_L1 b &&
mv -f a_L1 a &&
git add b a &&
test_tick && git commit -m "version L1 of files" &&
git tag L1 &&
# Handle the right side
git checkout R &&
mv -f b_R1 b &&
mv -f a_R1 a &&
git add b a &&
test_tick && git commit -m "verson R1 of files" &&
git tag R1 &&
# Create first merge on left side
git checkout L &&
test_must_fail git merge R1 &&
mv -f b_L2 b &&
mv -f a_L2 a &&
git add b a &&
git mv b m &&
test_tick && git commit -m "left merge, rename b->m" &&
git tag L2 &&
# Create first merge on right side
git checkout R &&
test_must_fail git merge L1 &&
mv -f b_R2 b &&
mv -f a_R2 a &&
git add b a &&
git mv a m &&
test_tick && git commit -m "right merge, rename a->m" &&
git tag R2
)
'
test_expect_success 'check nested conflicts' '
(
cd nested_conflicts &&
git clean -f &&
git checkout L2^0 &&
# Merge must fail; there is a conflict
test_must_fail git -c merge.conflictstyle=diff3 merge -s recursive R2^0 &&
# Make sure the index has the right number of entries
git ls-files -s >out &&
test_line_count = 2 out &&
git ls-files -u >out &&
test_line_count = 2 out &&
# Ensure we have the correct number of untracked files
git ls-files -o >out &&
test_line_count = 1 out &&
# Create a and b from virtual merge base X
git cat-file -p master:a >base &&
git cat-file -p L1:a >ours &&
git cat-file -p R1:a >theirs &&
test_must_fail git merge-file --diff3 \
-L "Temporary merge branch 1" \
-L "merged common ancestors" \
-L "Temporary merge branch 2" \
ours \
base \
theirs &&
sed -e "s/^\([<|=>]\)/\1\1/" ours >vmb_a &&
git cat-file -p master:b >base &&
git cat-file -p L1:b >ours &&
git cat-file -p R1:b >theirs &&
test_must_fail git merge-file --diff3 \
-L "Temporary merge branch 1" \
-L "merged common ancestors" \
-L "Temporary merge branch 2" \
ours \
base \
theirs &&
sed -e "s/^\([<|=>]\)/\1\1/" ours >vmb_b &&
# Compare :2:m to expected values
git cat-file -p L2:m >ours &&
git cat-file -p R2:b >theirs &&
test_must_fail git merge-file --diff3 \
-L "HEAD:m" \
-L "merged common ancestors:b" \
-L "R2^0:b" \
ours \
vmb_b \
theirs &&
sed -e "s/^\([<|=>]\)/\1\1/" ours >m_stage_2 &&
git cat-file -p :2:m >actual &&
test_cmp m_stage_2 actual &&
# Compare :3:m to expected values
git cat-file -p L2:a >ours &&
git cat-file -p R2:m >theirs &&
test_must_fail git merge-file --diff3 \
-L "HEAD:a" \
-L "merged common ancestors:a" \
-L "R2^0:m" \
ours \
vmb_a \
theirs &&
sed -e "s/^\([<|=>]\)/\1\1/" ours >m_stage_3 &&
git cat-file -p :3:m >actual &&
test_cmp m_stage_3 actual &&
# Compare m to expected contents
>empty &&
cp m_stage_2 expected_final_m &&
test_must_fail git merge-file --diff3 \
-L "HEAD" \
-L "merged common ancestors" \
-L "R2^0" \
expected_final_m \
empty \
m_stage_3 &&
test_cmp expected_final_m m
)
'
# Setup:
# L1---L2---L3
# / \ / \ / \
# master X1 X2 ?
# \ / \ / \ /
# R1---R2---R3
#
# Where:
# master has one file named 'content'
# branches L1 and R1 both modify each of the two files in conflicting ways
#
# L<n> (n>1) is a merge of R<n-1> into L<n-1>
# R<n> (n>1) is a merge of L<n-1> into R<n-1>
# L<n> and R<n> resolve the conflicts differently.
#
# X<n> is an auto-generated merge-base used when merging L<n+1> and R<n+1>.
# By construction, X1 has conflict markers due to conflicting versions.
# X2, due to using merge.conflictstyle=3, has nested conflict markers.
#
# So, merging R3 into L3 using merge.conflictstyle=3 should show the
# nested conflict markers from X2 in the base version -- that means we
# have three levels of conflict markers. Can we distinguish all three?
test_expect_success 'setup virtual merge base with nested conflicts' '
test_create_repo virtual_merge_base_has_nested_conflicts &&
(
cd virtual_merge_base_has_nested_conflicts &&
# Create some related files now
for i in $(test_seq 1 10)
do
echo Random base content line $i
done >content &&
# Setup original commit
git add content &&
test_tick && git commit -m initial &&
git branch L &&
git branch R &&
# Create L1
git checkout L &&
echo left >>content &&
git add content &&
test_tick && git commit -m "version L1 of content" &&
git tag L1 &&
# Create R1
git checkout R &&
echo right >>content &&
git add content &&
test_tick && git commit -m "verson R1 of content" &&
git tag R1 &&
# Create L2
git checkout L &&
test_must_fail git -c merge.conflictstyle=diff3 merge R1 &&
git checkout L1 content &&
test_tick && git commit -m "version L2 of content" &&
git tag L2 &&
# Create R2
git checkout R &&
test_must_fail git -c merge.conflictstyle=diff3 merge L1 &&
git checkout R1 content &&
test_tick && git commit -m "version R2 of content" &&
git tag R2 &&
# Create L3
git checkout L &&
test_must_fail git -c merge.conflictstyle=diff3 merge R2 &&
git checkout L1 content &&
test_tick && git commit -m "version L3 of content" &&
git tag L3 &&
# Create R3
git checkout R &&
test_must_fail git -c merge.conflictstyle=diff3 merge L2 &&
git checkout R1 content &&
test_tick && git commit -m "version R3 of content" &&
git tag R3
)
'
test_expect_success 'check virtual merge base with nested conflicts' '
(
cd virtual_merge_base_has_nested_conflicts &&
git checkout L3^0 &&
# Merge must fail; there is a conflict
test_must_fail git -c merge.conflictstyle=diff3 merge -s recursive R3^0 &&
# Make sure the index has the right number of entries
git ls-files -s >out &&
test_line_count = 3 out &&
git ls-files -u >out &&
test_line_count = 3 out &&
# Ensure we have the correct number of untracked files
git ls-files -o >out &&
test_line_count = 1 out &&
# Compare :[23]:content to expected values
git rev-parse L1:content R1:content >expect &&
git rev-parse :2:content :3:content >actual &&
test_cmp expect actual &&
# Imitate X1 merge base, except without long enough conflict
# markers because a subsequent sed will modify them. Put
# result into vmb.
git cat-file -p master:content >base &&
git cat-file -p L:content >left &&
git cat-file -p R:content >right &&
cp left merged-once &&
test_must_fail git merge-file --diff3 \
-L "Temporary merge branch 1" \
-L "merged common ancestors" \
-L "Temporary merge branch 2" \
merged-once \
base \
right &&
sed -e "s/^\([<|=>]\)/\1\1\1/" merged-once >vmb &&
# Imitate X2 merge base, overwriting vmb. Note that we
# extend both sets of conflict markers to make them longer
# with the sed command.
cp left merged-twice &&
test_must_fail git merge-file --diff3 \
-L "Temporary merge branch 1" \
-L "merged common ancestors" \
-L "Temporary merge branch 2" \
merged-twice \
vmb \
right &&
sed -e "s/^\([<|=>]\)/\1\1\1/" merged-twice >vmb &&
# Compare :1:content to expected value
git cat-file -p :1:content >actual &&
test_cmp vmb actual &&
# Determine expected content in final outer merge, compare to
# what the merge generated.
cp -f left expect &&
test_must_fail git merge-file --diff3 \
-L "HEAD" -L "merged common ancestors" -L "R3^0" \
expect vmb right &&
test_cmp expect content
)
'
test_done
......@@ -464,17 +464,28 @@ test_expect_success 'handle rename/rename (2to1) conflict correctly' '
git ls-files -u c >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 3 out &&
test_line_count = 1 out &&
test_path_is_missing a &&
test_path_is_missing b &&
test_path_is_file c~HEAD &&
test_path_is_file c~C^0 &&
git rev-parse >expect \
C:a B:b &&
git hash-object >actual \
c~HEAD c~C^0 &&
git rev-parse >expect \
C:a B:b &&
git rev-parse >actual \
:2:c :3:c &&
test_cmp expect actual &&
# Test that the two-way merge in new_a is as expected
git cat-file -p :2:c >>ours &&
git cat-file -p :3:c >>theirs &&
>empty &&
test_must_fail git merge-file \
-L "HEAD" \
-L "" \
-L "C^0" \
ours empty theirs &&
git hash-object c >actual &&
git hash-object ours >expect &&
test_cmp expect actual
)
'
......@@ -673,7 +684,7 @@ test_expect_success 'rename/rename/add-dest merge still knows about conflicting
git ls-files -u c >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 5 out &&
test_line_count = 1 out &&
git rev-parse >expect \
A:a C:b B:b C:c B:c &&
......@@ -681,14 +692,27 @@ test_expect_success 'rename/rename/add-dest merge still knows about conflicting
:1:a :2:b :3:b :2:c :3:c &&
test_cmp expect actual &&
git rev-parse >expect \
C:c B:c C:b B:b &&
git hash-object >actual \
c~HEAD c~B\^0 b~HEAD b~B\^0 &&
test_cmp expect actual &&
# Record some contents for re-doing merges
git cat-file -p A:a >stuff &&
git cat-file -p C:b >important_info &&
git cat-file -p B:c >precious_data &&
>empty &&
test_path_is_missing b &&
test_path_is_missing c
# Test the merge in b
test_must_fail git merge-file \
-L "HEAD" \
-L "" \
-L "B^0" \
important_info empty stuff &&
test_cmp important_info b &&
# Test the merge in c
test_must_fail git merge-file \
-L "HEAD" \
-L "" \
-L "B^0" \
stuff empty precious_data &&
test_cmp stuff c
)
'
......@@ -937,4 +961,283 @@ test_expect_failure 'mod6-check: chains of rename/rename(1to2) and rename/rename
)
'
test_conflicts_with_adds_and_renames() {
sideL=$1
sideR=$2
# Setup:
# L
# / \
# master ?
# \ /
# R
#
# Where:
# Both L and R have files named 'three' which collide. Each of
# the colliding files could have been involved in a rename, in
# which case there was a file named 'one' or 'two' that was
# modified on the opposite side of history and renamed into the
# collision on this side of history.
#
# Questions:
# 1) The index should contain both a stage 2 and stage 3 entry
# for the colliding file. Does it?
# 2) When renames are involved, the content merges are clean, so
# the index should reflect the content merges, not merely the
# version of the colliding file from the prior commit. Does
# it?
# 3) There should be a file in the worktree named 'three'
# containing the two-way merged contents of the content-merged
# versions of 'three' from each of the two colliding
# files. Is it present?
# 4) There should not be any three~* files in the working
# tree
test_expect_success "setup simple $sideL/$sideR conflict" '
test_create_repo simple_${sideL}_${sideR} &&
(
cd simple_${sideL}_${sideR} &&
# Create some related files now
for i in $(test_seq 1 10)
do
echo Random base content line $i
done >file_v1 &&
cp file_v1 file_v2 &&
echo modification >>file_v2 &&
cp file_v1 file_v3 &&
echo more stuff >>file_v3 &&
cp file_v3 file_v4 &&
echo yet more stuff >>file_v4 &&
# Use a tag to record both these files for simple
# access, and clean out these untracked files
git tag file_v1 $(git hash-object -w file_v1) &&
git tag file_v2 $(git hash-object -w file_v2) &&
git tag file_v3 $(git hash-object -w file_v3) &&
git tag file_v4 $(git hash-object -w file_v4) &&
git clean -f &&
# Setup original commit (or merge-base), consisting of
# files named "one" and "two" if renames were involved.
touch irrelevant_file &&
git add irrelevant_file &&
if [ $sideL = "rename" ]
then
git show file_v1 >one &&
git add one
fi &&
if [ $sideR = "rename" ]
then
git show file_v3 >two &&
git add two
fi &&
test_tick && git commit -m initial &&
git branch L &&
git branch R &&
# Handle the left side
git checkout L &&
if [ $sideL = "rename" ]
then
git mv one three
else
git show file_v2 >three &&
git add three
fi &&
if [ $sideR = "rename" ]
then
git show file_v4 >two &&
git add two
fi &&
test_tick && git commit -m L &&
# Handle the right side
git checkout R &&
if [ $sideL = "rename" ]
then
git show file_v2 >one &&
git add one
fi &&
if [ $sideR = "rename" ]
then
git mv two three
else
git show file_v4 >three &&
git add three
fi &&
test_tick && git commit -m R
)
'
test_expect_success "check simple $sideL/$sideR conflict" '
(
cd simple_${sideL}_${sideR} &&
git checkout L^0 &&
# Merge must fail; there is a conflict
test_must_fail git merge -s recursive R^0 &&
# Make sure the index has the right number of entries
git ls-files -s >out &&
test_line_count = 3 out &&
git ls-files -u >out &&
test_line_count = 2 out &&
# Ensure we have the correct number of untracked files
git ls-files -o >out &&
test_line_count = 1 out &&
# Nothing should have touched irrelevant_file
git rev-parse >actual \
:0:irrelevant_file \
:2:three \
:3:three &&
git rev-parse >expected \
master:irrelevant_file \
file_v2 \
file_v4 &&
test_cmp expected actual &&
# Make sure we have the correct merged contents for
# three
git show file_v1 >expected &&
cat <<-\EOF >>expected &&
<<<<<<< HEAD
modification
=======
more stuff
yet more stuff
>>>>>>> R^0
EOF
test_cmp expected three
)
'
}
test_conflicts_with_adds_and_renames rename rename
test_conflicts_with_adds_and_renames rename add
test_conflicts_with_adds_and_renames add rename
test_conflicts_with_adds_and_renames add add
# Setup:
# L
# / \
# master ?
# \ /
# R
#
# Where:
# master has two files, named 'one' and 'two'.
# branches L and R both modify 'one', in conflicting ways.
# branches L and R both modify 'two', in conflicting ways.
# branch L also renames 'one' to 'three'.
# branch R also renames 'two' to 'three'.
#
# So, we have four different conflicting files that all end up at path
# 'three'.
test_expect_success 'setup nested conflicts from rename/rename(2to1)' '
test_create_repo nested_conflicts_from_rename_rename &&
(
cd nested_conflicts_from_rename_rename &&
# Create some related files now
for i in $(test_seq 1 10)
do
echo Random base content line $i
done >file_v1 &&
cp file_v1 file_v2 &&
cp file_v1 file_v3 &&
cp file_v1 file_v4 &&
cp file_v1 file_v5 &&
cp file_v1 file_v6 &&
echo one >>file_v1 &&
echo uno >>file_v2 &&
echo eins >>file_v3 &&
echo two >>file_v4 &&
echo dos >>file_v5 &&
echo zwei >>file_v6 &&
# Setup original commit (or merge-base), consisting of
# files named "one" and "two".
mv file_v1 one &&
mv file_v4 two &&
git add one two &&
test_tick && git commit -m english &&
git branch L &&
git branch R &&
# Handle the left side
git checkout L &&
git mv one three &&
mv -f file_v2 three &&
mv -f file_v5 two &&
git add two three &&
test_tick && git commit -m spanish &&
# Handle the right side
git checkout R &&
git mv two three &&
mv -f file_v3 one &&
mv -f file_v6 three &&
git add one three &&
test_tick && git commit -m german
)
'
test_expect_success 'check nested conflicts from rename/rename(2to1)' '
(
cd nested_conflicts_from_rename_rename &&
git checkout L^0 &&
# Merge must fail; there is a conflict
test_must_fail git merge -s recursive R^0 &&
# Make sure the index has the right number of entries
git ls-files -s >out &&
test_line_count = 2 out &&
git ls-files -u >out &&
test_line_count = 2 out &&
# Ensure we have the correct number of untracked files
git ls-files -o >out &&
test_line_count = 1 out &&
# Compare :2:three to expected values
git cat-file -p master:one >base &&
git cat-file -p L:three >ours &&
git cat-file -p R:one >theirs &&
test_must_fail git merge-file \
-L "HEAD:three" -L "" -L "R^0:one" \
ours base theirs &&
sed -e "s/^\([<=>]\)/\1\1/" ours >L-three &&
git cat-file -p :2:three >expect &&
test_cmp expect L-three &&
# Compare :2:three to expected values
git cat-file -p master:two >base &&
git cat-file -p L:two >ours &&
git cat-file -p R:three >theirs &&
test_must_fail git merge-file \
-L "HEAD:two" -L "" -L "R^0:three" \
ours base theirs &&
sed -e "s/^\([<=>]\)/\1\1/" ours >R-three &&
git cat-file -p :3:three >expect &&
test_cmp expect R-three &&
# Compare three to expected contents
>empty &&
test_must_fail git merge-file \
-L "HEAD" -L "" -L "R^0" \
L-three empty R-three &&
test_cmp three L-three
)
'
test_done
......@@ -278,7 +278,7 @@ test_expect_success '1d-check: Directory renames cause a rename/rename(2to1) con
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 3 out &&
test_line_count = 1 out &&
git rev-parse >actual \
:0:x/b :0:x/c :0:x/d :0:x/e :0:x/m :0:x/n &&
......@@ -293,15 +293,16 @@ test_expect_success '1d-check: Directory renames cause a rename/rename(2to1) con
A:y/wham B:z/wham &&
test_cmp expect actual &&
test_path_is_missing x/wham &&
test_path_is_file x/wham~HEAD &&
test_path_is_file x/wham~B^0 &&
git hash-object >actual \
x/wham~HEAD x/wham~B^0 &&
git rev-parse >expect \
A:y/wham B:z/wham &&
test_cmp expect actual
# Test that the two-way merge in x/wham is as expected
git cat-file -p :2:x/wham >expect &&
git cat-file -p :3:x/wham >other &&
>empty &&
test_must_fail git merge-file \
-L "HEAD" \
-L "" \
-L "B^0" \
expect empty other &&
test_cmp expect x/wham
)
'
......@@ -1077,7 +1078,7 @@ test_expect_success '5c-check: Transitive rename would cause rename/rename/renam
git ls-files -u >out &&
test_line_count = 6 out &&
git ls-files -o >out &&
test_line_count = 3 out &&
test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:y/c :0:y/e &&
......@@ -1093,9 +1094,9 @@ test_expect_success '5c-check: Transitive rename would cause rename/rename/renam
test_cmp expect actual &&
git hash-object >actual \
w/d~HEAD w/d~B^0 z/d &&
z/d &&
git rev-parse >expect \
O:x/d B:w/d O:x/d &&
O:x/d &&
test_cmp expect actual &&
test_path_is_missing x/d &&
test_path_is_file y/d &&
......@@ -1670,7 +1671,7 @@ test_expect_success '7b-check: rename/rename(2to1), but only due to transitive r
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 3 out &&
test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:y/c :2:y/d :3:y/d &&
......@@ -1678,15 +1679,16 @@ test_expect_success '7b-check: rename/rename(2to1), but only due to transitive r
O:z/b O:z/c O:w/d O:x/d &&
test_cmp expect actual &&
test_path_is_missing y/d &&
test_path_is_file y/d~HEAD &&
test_path_is_file y/d~B^0 &&
git hash-object >actual \
y/d~HEAD y/d~B^0 &&
git rev-parse >expect \
O:w/d O:x/d &&
test_cmp expect actual
# Test that the two-way merge in y/d is as expected
git cat-file -p :2:y/d >expect &&
git cat-file -p :3:y/d >other &&
>empty &&
test_must_fail git merge-file \
-L "HEAD" \
-L "" \
-L "B^0" \
expect empty other &&
test_cmp expect y/d
)
'
......@@ -3161,11 +3163,48 @@ test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2)
)
'
test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2), other direction' '
(
cd 10c &&
git reset --hard &&
git clean -fdqx &&
git checkout B^0 &&
mkdir y &&
echo important >y/c &&
test_must_fail git merge -s recursive A^0 >out 2>err &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
test_i18ngrep "Refusing to lose untracked file at y/c; adding as y/c~HEAD instead" out &&
git ls-files -s >out &&
test_line_count = 6 out &&
git ls-files -u >out &&
test_line_count = 3 out &&
git ls-files -o >out &&
test_line_count = 3 out &&
git rev-parse >actual \
:0:y/a :0:y/b :0:x/d :1:x/c :3:w/c :2:y/c &&
git rev-parse >expect \
O:z/a O:z/b O:x/d O:x/c O:x/c O:x/c &&
test_cmp expect actual &&
git hash-object y/c~HEAD >actual &&
git rev-parse O:x/c >expect &&
test_cmp expect actual &&
echo important >expect &&
test_cmp expect y/c
)
'
# Testcase 10d, Delete untracked w/ dir rename/rename(2to1)
# Commit O: z/{a,b,c_1}, x/{d,e,f_2}
# Commit A: y/{a,b}, x/{d,e,f_2,wham_1} + untracked y/wham
# Commit B: z/{a,b,c_1,wham_2}, y/{d,e}
# Expected: Failed Merge; y/{a,b,d,e} + untracked y/{wham,wham~B^0,wham~HEAD}+
# Expected: Failed Merge; y/{a,b,d,e} + untracked y/{wham,wham~merged}+
# CONFLICT(rename/rename) z/c_1 vs x/f_2 -> y/wham
# ERROR_MSG(Refusing to lose untracked file at y/wham)
......@@ -3219,7 +3258,7 @@ test_expect_success '10d-check: Delete untracked with dir rename/rename(2to1)' '
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 4 out &&
test_line_count = 3 out &&
git rev-parse >actual \
:0:y/a :0:y/b :0:y/d :0:y/e :2:y/wham :3:y/wham &&
......@@ -3232,11 +3271,16 @@ test_expect_success '10d-check: Delete untracked with dir rename/rename(2to1)' '
echo important >expect &&
test_cmp expect y/wham &&
git hash-object >actual \
y/wham~B^0 y/wham~HEAD &&
git rev-parse >expect \
O:x/f O:z/c &&
test_cmp expect actual
# Test that the two-way merge in y/wham~merged is as expected
git cat-file -p :2:y/wham >expect &&
git cat-file -p :3:y/wham >other &&
>empty &&
test_must_fail git merge-file \
-L "HEAD" \
-L "" \
-L "B^0" \
expect empty other &&
test_cmp expect y/wham~merged
)
'
......@@ -3665,7 +3709,7 @@ test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rena
git ls-files -u >out &&
test_line_count = 4 out &&
git ls-files -o >out &&
test_line_count = 4 out &&
test_line_count = 3 out &&
echo different >expected &&
echo mods >>expected &&
......@@ -3677,11 +3721,17 @@ test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rena
O:z/a O:z/b O:x/d O:x/c O:x/c A:y/c O:x/c &&
test_cmp expect actual &&
git hash-object >actual \
y/c~B^0 y/c~HEAD &&
git rev-parse >expect \
O:x/c A:y/c &&
test_cmp expect actual
# See if y/c~merged has expected contents; requires manually
# doing the expected file merge
git cat-file -p A:y/c >c1 &&
git cat-file -p B:z/c >c2 &&
>empty &&
test_must_fail git merge-file \
-L "HEAD" \
-L "" \
-L "B^0" \
c1 empty c2 &&
test_cmp c1 y/c~merged
)
'
......@@ -3689,7 +3739,7 @@ test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rena
# Commit O: z/{a,b}, x/{c_1,d_2}
# Commit A: y/{a,b,wham_1}, x/d_2, except y/wham has uncommitted mods
# Commit B: z/{a,b,wham_2}, x/c_1
# Expected: Failed Merge; y/{a,b} + untracked y/{wham~B^0,wham~B^HEAD} +
# Expected: Failed Merge; y/{a,b} + untracked y/{wham~merged} +
# y/wham with dirty changes from before merge +
# CONFLICT(rename/rename) x/c vs x/d -> y/wham
# ERROR_MSG(Refusing to lose dirty file at y/wham)
......@@ -3741,24 +3791,30 @@ test_expect_success '11f-check: Avoid deleting not-uptodate with dir rename/rena
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 4 out &&
test_line_count = 3 out &&
test_seq 1 10 >expected &&
echo important >>expected &&
test_cmp expected y/wham &&
test_must_fail git rev-parse :1:y/wham &&
git hash-object >actual \
y/wham~B^0 y/wham~HEAD &&
git rev-parse >expect \
O:x/d O:x/c &&
test_cmp expect actual &&
git rev-parse >actual \
:0:y/a :0:y/b :2:y/wham :3:y/wham &&
git rev-parse >expect \
O:z/a O:z/b O:x/c O:x/d &&
test_cmp expect actual
test_cmp expect actual &&
# Test that the two-way merge in y/wham~merged is as expected
git cat-file -p :2:y/wham >expect &&
git cat-file -p :3:y/wham >other &&
>empty &&
test_must_fail git merge-file \
-L "HEAD" \
-L "" \
-L "B^0" \
expect empty other &&
test_cmp expect y/wham~merged
)
'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册