2011-08-12 13:19:34 +08:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description="recursive merge corner cases w/ renames but not criss-crosses"
|
|
|
|
# t6036 has corner cases that involve both criss-cross merges and renames
|
|
|
|
|
2020-11-19 07:44:38 +08:00
|
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
tests: mark tests relying on the current default for `init.defaultBranch`
In addition to the manual adjustment to let the `linux-gcc` CI job run
the test suite with `master` and then with `main`, this patch makes sure
that GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME is set in all test scripts
that currently rely on the initial branch name being `master by default.
To determine which test scripts to mark up, the first step was to
force-set the default branch name to `master` in
- all test scripts that contain the keyword `master`,
- t4211, which expects `t/t4211/history.export` with a hard-coded ref to
initialize the default branch,
- t5560 because it sources `t/t556x_common` which uses `master`,
- t8002 and t8012 because both source `t/annotate-tests.sh` which also
uses `master`)
This trick was performed by this command:
$ sed -i '/^ *\. \.\/\(test-lib\|lib-\(bash\|cvs\|git-svn\)\|gitweb-lib\)\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' $(git grep -l master t/t[0-9]*.sh) \
t/t4211*.sh t/t5560*.sh t/t8002*.sh t/t8012*.sh
After that, careful, manual inspection revealed that some of the test
scripts containing the needle `master` do not actually rely on a
specific default branch name: either they mention `master` only in a
comment, or they initialize that branch specificially, or they do not
actually refer to the current default branch. Therefore, the
aforementioned modification was undone in those test scripts thusly:
$ git checkout HEAD -- \
t/t0027-auto-crlf.sh t/t0060-path-utils.sh \
t/t1011-read-tree-sparse-checkout.sh \
t/t1305-config-include.sh t/t1309-early-config.sh \
t/t1402-check-ref-format.sh t/t1450-fsck.sh \
t/t2024-checkout-dwim.sh \
t/t2106-update-index-assume-unchanged.sh \
t/t3040-subprojects-basic.sh t/t3301-notes.sh \
t/t3308-notes-merge.sh t/t3423-rebase-reword.sh \
t/t3436-rebase-more-options.sh \
t/t4015-diff-whitespace.sh t/t4257-am-interactive.sh \
t/t5323-pack-redundant.sh t/t5401-update-hooks.sh \
t/t5511-refspec.sh t/t5526-fetch-submodules.sh \
t/t5529-push-errors.sh t/t5530-upload-pack-error.sh \
t/t5548-push-porcelain.sh \
t/t5552-skipping-fetch-negotiator.sh \
t/t5572-pull-submodule.sh t/t5608-clone-2gb.sh \
t/t5614-clone-submodules-shallow.sh \
t/t7508-status.sh t/t7606-merge-custom.sh \
t/t9302-fast-import-unpack-limit.sh
We excluded one set of test scripts in these commands, though: the range
of `git p4` tests. The reason? `git p4` stores the (foreign) remote
branch in the branch called `p4/master`, which is obviously not the
default branch. Manual analysis revealed that only five of these tests
actually require a specific default branch name to pass; They were
modified thusly:
$ sed -i '/^ *\. \.\/lib-git-p4\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' t/t980[0167]*.sh t/t9811*.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-19 07:44:19 +08:00
|
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
|
2011-08-12 13:19:34 +08:00
|
|
|
. ./test-lib.sh
|
2020-10-27 01:01:36 +08:00
|
|
|
. "$TEST_DIRECTORY"/lib-merge.sh
|
2011-08-12 13:19:34 +08:00
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_delete_untracked () {
|
2018-05-24 15:04:35 +08:00
|
|
|
test_create_repo rename-delete-untracked &&
|
|
|
|
(
|
|
|
|
cd rename-delete-untracked &&
|
|
|
|
|
|
|
|
echo "A pretty inscription" >ring &&
|
|
|
|
git add ring &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m beginning &&
|
|
|
|
|
|
|
|
git branch people &&
|
|
|
|
git checkout -b rename-the-ring &&
|
|
|
|
git mv ring one-ring-to-rule-them-all &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m fullname &&
|
|
|
|
|
|
|
|
git checkout people &&
|
|
|
|
git rm ring &&
|
|
|
|
echo gollum >owner &&
|
|
|
|
git add owner &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m track-people-instead-of-objects &&
|
|
|
|
echo "Myyy PRECIOUSSS" >ring
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
2011-08-12 13:19:34 +08:00
|
|
|
|
merge-recursive: Fix deletion of untracked file in rename/delete conflicts
In the recursive case (o->call_depth > 0), we do not modify the working
directory. However, when o->call_depth==0, file renames can mean we need
to delete the old filename from the working copy. Since there have been
lots of changes and mistakes here, let's go through the details. Let's
start with a simple explanation of what we are trying to achieve:
Original goal: If a file is renamed on the side of history being merged
into head, the filename serving as the source of that rename needs to be
removed from the working directory.
The path to getting the above statement implemented in merge-recursive took
several steps. The relevant bits of code may be instructive to keep in
mind for the explanation, especially since an English-only description
involves double negatives that are hard to follow. These bits of code are:
int remove_file(..., const char *path, int no_wd)
{
...
int update_working_directory = !o->call_depth && !no_wd;
and
remove_file(o, 1, ren1_src, <expression>);
Where the choice for <expression> has morphed over time:
65ac6e9 (merge-recursive: adjust to loosened "working file clobbered"
check 2006-10-27), introduced the "no_wd" parameter to remove_file() and
used "1" for <expression>. This meant ren1_src was never deleted, leaving
it around in the working copy.
In 8371234 (Remove uncontested renamed files during merge. 2006-12-13),
<expression> was changed to "index_only" (where index_only ==
!!o->call_depth; see b7fa51da). This was equivalent to using "0" for
<expression> (due to the early logic in remove_file), and is orthogonal to
the condition we actually want to check at this point; it resulted in the
source file being removed except when index_only was false. This was
problematic because the file could have been renamed on the side of history
including head, in which case ren1_src could correspond to an untracked
file that should not be deleted.
In 183d797 (Keep untracked files not involved in a merge. 2007-02-04),
<expression> was changed to "index_only || stage == 3". While this gives
correct behavior, the "index_only ||" portion of <expression> is
unnecessary and makes the code slightly harder to follow.
There were also two further changes to this expression, though without
any change in behavior. First in b7fa51d (merge-recursive: get rid of the
index_only global variable 2008-09-02), it was changed to "o->call_depth
|| stage == 3". (index_only == !!o->call_depth). Later, in 41d70bd6
(merge-recursive: Small code clarification -- variable name and comments),
this was changed to "o->call_depth || renamed_stage == 2" (where stage was
renamed to other_stage and renamed_stage == other_stage ^ 1).
So we ended with <expression> being "o->call_depth || renamed_stage == 2".
But the "o->call_depth ||" piece was unnecessary. We can remove it,
leaving us with <expression> being "renamed_stage == 2". This doesn't
change behavior at all, but it makes the code clearer. Which is good,
because it's about to get uglier.
Corrected goal: If a file is renamed on the side of history being merged
into head, the filename serving as the source of that rename needs to be
removed from the working directory *IF* that file is tracked in head AND
the file tracked in head is related to the original file.
Note that the only difference between the original goal and the corrected
goal is the two extra conditions added at the end. The first condition is
relevant in a rename/delete conflict. If the file was deleted on the
HEAD side of the merge and an untracked file of the same name was added to
the working copy, then without that extra condition the untracked file
will be erroneously deleted. This changes <expression> to "renamed_stage
== 2 || !was_tracked(ren1_src)".
The second additional condition is relevant in two cases.
The first case the second condition can occur is when a file is deleted
and a completely different file is added with the same name. To my
knowledge, merge-recursive has no mechanism for detecting deleted-and-
replaced-by-different-file cases, so I am simply punting on this
possibility.
The second case for the second condition to occur is when there is a
rename/rename/add-source conflict. That is, when the original file was
renamed on both sides of history AND the original filename is being
re-used by some unrelated (but tracked) content. This case also presents
some additional difficulties for us since we cannot currently detect these
rename/rename/add-source conflicts; as long as the rename detection logic
"optimizes" by ignoring filenames that are present at both ends of the
diff, these conflicts will go unnoticed. However, rename/rename conflicts
are handled by an entirely separate codepath not being discussed here, so
this case is not relevant for the line of code under consideration.
In summary:
Change <expression> from "o->call_depth || renamed_stage == 2" to
"renamed_stage == 2 || !was_tracked(ren1_src)", in order to remove
unnecessary code and avoid deleting untracked files.
96 lines of explanation in the changelog to describe a one-line fix...
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:20:03 +08:00
|
|
|
test_expect_success "Does git preserve Gollum's precious artifact?" '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_delete_untracked &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
|
|
|
cd rename-delete-untracked &&
|
2011-08-12 13:19:34 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
test_must_fail git merge -s recursive rename-the-ring &&
|
|
|
|
|
|
|
|
# Make sure git did not delete an untracked file
|
2018-05-24 15:04:37 +08:00
|
|
|
test_path_is_file ring
|
2018-05-24 15:04:35 +08:00
|
|
|
)
|
2011-08-12 13:19:34 +08:00
|
|
|
'
|
|
|
|
|
2011-08-12 13:19:35 +08:00
|
|
|
# Testcase setup for rename/modify/add-source:
|
|
|
|
# Commit A: new file: a
|
|
|
|
# Commit B: modify a slightly
|
|
|
|
# Commit C: rename a->b, add completely different a
|
|
|
|
#
|
|
|
|
# We should be able to merge B & C cleanly
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_modify_add_source () {
|
2018-05-24 15:04:35 +08:00
|
|
|
test_create_repo rename-modify-add-source &&
|
|
|
|
(
|
|
|
|
cd rename-modify-add-source &&
|
|
|
|
|
|
|
|
printf "1\n2\n3\n4\n5\n6\n7\n" >a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m A &&
|
|
|
|
git tag A &&
|
|
|
|
|
|
|
|
git checkout -b B A &&
|
|
|
|
echo 8 >>a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m B &&
|
|
|
|
|
|
|
|
git checkout -b C A &&
|
|
|
|
git mv a b &&
|
|
|
|
echo something completely different >a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m C
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
2011-08-12 13:19:35 +08:00
|
|
|
|
|
|
|
test_expect_failure 'rename/modify/add-source conflict resolvable' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_modify_add_source &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
|
|
|
cd rename-modify-add-source &&
|
|
|
|
|
|
|
|
git checkout B^0 &&
|
2011-08-12 13:19:35 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
git merge -s recursive C^0 &&
|
2011-08-12 13:19:35 +08:00
|
|
|
|
2018-05-24 15:04:38 +08:00
|
|
|
git rev-parse >expect \
|
|
|
|
B:a C:a &&
|
|
|
|
git rev-parse >actual \
|
|
|
|
b c &&
|
|
|
|
test_cmp expect actual
|
2018-05-24 15:04:35 +08:00
|
|
|
)
|
2011-08-12 13:19:35 +08:00
|
|
|
'
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_break_detection_1 () {
|
2018-05-24 15:04:35 +08:00
|
|
|
test_create_repo break-detection-1 &&
|
|
|
|
(
|
|
|
|
cd break-detection-1 &&
|
|
|
|
|
|
|
|
printf "1\n2\n3\n4\n5\n" >a &&
|
|
|
|
echo foo >b &&
|
|
|
|
git add a b &&
|
|
|
|
git commit -m A &&
|
|
|
|
git tag A &&
|
|
|
|
|
|
|
|
git checkout -b B A &&
|
|
|
|
git mv a c &&
|
|
|
|
echo "Completely different content" >a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m B &&
|
|
|
|
|
|
|
|
git checkout -b C A &&
|
|
|
|
echo 6 >>a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m C
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
2011-08-12 13:19:36 +08:00
|
|
|
|
|
|
|
test_expect_failure 'conflict caused if rename not detected' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_break_detection_1 &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
|
|
|
cd break-detection-1 &&
|
|
|
|
|
|
|
|
git checkout -q C^0 &&
|
|
|
|
git merge -s recursive B^0 &&
|
2011-08-12 13:19:36 +08:00
|
|
|
|
2018-05-24 15:04:36 +08:00
|
|
|
git ls-files -s >out &&
|
|
|
|
test_line_count = 3 out &&
|
|
|
|
git ls-files -u >out &&
|
|
|
|
test_line_count = 0 out &&
|
|
|
|
git ls-files -o >out &&
|
|
|
|
test_line_count = 1 out &&
|
2011-08-12 13:19:36 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
test_line_count = 6 c &&
|
2018-05-24 15:04:38 +08:00
|
|
|
git rev-parse >expect \
|
|
|
|
B:a A:b &&
|
|
|
|
git rev-parse >actual \
|
|
|
|
:0:a :0:b &&
|
|
|
|
test_cmp expect actual
|
2018-05-24 15:04:35 +08:00
|
|
|
)
|
2011-08-12 13:19:36 +08:00
|
|
|
'
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_break_detection_2 () {
|
2018-05-24 15:04:35 +08:00
|
|
|
test_create_repo break-detection-2 &&
|
|
|
|
(
|
|
|
|
cd break-detection-2 &&
|
|
|
|
|
|
|
|
printf "1\n2\n3\n4\n5\n" >a &&
|
|
|
|
echo foo >b &&
|
|
|
|
git add a b &&
|
|
|
|
git commit -m A &&
|
|
|
|
git tag A &&
|
|
|
|
|
|
|
|
git checkout -b D A &&
|
|
|
|
echo 7 >>a &&
|
|
|
|
git add a &&
|
|
|
|
git mv a c &&
|
|
|
|
echo "Completely different content" >a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m D &&
|
|
|
|
|
|
|
|
git checkout -b E A &&
|
|
|
|
git rm a &&
|
|
|
|
echo "Completely different content" >>a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m E
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
2011-08-12 13:19:36 +08:00
|
|
|
|
|
|
|
test_expect_failure 'missed conflict if rename not detected' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_break_detection_2 &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
|
|
|
cd break-detection-2 &&
|
|
|
|
|
|
|
|
git checkout -q E^0 &&
|
|
|
|
test_must_fail git merge -s recursive D^0
|
|
|
|
)
|
2011-08-12 13:19:36 +08:00
|
|
|
'
|
|
|
|
|
2011-08-12 13:19:37 +08:00
|
|
|
# Tests for undetected rename/add-source causing a file to erroneously be
|
|
|
|
# deleted (and for mishandled rename/rename(1to1) causing the same issue).
|
|
|
|
#
|
|
|
|
# This test uses a rename/rename(1to1)+add-source conflict (1to1 means the
|
|
|
|
# same file is renamed on both sides to the same thing; it should trigger
|
|
|
|
# the 1to2 logic, which it would do if the add-source didn't cause issues
|
|
|
|
# for git's rename detection):
|
|
|
|
# Commit A: new file: a
|
|
|
|
# Commit B: rename a->b
|
|
|
|
# Commit C: rename a->b, add unrelated a
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_break_detection_3 () {
|
2018-05-24 15:04:35 +08:00
|
|
|
test_create_repo break-detection-3 &&
|
|
|
|
(
|
|
|
|
cd break-detection-3 &&
|
|
|
|
|
|
|
|
printf "1\n2\n3\n4\n5\n" >a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m A &&
|
|
|
|
git tag A &&
|
|
|
|
|
|
|
|
git checkout -b B A &&
|
|
|
|
git mv a b &&
|
|
|
|
git commit -m B &&
|
|
|
|
|
|
|
|
git checkout -b C A &&
|
|
|
|
git mv a b &&
|
|
|
|
echo foobar >a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m C
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
2011-08-12 13:19:37 +08:00
|
|
|
|
|
|
|
test_expect_failure 'detect rename/add-source and preserve all data' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_break_detection_3 &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
|
|
|
cd break-detection-3 &&
|
|
|
|
|
|
|
|
git checkout B^0 &&
|
2011-08-12 13:19:37 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
git merge -s recursive C^0 &&
|
2011-08-12 13:19:37 +08:00
|
|
|
|
2018-05-24 15:04:36 +08:00
|
|
|
git ls-files -s >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -u >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -o >out &&
|
|
|
|
test_line_count = 1 out &&
|
2011-08-12 13:19:37 +08:00
|
|
|
|
2018-05-24 15:04:37 +08:00
|
|
|
test_path_is_file a &&
|
|
|
|
test_path_is_file b &&
|
2011-08-12 13:19:37 +08:00
|
|
|
|
2018-05-24 15:04:38 +08:00
|
|
|
git rev-parse >expect \
|
|
|
|
A:a C:a &&
|
|
|
|
git rev-parse >actual \
|
|
|
|
:0:b :0:a &&
|
|
|
|
test_cmp expect actual
|
2018-05-24 15:04:35 +08:00
|
|
|
)
|
2011-08-12 13:19:37 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_failure 'detect rename/add-source and preserve all data, merge other way' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_break_detection_3 &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
|
|
|
cd break-detection-3 &&
|
2011-08-12 13:19:37 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
git checkout C^0 &&
|
2011-08-12 13:19:37 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
git merge -s recursive B^0 &&
|
2011-08-12 13:19:37 +08:00
|
|
|
|
2018-05-24 15:04:36 +08:00
|
|
|
git ls-files -s >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -u >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -o >out &&
|
|
|
|
test_line_count = 1 out &&
|
2011-08-12 13:19:37 +08:00
|
|
|
|
2018-05-24 15:04:37 +08:00
|
|
|
test_path_is_file a &&
|
|
|
|
test_path_is_file b &&
|
2018-05-24 15:04:35 +08:00
|
|
|
|
2018-05-24 15:04:38 +08:00
|
|
|
git rev-parse >expect \
|
|
|
|
A:a C:a &&
|
|
|
|
git rev-parse >actual \
|
|
|
|
:0:b :0:a &&
|
|
|
|
test_cmp expect actual
|
2018-05-24 15:04:35 +08:00
|
|
|
)
|
2011-08-12 13:19:37 +08:00
|
|
|
'
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_directory () {
|
|
|
|
test_create_repo rename-directory-$1 &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
2019-10-23 05:22:51 +08:00
|
|
|
cd rename-directory-$1 &&
|
2018-05-24 15:04:35 +08:00
|
|
|
|
|
|
|
printf "1\n2\n3\n4\n5\n6\n" >file &&
|
|
|
|
git add file &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m base &&
|
|
|
|
git tag base &&
|
|
|
|
|
|
|
|
git checkout -b right &&
|
|
|
|
echo 7 >>file &&
|
|
|
|
mkdir newfile &&
|
|
|
|
echo junk >newfile/realfile &&
|
|
|
|
git add file newfile/realfile &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m right &&
|
|
|
|
|
|
|
|
git checkout -b left-conflict base &&
|
|
|
|
echo 8 >>file &&
|
|
|
|
git add file &&
|
|
|
|
git mv file newfile &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m left &&
|
|
|
|
|
|
|
|
git checkout -b left-clean base &&
|
|
|
|
echo 0 >newfile &&
|
|
|
|
cat file >>newfile &&
|
|
|
|
git add newfile &&
|
|
|
|
git rm file &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m left
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
|
2011-08-12 13:20:06 +08:00
|
|
|
test_expect_success 'rename/directory conflict + clean content merge' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_directory 1a &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
2019-10-23 05:22:51 +08:00
|
|
|
cd rename-directory-1a &&
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
git checkout left-clean^0 &&
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
test_must_fail git merge -s recursive right^0 &&
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
|
2018-05-24 15:04:36 +08:00
|
|
|
git ls-files -s >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -u >out &&
|
|
|
|
test_line_count = 1 out &&
|
|
|
|
git ls-files -o >out &&
|
merge tests: expect improved directory/file conflict handling in ort
merge-recursive.c is built on the idea of running unpack_trees() and
then "doing minor touch-ups" to get the result. Unfortunately,
unpack_trees() was run in an update-as-it-goes mode, leading
merge-recursive.c to follow suit and end up with an immediate evaluation
and fix-it-up-as-you-go design. Some things like directory/file
conflicts are not well representable in the index data structure, and
required special extra code to handle. But then when it was discovered
that rename/delete conflicts could also be involved in directory/file
conflicts, the special directory/file conflict handling code had to be
copied to the rename/delete codepath. ...and then it had to be copied
for modify/delete, and for rename/rename(1to2) conflicts, ...and yet it
still missed some. Further, when it was discovered that there were also
file/submodule conflicts and submodule/directory conflicts, we needed to
copy the special submodule handling code to all the special cases
throughout the codebase.
And then it was discovered that our handling of directory/file conflicts
was suboptimal because it would create untracked files to store the
contents of the conflicting file, which would not be cleaned up if
someone were to run a 'git merge --abort' or 'git rebase --abort'. It
was also difficult or scary to try to add or remove the index entries
corresponding to these files given the directory/file conflict in the
index. But changing merge-recursive.c to handle these correctly was a
royal pain because there were so many sites in the code with similar but
not identical code for handling directory/file/submodule conflicts that
would all need to be updated.
I have worked hard to push all directory/file/submodule conflict
handling in merge-ort through a single codepath, and avoid creating
untracked files for storing tracked content (it does record things at
alternate paths, but makes sure they have higher-order stages in the
index).
Since updating merge-recursive is too much work and we don't want to
destabilize it, instead update the testsuite to have different
expectations for relevant directory/file/submodule conflict tests.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-27 01:01:37 +08:00
|
|
|
if test "$GIT_TEST_MERGE_ALGORITHM" = ort
|
|
|
|
then
|
|
|
|
test_line_count = 1 out
|
|
|
|
else
|
|
|
|
test_line_count = 2 out
|
|
|
|
fi &&
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
echo 0 >expect &&
|
|
|
|
git cat-file -p base:file >>expect &&
|
|
|
|
echo 7 >>expect &&
|
|
|
|
test_cmp expect newfile~HEAD &&
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
|
2018-05-24 15:04:37 +08:00
|
|
|
test_path_is_file newfile/realfile &&
|
|
|
|
test_path_is_file newfile~HEAD
|
2018-05-24 15:04:35 +08:00
|
|
|
)
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
'
|
|
|
|
|
2011-08-12 13:20:09 +08:00
|
|
|
test_expect_success 'rename/directory conflict + content merge conflict' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_directory 1b &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
2019-10-23 05:22:51 +08:00
|
|
|
cd rename-directory-1b &&
|
2018-05-24 15:04:35 +08:00
|
|
|
|
|
|
|
git reset --hard &&
|
|
|
|
git clean -fdqx &&
|
|
|
|
|
|
|
|
git checkout left-conflict^0 &&
|
|
|
|
|
|
|
|
test_must_fail git merge -s recursive right^0 &&
|
|
|
|
|
2018-05-24 15:04:36 +08:00
|
|
|
git ls-files -s >out &&
|
|
|
|
test_line_count = 4 out &&
|
|
|
|
git ls-files -u >out &&
|
|
|
|
test_line_count = 3 out &&
|
|
|
|
git ls-files -o >out &&
|
merge tests: expect improved directory/file conflict handling in ort
merge-recursive.c is built on the idea of running unpack_trees() and
then "doing minor touch-ups" to get the result. Unfortunately,
unpack_trees() was run in an update-as-it-goes mode, leading
merge-recursive.c to follow suit and end up with an immediate evaluation
and fix-it-up-as-you-go design. Some things like directory/file
conflicts are not well representable in the index data structure, and
required special extra code to handle. But then when it was discovered
that rename/delete conflicts could also be involved in directory/file
conflicts, the special directory/file conflict handling code had to be
copied to the rename/delete codepath. ...and then it had to be copied
for modify/delete, and for rename/rename(1to2) conflicts, ...and yet it
still missed some. Further, when it was discovered that there were also
file/submodule conflicts and submodule/directory conflicts, we needed to
copy the special submodule handling code to all the special cases
throughout the codebase.
And then it was discovered that our handling of directory/file conflicts
was suboptimal because it would create untracked files to store the
contents of the conflicting file, which would not be cleaned up if
someone were to run a 'git merge --abort' or 'git rebase --abort'. It
was also difficult or scary to try to add or remove the index entries
corresponding to these files given the directory/file conflict in the
index. But changing merge-recursive.c to handle these correctly was a
royal pain because there were so many sites in the code with similar but
not identical code for handling directory/file/submodule conflicts that
would all need to be updated.
I have worked hard to push all directory/file/submodule conflict
handling in merge-ort through a single codepath, and avoid creating
untracked files for storing tracked content (it does record things at
alternate paths, but makes sure they have higher-order stages in the
index).
Since updating merge-recursive is too much work and we don't want to
destabilize it, instead update the testsuite to have different
expectations for relevant directory/file/submodule conflict tests.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-27 01:01:37 +08:00
|
|
|
if test "$GIT_TEST_MERGE_ALGORITHM" = ort
|
|
|
|
then
|
|
|
|
test_line_count = 1 out
|
|
|
|
else
|
|
|
|
test_line_count = 2 out
|
|
|
|
fi &&
|
2018-05-24 15:04:35 +08:00
|
|
|
|
|
|
|
git cat-file -p left-conflict:newfile >left &&
|
|
|
|
git cat-file -p base:file >base &&
|
|
|
|
git cat-file -p right:file >right &&
|
|
|
|
test_must_fail git merge-file \
|
|
|
|
-L "HEAD:newfile" \
|
|
|
|
-L "" \
|
|
|
|
-L "right^0:file" \
|
|
|
|
left base right &&
|
|
|
|
test_cmp left newfile~HEAD &&
|
|
|
|
|
merge tests: expect improved directory/file conflict handling in ort
merge-recursive.c is built on the idea of running unpack_trees() and
then "doing minor touch-ups" to get the result. Unfortunately,
unpack_trees() was run in an update-as-it-goes mode, leading
merge-recursive.c to follow suit and end up with an immediate evaluation
and fix-it-up-as-you-go design. Some things like directory/file
conflicts are not well representable in the index data structure, and
required special extra code to handle. But then when it was discovered
that rename/delete conflicts could also be involved in directory/file
conflicts, the special directory/file conflict handling code had to be
copied to the rename/delete codepath. ...and then it had to be copied
for modify/delete, and for rename/rename(1to2) conflicts, ...and yet it
still missed some. Further, when it was discovered that there were also
file/submodule conflicts and submodule/directory conflicts, we needed to
copy the special submodule handling code to all the special cases
throughout the codebase.
And then it was discovered that our handling of directory/file conflicts
was suboptimal because it would create untracked files to store the
contents of the conflicting file, which would not be cleaned up if
someone were to run a 'git merge --abort' or 'git rebase --abort'. It
was also difficult or scary to try to add or remove the index entries
corresponding to these files given the directory/file conflict in the
index. But changing merge-recursive.c to handle these correctly was a
royal pain because there were so many sites in the code with similar but
not identical code for handling directory/file/submodule conflicts that
would all need to be updated.
I have worked hard to push all directory/file/submodule conflict
handling in merge-ort through a single codepath, and avoid creating
untracked files for storing tracked content (it does record things at
alternate paths, but makes sure they have higher-order stages in the
index).
Since updating merge-recursive is too much work and we don't want to
destabilize it, instead update the testsuite to have different
expectations for relevant directory/file/submodule conflict tests.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-27 01:01:37 +08:00
|
|
|
git rev-parse >expect \
|
|
|
|
base:file left-conflict:newfile right:file &&
|
|
|
|
if test "$GIT_TEST_MERGE_ALGORITHM" = ort
|
|
|
|
then
|
|
|
|
git rev-parse >actual \
|
|
|
|
:1:newfile~HEAD :2:newfile~HEAD :3:newfile~HEAD
|
|
|
|
else
|
|
|
|
git rev-parse >actual \
|
|
|
|
:1:newfile :2:newfile :3:newfile
|
|
|
|
fi &&
|
2018-07-02 08:24:02 +08:00
|
|
|
test_cmp expect actual &&
|
2018-05-24 15:04:35 +08:00
|
|
|
|
2018-05-24 15:04:37 +08:00
|
|
|
test_path_is_file newfile/realfile &&
|
|
|
|
test_path_is_file newfile~HEAD
|
2018-05-24 15:04:35 +08:00
|
|
|
)
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
'
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_directory_2 () {
|
2018-05-24 15:04:35 +08:00
|
|
|
test_create_repo rename-directory-2 &&
|
|
|
|
(
|
|
|
|
cd rename-directory-2 &&
|
|
|
|
|
|
|
|
mkdir sub &&
|
|
|
|
printf "1\n2\n3\n4\n5\n6\n" >sub/file &&
|
|
|
|
git add sub/file &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m base &&
|
|
|
|
git tag base &&
|
|
|
|
|
|
|
|
git checkout -b right &&
|
|
|
|
echo 7 >>sub/file &&
|
|
|
|
git add sub/file &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m right &&
|
|
|
|
|
|
|
|
git checkout -b left base &&
|
|
|
|
echo 0 >newfile &&
|
|
|
|
cat sub/file >>newfile &&
|
|
|
|
git rm sub/file &&
|
|
|
|
mv newfile sub &&
|
|
|
|
git add sub &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m left
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
|
|
|
|
test_expect_success 'disappearing dir in rename/directory conflict handled' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_directory_2 &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
|
|
|
cd rename-directory-2 &&
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
git checkout left^0 &&
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
git merge -s recursive right^0 &&
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
|
2018-05-24 15:04:36 +08:00
|
|
|
git ls-files -s >out &&
|
|
|
|
test_line_count = 1 out &&
|
|
|
|
git ls-files -u >out &&
|
|
|
|
test_line_count = 0 out &&
|
|
|
|
git ls-files -o >out &&
|
|
|
|
test_line_count = 1 out &&
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
echo 0 >expect &&
|
|
|
|
git cat-file -p base:sub/file >>expect &&
|
|
|
|
echo 7 >>expect &&
|
|
|
|
test_cmp expect sub &&
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
|
2018-05-24 15:04:37 +08:00
|
|
|
test_path_is_file sub
|
2018-05-24 15:04:35 +08:00
|
|
|
)
|
t6042: Add tests for content issues with modify/rename/directory conflicts
Add testcases that cover a variety of merge issues with files being
renamed and modified on different sides of history, when there are
directories possibly conflicting with the rename location.
Case 1:
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a non-conflicting
way but is renamed to the location of the new directory.
Case 2:
[Same as case 1, but there is also a content conflict. In detail:]
On one side of history, a file is modified and a new directory is added.
On the other side of history, the file is modified in a conflicting way
and it is renamed to the location of the new directory.
Case 3:
[Similar to case 1, but the "conflicting" directory is the directory
where the file original resided. In detail:]
On one side of history, a file is modified. On the other side of history,
the file is modified in a non-conflicting way, but the directory it was
under is removed and the file is renamed to the location of the directory
it used to reside in (i.e. 'sub/file' gets renamed to 'sub'). This is
flagged as a directory/rename conflict, but should be able to be resolved
since the directory can be cleanly removed by the merge.
One branch renames a file and makes a file where the directory the renamed
file used to be in, and the other branch updates the file in
place. Merging them should resolve it cleanly as long as the content level
change on the branches do not overlap and rename is detected, or should
leave conflict without losing information.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:38 +08:00
|
|
|
'
|
|
|
|
|
merge-recursive: restore accidentally dropped setting of path
In commit 8daec1df03de ("merge-recursive: switch from (oid,mode) pairs
to a diff_filespec", 2019-04-05), we actually switched from
(oid,mode,path) triplets to a diff_filespec -- but most callsites in the
patch only needed to worry about oid and mode so the commit message
focused on that. The oversight in the commit message apparently spilled
over to the code as well; one of the dozen or so callsites accidentally
dropped the setting of the path in the conversion. Restore the path
setting in that location.
Also, this pointed out that our testsuite was lacking a good rename/add
test, at least one that involved the need for merge content with the
rename. Add such a test, and since rename/add vs. add/rename could
possibly be important, redo the merge the opposite direction to make
sure we don't have issues with the direction of the merge. These
testcases failed before restoring the setting of path, but with the
paths appropriately set the testcases both pass.
Reported-by: Ben Humphreys <behumphreys@atlassian.com>
Based-on-patch-by: SZEDER Gábor <szeder.dev@gmail.com>
Tested-by: Ben Humphreys <behumphreys@atlassian.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-06-05 04:27:50 +08:00
|
|
|
# Test for basic rename/add-dest conflict, with rename needing content merge:
|
|
|
|
# Commit O: a
|
|
|
|
# Commit A: rename a->b, modifying b too
|
|
|
|
# Commit B: modify a, add different b
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_with_content_merge_and_add () {
|
|
|
|
test_create_repo rename-with-content-merge-and-add-$1 &&
|
merge-recursive: restore accidentally dropped setting of path
In commit 8daec1df03de ("merge-recursive: switch from (oid,mode) pairs
to a diff_filespec", 2019-04-05), we actually switched from
(oid,mode,path) triplets to a diff_filespec -- but most callsites in the
patch only needed to worry about oid and mode so the commit message
focused on that. The oversight in the commit message apparently spilled
over to the code as well; one of the dozen or so callsites accidentally
dropped the setting of the path in the conversion. Restore the path
setting in that location.
Also, this pointed out that our testsuite was lacking a good rename/add
test, at least one that involved the need for merge content with the
rename. Add such a test, and since rename/add vs. add/rename could
possibly be important, redo the merge the opposite direction to make
sure we don't have issues with the direction of the merge. These
testcases failed before restoring the setting of path, but with the
paths appropriately set the testcases both pass.
Reported-by: Ben Humphreys <behumphreys@atlassian.com>
Based-on-patch-by: SZEDER Gábor <szeder.dev@gmail.com>
Tested-by: Ben Humphreys <behumphreys@atlassian.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-06-05 04:27:50 +08:00
|
|
|
(
|
2019-10-23 05:22:51 +08:00
|
|
|
cd rename-with-content-merge-and-add-$1 &&
|
merge-recursive: restore accidentally dropped setting of path
In commit 8daec1df03de ("merge-recursive: switch from (oid,mode) pairs
to a diff_filespec", 2019-04-05), we actually switched from
(oid,mode,path) triplets to a diff_filespec -- but most callsites in the
patch only needed to worry about oid and mode so the commit message
focused on that. The oversight in the commit message apparently spilled
over to the code as well; one of the dozen or so callsites accidentally
dropped the setting of the path in the conversion. Restore the path
setting in that location.
Also, this pointed out that our testsuite was lacking a good rename/add
test, at least one that involved the need for merge content with the
rename. Add such a test, and since rename/add vs. add/rename could
possibly be important, redo the merge the opposite direction to make
sure we don't have issues with the direction of the merge. These
testcases failed before restoring the setting of path, but with the
paths appropriately set the testcases both pass.
Reported-by: Ben Humphreys <behumphreys@atlassian.com>
Based-on-patch-by: SZEDER Gábor <szeder.dev@gmail.com>
Tested-by: Ben Humphreys <behumphreys@atlassian.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-06-05 04:27:50 +08:00
|
|
|
|
|
|
|
test_seq 1 5 >a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m O &&
|
|
|
|
git tag O &&
|
|
|
|
|
|
|
|
git checkout -b A O &&
|
|
|
|
git mv a b &&
|
|
|
|
test_seq 0 5 >b &&
|
|
|
|
git add b &&
|
|
|
|
git commit -m A &&
|
|
|
|
|
|
|
|
git checkout -b B O &&
|
|
|
|
echo 6 >>a &&
|
|
|
|
echo hello world >b &&
|
|
|
|
git add a b &&
|
|
|
|
git commit -m B
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
merge-recursive: restore accidentally dropped setting of path
In commit 8daec1df03de ("merge-recursive: switch from (oid,mode) pairs
to a diff_filespec", 2019-04-05), we actually switched from
(oid,mode,path) triplets to a diff_filespec -- but most callsites in the
patch only needed to worry about oid and mode so the commit message
focused on that. The oversight in the commit message apparently spilled
over to the code as well; one of the dozen or so callsites accidentally
dropped the setting of the path in the conversion. Restore the path
setting in that location.
Also, this pointed out that our testsuite was lacking a good rename/add
test, at least one that involved the need for merge content with the
rename. Add such a test, and since rename/add vs. add/rename could
possibly be important, redo the merge the opposite direction to make
sure we don't have issues with the direction of the merge. These
testcases failed before restoring the setting of path, but with the
paths appropriately set the testcases both pass.
Reported-by: Ben Humphreys <behumphreys@atlassian.com>
Based-on-patch-by: SZEDER Gábor <szeder.dev@gmail.com>
Tested-by: Ben Humphreys <behumphreys@atlassian.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-06-05 04:27:50 +08:00
|
|
|
|
|
|
|
test_expect_success 'handle rename-with-content-merge vs. add' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_with_content_merge_and_add AB &&
|
merge-recursive: restore accidentally dropped setting of path
In commit 8daec1df03de ("merge-recursive: switch from (oid,mode) pairs
to a diff_filespec", 2019-04-05), we actually switched from
(oid,mode,path) triplets to a diff_filespec -- but most callsites in the
patch only needed to worry about oid and mode so the commit message
focused on that. The oversight in the commit message apparently spilled
over to the code as well; one of the dozen or so callsites accidentally
dropped the setting of the path in the conversion. Restore the path
setting in that location.
Also, this pointed out that our testsuite was lacking a good rename/add
test, at least one that involved the need for merge content with the
rename. Add such a test, and since rename/add vs. add/rename could
possibly be important, redo the merge the opposite direction to make
sure we don't have issues with the direction of the merge. These
testcases failed before restoring the setting of path, but with the
paths appropriately set the testcases both pass.
Reported-by: Ben Humphreys <behumphreys@atlassian.com>
Based-on-patch-by: SZEDER Gábor <szeder.dev@gmail.com>
Tested-by: Ben Humphreys <behumphreys@atlassian.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-06-05 04:27:50 +08:00
|
|
|
(
|
2019-10-23 05:22:51 +08:00
|
|
|
cd rename-with-content-merge-and-add-AB &&
|
merge-recursive: restore accidentally dropped setting of path
In commit 8daec1df03de ("merge-recursive: switch from (oid,mode) pairs
to a diff_filespec", 2019-04-05), we actually switched from
(oid,mode,path) triplets to a diff_filespec -- but most callsites in the
patch only needed to worry about oid and mode so the commit message
focused on that. The oversight in the commit message apparently spilled
over to the code as well; one of the dozen or so callsites accidentally
dropped the setting of the path in the conversion. Restore the path
setting in that location.
Also, this pointed out that our testsuite was lacking a good rename/add
test, at least one that involved the need for merge content with the
rename. Add such a test, and since rename/add vs. add/rename could
possibly be important, redo the merge the opposite direction to make
sure we don't have issues with the direction of the merge. These
testcases failed before restoring the setting of path, but with the
paths appropriately set the testcases both pass.
Reported-by: Ben Humphreys <behumphreys@atlassian.com>
Based-on-patch-by: SZEDER Gábor <szeder.dev@gmail.com>
Tested-by: Ben Humphreys <behumphreys@atlassian.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-06-05 04:27:50 +08:00
|
|
|
|
|
|
|
git checkout A^0 &&
|
|
|
|
|
|
|
|
test_must_fail git merge -s recursive B^0 >out &&
|
2020-08-11 06:29:17 +08:00
|
|
|
test_i18ngrep "CONFLICT (.*/add)" out &&
|
merge-recursive: restore accidentally dropped setting of path
In commit 8daec1df03de ("merge-recursive: switch from (oid,mode) pairs
to a diff_filespec", 2019-04-05), we actually switched from
(oid,mode,path) triplets to a diff_filespec -- but most callsites in the
patch only needed to worry about oid and mode so the commit message
focused on that. The oversight in the commit message apparently spilled
over to the code as well; one of the dozen or so callsites accidentally
dropped the setting of the path in the conversion. Restore the path
setting in that location.
Also, this pointed out that our testsuite was lacking a good rename/add
test, at least one that involved the need for merge content with the
rename. Add such a test, and since rename/add vs. add/rename could
possibly be important, redo the merge the opposite direction to make
sure we don't have issues with the direction of the merge. These
testcases failed before restoring the setting of path, but with the
paths appropriately set the testcases both pass.
Reported-by: Ben Humphreys <behumphreys@atlassian.com>
Based-on-patch-by: SZEDER Gábor <szeder.dev@gmail.com>
Tested-by: Ben Humphreys <behumphreys@atlassian.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-06-05 04:27:50 +08:00
|
|
|
|
|
|
|
git ls-files -s >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -u >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
# Also, make sure both unmerged entries are for "b"
|
|
|
|
git ls-files -u b >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -o >out &&
|
|
|
|
test_line_count = 1 out &&
|
|
|
|
|
|
|
|
test_path_is_missing a &&
|
|
|
|
test_path_is_file b &&
|
|
|
|
|
|
|
|
test_seq 0 6 >tmp &&
|
|
|
|
git hash-object tmp >expect &&
|
|
|
|
git rev-parse B:b >>expect &&
|
|
|
|
git rev-parse >actual \
|
|
|
|
:2:b :3:b &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Test that the two-way merge in b is as expected
|
|
|
|
git cat-file -p :2:b >>ours &&
|
|
|
|
git cat-file -p :3:b >>theirs &&
|
|
|
|
>empty &&
|
|
|
|
test_must_fail git merge-file \
|
|
|
|
-L "HEAD" \
|
|
|
|
-L "" \
|
|
|
|
-L "B^0" \
|
|
|
|
ours empty theirs &&
|
|
|
|
test_cmp ours b
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'handle rename-with-content-merge vs. add, merge other way' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_with_content_merge_and_add BA &&
|
merge-recursive: restore accidentally dropped setting of path
In commit 8daec1df03de ("merge-recursive: switch from (oid,mode) pairs
to a diff_filespec", 2019-04-05), we actually switched from
(oid,mode,path) triplets to a diff_filespec -- but most callsites in the
patch only needed to worry about oid and mode so the commit message
focused on that. The oversight in the commit message apparently spilled
over to the code as well; one of the dozen or so callsites accidentally
dropped the setting of the path in the conversion. Restore the path
setting in that location.
Also, this pointed out that our testsuite was lacking a good rename/add
test, at least one that involved the need for merge content with the
rename. Add such a test, and since rename/add vs. add/rename could
possibly be important, redo the merge the opposite direction to make
sure we don't have issues with the direction of the merge. These
testcases failed before restoring the setting of path, but with the
paths appropriately set the testcases both pass.
Reported-by: Ben Humphreys <behumphreys@atlassian.com>
Based-on-patch-by: SZEDER Gábor <szeder.dev@gmail.com>
Tested-by: Ben Humphreys <behumphreys@atlassian.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-06-05 04:27:50 +08:00
|
|
|
(
|
2019-10-23 05:22:51 +08:00
|
|
|
cd rename-with-content-merge-and-add-BA &&
|
merge-recursive: restore accidentally dropped setting of path
In commit 8daec1df03de ("merge-recursive: switch from (oid,mode) pairs
to a diff_filespec", 2019-04-05), we actually switched from
(oid,mode,path) triplets to a diff_filespec -- but most callsites in the
patch only needed to worry about oid and mode so the commit message
focused on that. The oversight in the commit message apparently spilled
over to the code as well; one of the dozen or so callsites accidentally
dropped the setting of the path in the conversion. Restore the path
setting in that location.
Also, this pointed out that our testsuite was lacking a good rename/add
test, at least one that involved the need for merge content with the
rename. Add such a test, and since rename/add vs. add/rename could
possibly be important, redo the merge the opposite direction to make
sure we don't have issues with the direction of the merge. These
testcases failed before restoring the setting of path, but with the
paths appropriately set the testcases both pass.
Reported-by: Ben Humphreys <behumphreys@atlassian.com>
Based-on-patch-by: SZEDER Gábor <szeder.dev@gmail.com>
Tested-by: Ben Humphreys <behumphreys@atlassian.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-06-05 04:27:50 +08:00
|
|
|
|
|
|
|
git reset --hard &&
|
|
|
|
git clean -fdx &&
|
|
|
|
|
|
|
|
git checkout B^0 &&
|
|
|
|
|
|
|
|
test_must_fail git merge -s recursive A^0 >out &&
|
2020-08-11 06:29:17 +08:00
|
|
|
test_i18ngrep "CONFLICT (.*/add)" out &&
|
merge-recursive: restore accidentally dropped setting of path
In commit 8daec1df03de ("merge-recursive: switch from (oid,mode) pairs
to a diff_filespec", 2019-04-05), we actually switched from
(oid,mode,path) triplets to a diff_filespec -- but most callsites in the
patch only needed to worry about oid and mode so the commit message
focused on that. The oversight in the commit message apparently spilled
over to the code as well; one of the dozen or so callsites accidentally
dropped the setting of the path in the conversion. Restore the path
setting in that location.
Also, this pointed out that our testsuite was lacking a good rename/add
test, at least one that involved the need for merge content with the
rename. Add such a test, and since rename/add vs. add/rename could
possibly be important, redo the merge the opposite direction to make
sure we don't have issues with the direction of the merge. These
testcases failed before restoring the setting of path, but with the
paths appropriately set the testcases both pass.
Reported-by: Ben Humphreys <behumphreys@atlassian.com>
Based-on-patch-by: SZEDER Gábor <szeder.dev@gmail.com>
Tested-by: Ben Humphreys <behumphreys@atlassian.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-06-05 04:27:50 +08:00
|
|
|
|
|
|
|
git ls-files -s >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -u >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
# Also, make sure both unmerged entries are for "b"
|
|
|
|
git ls-files -u b >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -o >out &&
|
|
|
|
test_line_count = 1 out &&
|
|
|
|
|
|
|
|
test_path_is_missing a &&
|
|
|
|
test_path_is_file b &&
|
|
|
|
|
|
|
|
test_seq 0 6 >tmp &&
|
|
|
|
git rev-parse B:b >expect &&
|
|
|
|
git hash-object tmp >>expect &&
|
|
|
|
git rev-parse >actual \
|
|
|
|
:2:b :3:b &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
# Test that the two-way merge in b is as expected
|
|
|
|
git cat-file -p :2:b >>ours &&
|
|
|
|
git cat-file -p :3:b >>theirs &&
|
|
|
|
>empty &&
|
|
|
|
test_must_fail git merge-file \
|
|
|
|
-L "HEAD" \
|
|
|
|
-L "" \
|
|
|
|
-L "A^0" \
|
|
|
|
ours empty theirs &&
|
|
|
|
test_cmp ours b
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2011-08-12 13:19:39 +08:00
|
|
|
# Test for all kinds of things that can go wrong with rename/rename (2to1):
|
|
|
|
# Commit A: new files: a & b
|
|
|
|
# Commit B: rename a->c, modify b
|
|
|
|
# Commit C: rename b->c, modify a
|
|
|
|
#
|
|
|
|
# Merging of B & C should NOT be clean. Questions:
|
|
|
|
# * Both a & b should be removed by the merge; are they?
|
|
|
|
# * The two c's should contain modifications to a & b; do they?
|
|
|
|
# * The index should contain two files, both for c; does it?
|
|
|
|
# * The working copy should have two files, both of form c~<unique>; does it?
|
|
|
|
# * Nothing else should be present. Is anything?
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_rename_2to1 () {
|
2018-05-24 15:04:35 +08:00
|
|
|
test_create_repo rename-rename-2to1 &&
|
|
|
|
(
|
|
|
|
cd rename-rename-2to1 &&
|
|
|
|
|
|
|
|
printf "1\n2\n3\n4\n5\n" >a &&
|
|
|
|
printf "5\n4\n3\n2\n1\n" >b &&
|
|
|
|
git add a b &&
|
|
|
|
git commit -m A &&
|
|
|
|
git tag A &&
|
|
|
|
|
|
|
|
git checkout -b B A &&
|
|
|
|
git mv a c &&
|
|
|
|
echo 0 >>b &&
|
|
|
|
git add b &&
|
|
|
|
git commit -m B &&
|
|
|
|
|
|
|
|
git checkout -b C A &&
|
|
|
|
git mv b c &&
|
|
|
|
echo 6 >>a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m C
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
2011-08-12 13:19:39 +08:00
|
|
|
|
merge-recursive: Consider modifications in rename/rename(2to1) conflicts
Our previous conflict resolution for renaming two different files to the
same name ignored the fact that each of those files may have modifications
from both sides of history to consider. We need to do a three-way merge
for each of those files, and then handle the conflict of both sets of
merged contents trying to be recorded with the same name.
It is important to note that this changes our strategy in the recursive
case. After doing a three-way content merge of each of the files
involved, we still are faced with the fact that we are trying to put both
of the results (including conflict markers) into the same path. We could
do another two-way merge, but I think that becomes confusing. Also,
taking a hint from the modify/delete and rename/delete cases we handled
earlier, a more useful "common ground" would be to keep the three-way
content merge but record it with the original filename. The renames can
still be detected, we just allow it to be done in the o->call_depth=0
case. This seems to result in simpler & easier to understand merge
conflicts as well, as evidenced by some of the changes needed in our
testsuite in t6036. (However, it should be noted that this change will
cause problems those renames also occur along with a file being added
whose name matches the source of the rename. Since git currently cannot
detect rename/add-source situations, though, this codepath is not
currently used for those cases anyway.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:20:18 +08:00
|
|
|
test_expect_success 'handle rename/rename (2to1) conflict correctly' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_rename_2to1 &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
|
|
|
cd rename-rename-2to1 &&
|
|
|
|
|
|
|
|
git checkout B^0 &&
|
2011-08-12 13:19:39 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
test_must_fail git merge -s recursive C^0 >out &&
|
2020-08-11 06:29:18 +08:00
|
|
|
test_i18ngrep "CONFLICT (\(.*\)/\1)" out &&
|
2011-08-12 13:19:39 +08:00
|
|
|
|
2018-05-24 15:04:36 +08:00
|
|
|
git ls-files -s >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -u >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -u c >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -o >out &&
|
2018-11-08 12:40:27 +08:00
|
|
|
test_line_count = 1 out &&
|
2011-08-12 13:19:39 +08:00
|
|
|
|
2018-05-24 15:04:37 +08:00
|
|
|
test_path_is_missing a &&
|
|
|
|
test_path_is_missing b &&
|
2011-08-12 13:19:39 +08:00
|
|
|
|
2018-11-08 12:40:27 +08:00
|
|
|
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 &&
|
2018-05-24 15:04:38 +08:00
|
|
|
test_cmp expect actual
|
2018-05-24 15:04:35 +08:00
|
|
|
)
|
2011-08-12 13:19:39 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
# Testcase setup for simple rename/rename (1to2) conflict:
|
|
|
|
# Commit A: new file: a
|
|
|
|
# Commit B: rename a->b
|
|
|
|
# Commit C: rename a->c
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_rename_1to2 () {
|
2018-05-24 15:04:35 +08:00
|
|
|
test_create_repo rename-rename-1to2 &&
|
|
|
|
(
|
|
|
|
cd rename-rename-1to2 &&
|
|
|
|
|
|
|
|
echo stuff >a &&
|
|
|
|
git add a &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m A &&
|
|
|
|
git tag A &&
|
|
|
|
|
|
|
|
git checkout -b B A &&
|
|
|
|
git mv a b &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m B &&
|
|
|
|
|
|
|
|
git checkout -b C A &&
|
|
|
|
git mv a c &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m C
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
2011-08-12 13:19:39 +08:00
|
|
|
|
|
|
|
test_expect_success 'merge has correct working tree contents' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_rename_1to2 &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
|
|
|
cd rename-rename-1to2 &&
|
|
|
|
|
|
|
|
git checkout C^0 &&
|
2011-08-12 13:19:39 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
test_must_fail git merge -s recursive B^0 &&
|
2011-08-12 13:19:39 +08:00
|
|
|
|
2018-05-24 15:04:36 +08:00
|
|
|
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 &&
|
2011-08-12 13:19:39 +08:00
|
|
|
|
2018-05-24 15:04:37 +08:00
|
|
|
test_path_is_missing a &&
|
2018-05-24 15:04:38 +08:00
|
|
|
git rev-parse >expect \
|
|
|
|
A:a A:a A:a \
|
|
|
|
A:a A:a &&
|
|
|
|
git rev-parse >actual \
|
|
|
|
:1:a :3:b :2:c &&
|
|
|
|
git hash-object >>actual \
|
|
|
|
b c &&
|
|
|
|
test_cmp expect actual
|
2018-05-24 15:04:35 +08:00
|
|
|
)
|
2011-08-12 13:19:39 +08:00
|
|
|
'
|
|
|
|
|
t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
Add testcases that cover three failures with current git merge, all
involving renaming one file on both sides of history:
Case 1:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. Adding a new file on one of those
sides of history whose name happens to match the rename source should not
cause the merge to suddenly succeed.
Case 2:
If a single file is renamed on both sides of history but renamed
identically, there should not be a conflict. This works fine. However,
if one of those sides also added a new file that happened to match the
rename source, then that file should be left alone. Currently, the
rename/rename conflict handling causes that new file to become untracked.
Case 3:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. This works currently. However,
if those renames also involve rename/add conflicts (i.e. there are new
files on one side of history that match the destination of the rename of
the other side of history), then the resulting conflict should be recorded
in the index, showing that there were multiple files with a given filename.
Currently, git silently discards one of file versions.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:40 +08:00
|
|
|
# Testcase setup for rename/rename(1to2)/add-source conflict:
|
|
|
|
# Commit A: new file: a
|
|
|
|
# Commit B: rename a->b
|
|
|
|
# Commit C: rename a->c, add completely different a
|
|
|
|
#
|
|
|
|
# Merging of B & C should NOT be clean; there's a rename/rename conflict
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_rename_1to2_add_source_1 () {
|
2018-05-24 15:04:35 +08:00
|
|
|
test_create_repo rename-rename-1to2-add-source-1 &&
|
|
|
|
(
|
|
|
|
cd rename-rename-1to2-add-source-1 &&
|
|
|
|
|
|
|
|
printf "1\n2\n3\n4\n5\n6\n7\n" >a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m A &&
|
|
|
|
git tag A &&
|
|
|
|
|
|
|
|
git checkout -b B A &&
|
|
|
|
git mv a b &&
|
|
|
|
git commit -m B &&
|
|
|
|
|
|
|
|
git checkout -b C A &&
|
|
|
|
git mv a c &&
|
|
|
|
echo something completely different >a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m C
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
Add testcases that cover three failures with current git merge, all
involving renaming one file on both sides of history:
Case 1:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. Adding a new file on one of those
sides of history whose name happens to match the rename source should not
cause the merge to suddenly succeed.
Case 2:
If a single file is renamed on both sides of history but renamed
identically, there should not be a conflict. This works fine. However,
if one of those sides also added a new file that happened to match the
rename source, then that file should be left alone. Currently, the
rename/rename conflict handling causes that new file to become untracked.
Case 3:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. This works currently. However,
if those renames also involve rename/add conflicts (i.e. there are new
files on one side of history that match the destination of the rename of
the other side of history), then the resulting conflict should be recorded
in the index, showing that there were multiple files with a given filename.
Currently, git silently discards one of file versions.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:40 +08:00
|
|
|
|
|
|
|
test_expect_failure 'detect conflict with rename/rename(1to2)/add-source merge' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_rename_1to2_add_source_1 &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
|
|
|
cd rename-rename-1to2-add-source-1 &&
|
t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
Add testcases that cover three failures with current git merge, all
involving renaming one file on both sides of history:
Case 1:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. Adding a new file on one of those
sides of history whose name happens to match the rename source should not
cause the merge to suddenly succeed.
Case 2:
If a single file is renamed on both sides of history but renamed
identically, there should not be a conflict. This works fine. However,
if one of those sides also added a new file that happened to match the
rename source, then that file should be left alone. Currently, the
rename/rename conflict handling causes that new file to become untracked.
Case 3:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. This works currently. However,
if those renames also involve rename/add conflicts (i.e. there are new
files on one side of history that match the destination of the rename of
the other side of history), then the resulting conflict should be recorded
in the index, showing that there were multiple files with a given filename.
Currently, git silently discards one of file versions.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:40 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
git checkout B^0 &&
|
t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
Add testcases that cover three failures with current git merge, all
involving renaming one file on both sides of history:
Case 1:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. Adding a new file on one of those
sides of history whose name happens to match the rename source should not
cause the merge to suddenly succeed.
Case 2:
If a single file is renamed on both sides of history but renamed
identically, there should not be a conflict. This works fine. However,
if one of those sides also added a new file that happened to match the
rename source, then that file should be left alone. Currently, the
rename/rename conflict handling causes that new file to become untracked.
Case 3:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. This works currently. However,
if those renames also involve rename/add conflicts (i.e. there are new
files on one side of history that match the destination of the rename of
the other side of history), then the resulting conflict should be recorded
in the index, showing that there were multiple files with a given filename.
Currently, git silently discards one of file versions.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:40 +08:00
|
|
|
|
2018-05-24 15:04:35 +08:00
|
|
|
test_must_fail git merge -s recursive C^0 &&
|
t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
Add testcases that cover three failures with current git merge, all
involving renaming one file on both sides of history:
Case 1:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. Adding a new file on one of those
sides of history whose name happens to match the rename source should not
cause the merge to suddenly succeed.
Case 2:
If a single file is renamed on both sides of history but renamed
identically, there should not be a conflict. This works fine. However,
if one of those sides also added a new file that happened to match the
rename source, then that file should be left alone. Currently, the
rename/rename conflict handling causes that new file to become untracked.
Case 3:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. This works currently. However,
if those renames also involve rename/add conflicts (i.e. there are new
files on one side of history that match the destination of the rename of
the other side of history), then the resulting conflict should be recorded
in the index, showing that there were multiple files with a given filename.
Currently, git silently discards one of file versions.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:40 +08:00
|
|
|
|
2018-05-24 15:04:36 +08:00
|
|
|
git ls-files -s >out &&
|
|
|
|
test_line_count = 4 out &&
|
|
|
|
git ls-files -o >out &&
|
|
|
|
test_line_count = 1 out &&
|
t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
Add testcases that cover three failures with current git merge, all
involving renaming one file on both sides of history:
Case 1:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. Adding a new file on one of those
sides of history whose name happens to match the rename source should not
cause the merge to suddenly succeed.
Case 2:
If a single file is renamed on both sides of history but renamed
identically, there should not be a conflict. This works fine. However,
if one of those sides also added a new file that happened to match the
rename source, then that file should be left alone. Currently, the
rename/rename conflict handling causes that new file to become untracked.
Case 3:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. This works currently. However,
if those renames also involve rename/add conflicts (i.e. there are new
files on one side of history that match the destination of the rename of
the other side of history), then the resulting conflict should be recorded
in the index, showing that there were multiple files with a given filename.
Currently, git silently discards one of file versions.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:40 +08:00
|
|
|
|
2018-05-24 15:04:38 +08:00
|
|
|
git rev-parse >expect \
|
|
|
|
C:a A:a B:b C:C &&
|
|
|
|
git rev-parse >actual \
|
|
|
|
:3:a :1:a :2:b :3:c &&
|
2018-07-02 08:24:02 +08:00
|
|
|
test_cmp expect actual &&
|
2018-05-24 15:04:35 +08:00
|
|
|
|
2018-05-24 15:04:37 +08:00
|
|
|
test_path_is_file a &&
|
|
|
|
test_path_is_file b &&
|
|
|
|
test_path_is_file c
|
2018-05-24 15:04:35 +08:00
|
|
|
)
|
t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
Add testcases that cover three failures with current git merge, all
involving renaming one file on both sides of history:
Case 1:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. Adding a new file on one of those
sides of history whose name happens to match the rename source should not
cause the merge to suddenly succeed.
Case 2:
If a single file is renamed on both sides of history but renamed
identically, there should not be a conflict. This works fine. However,
if one of those sides also added a new file that happened to match the
rename source, then that file should be left alone. Currently, the
rename/rename conflict handling causes that new file to become untracked.
Case 3:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. This works currently. However,
if those renames also involve rename/add conflicts (i.e. there are new
files on one side of history that match the destination of the rename of
the other side of history), then the resulting conflict should be recorded
in the index, showing that there were multiple files with a given filename.
Currently, git silently discards one of file versions.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:40 +08:00
|
|
|
'
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_rename_1to2_add_source_2 () {
|
2018-05-24 15:04:35 +08:00
|
|
|
test_create_repo rename-rename-1to2-add-source-2 &&
|
|
|
|
(
|
|
|
|
cd rename-rename-1to2-add-source-2 &&
|
|
|
|
|
|
|
|
>a &&
|
|
|
|
git add a &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m base &&
|
|
|
|
git tag A &&
|
|
|
|
|
|
|
|
git checkout -b B A &&
|
|
|
|
git mv a b &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m one &&
|
|
|
|
|
|
|
|
git checkout -b C A &&
|
|
|
|
git mv a b &&
|
|
|
|
echo important-info >a &&
|
|
|
|
git add a &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m two
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
Add testcases that cover three failures with current git merge, all
involving renaming one file on both sides of history:
Case 1:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. Adding a new file on one of those
sides of history whose name happens to match the rename source should not
cause the merge to suddenly succeed.
Case 2:
If a single file is renamed on both sides of history but renamed
identically, there should not be a conflict. This works fine. However,
if one of those sides also added a new file that happened to match the
rename source, then that file should be left alone. Currently, the
rename/rename conflict handling causes that new file to become untracked.
Case 3:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. This works currently. However,
if those renames also involve rename/add conflicts (i.e. there are new
files on one side of history that match the destination of the rename of
the other side of history), then the resulting conflict should be recorded
in the index, showing that there were multiple files with a given filename.
Currently, git silently discards one of file versions.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:40 +08:00
|
|
|
|
|
|
|
test_expect_failure 'rename/rename/add-source still tracks new a file' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_rename_1to2_add_source_2 &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
|
|
|
cd rename-rename-1to2-add-source-2 &&
|
|
|
|
|
|
|
|
git checkout C^0 &&
|
|
|
|
git merge -s recursive B^0 &&
|
t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
Add testcases that cover three failures with current git merge, all
involving renaming one file on both sides of history:
Case 1:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. Adding a new file on one of those
sides of history whose name happens to match the rename source should not
cause the merge to suddenly succeed.
Case 2:
If a single file is renamed on both sides of history but renamed
identically, there should not be a conflict. This works fine. However,
if one of those sides also added a new file that happened to match the
rename source, then that file should be left alone. Currently, the
rename/rename conflict handling causes that new file to become untracked.
Case 3:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. This works currently. However,
if those renames also involve rename/add conflicts (i.e. there are new
files on one side of history that match the destination of the rename of
the other side of history), then the resulting conflict should be recorded
in the index, showing that there were multiple files with a given filename.
Currently, git silently discards one of file versions.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:40 +08:00
|
|
|
|
2018-05-24 15:04:36 +08:00
|
|
|
git ls-files -s >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -o >out &&
|
|
|
|
test_line_count = 1 out &&
|
t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
Add testcases that cover three failures with current git merge, all
involving renaming one file on both sides of history:
Case 1:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. Adding a new file on one of those
sides of history whose name happens to match the rename source should not
cause the merge to suddenly succeed.
Case 2:
If a single file is renamed on both sides of history but renamed
identically, there should not be a conflict. This works fine. However,
if one of those sides also added a new file that happened to match the
rename source, then that file should be left alone. Currently, the
rename/rename conflict handling causes that new file to become untracked.
Case 3:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. This works currently. However,
if those renames also involve rename/add conflicts (i.e. there are new
files on one side of history that match the destination of the rename of
the other side of history), then the resulting conflict should be recorded
in the index, showing that there were multiple files with a given filename.
Currently, git silently discards one of file versions.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:40 +08:00
|
|
|
|
2018-05-24 15:04:38 +08:00
|
|
|
git rev-parse >expect \
|
|
|
|
C:a A:a &&
|
|
|
|
git rev-parse >actual \
|
|
|
|
:0:a :0:b &&
|
|
|
|
test_cmp expect actual
|
2018-05-24 15:04:35 +08:00
|
|
|
)
|
t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
Add testcases that cover three failures with current git merge, all
involving renaming one file on both sides of history:
Case 1:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. Adding a new file on one of those
sides of history whose name happens to match the rename source should not
cause the merge to suddenly succeed.
Case 2:
If a single file is renamed on both sides of history but renamed
identically, there should not be a conflict. This works fine. However,
if one of those sides also added a new file that happened to match the
rename source, then that file should be left alone. Currently, the
rename/rename conflict handling causes that new file to become untracked.
Case 3:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. This works currently. However,
if those renames also involve rename/add conflicts (i.e. there are new
files on one side of history that match the destination of the rename of
the other side of history), then the resulting conflict should be recorded
in the index, showing that there were multiple files with a given filename.
Currently, git silently discards one of file versions.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:40 +08:00
|
|
|
'
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_rename_1to2_add_dest () {
|
2018-05-24 15:04:35 +08:00
|
|
|
test_create_repo rename-rename-1to2-add-dest &&
|
|
|
|
(
|
|
|
|
cd rename-rename-1to2-add-dest &&
|
|
|
|
|
|
|
|
echo stuff >a &&
|
|
|
|
git add a &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m base &&
|
|
|
|
git tag A &&
|
|
|
|
|
|
|
|
git checkout -b B A &&
|
|
|
|
git mv a b &&
|
|
|
|
echo precious-data >c &&
|
|
|
|
git add c &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m one &&
|
|
|
|
|
|
|
|
git checkout -b C A &&
|
|
|
|
git mv a c &&
|
|
|
|
echo important-info >b &&
|
|
|
|
git add b &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m two
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
Add testcases that cover three failures with current git merge, all
involving renaming one file on both sides of history:
Case 1:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. Adding a new file on one of those
sides of history whose name happens to match the rename source should not
cause the merge to suddenly succeed.
Case 2:
If a single file is renamed on both sides of history but renamed
identically, there should not be a conflict. This works fine. However,
if one of those sides also added a new file that happened to match the
rename source, then that file should be left alone. Currently, the
rename/rename conflict handling causes that new file to become untracked.
Case 3:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. This works currently. However,
if those renames also involve rename/add conflicts (i.e. there are new
files on one side of history that match the destination of the rename of
the other side of history), then the resulting conflict should be recorded
in the index, showing that there were multiple files with a given filename.
Currently, git silently discards one of file versions.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:40 +08:00
|
|
|
|
2011-08-12 13:20:21 +08:00
|
|
|
test_expect_success 'rename/rename/add-dest merge still knows about conflicting file versions' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rename_rename_1to2_add_dest &&
|
2018-05-24 15:04:35 +08:00
|
|
|
(
|
|
|
|
cd rename-rename-1to2-add-dest &&
|
|
|
|
|
|
|
|
git checkout C^0 &&
|
|
|
|
test_must_fail git merge -s recursive B^0 &&
|
|
|
|
|
2018-05-24 15:04:36 +08:00
|
|
|
git ls-files -s >out &&
|
|
|
|
test_line_count = 5 out &&
|
|
|
|
git ls-files -u b >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -u c >out &&
|
|
|
|
test_line_count = 2 out &&
|
|
|
|
git ls-files -o >out &&
|
2018-11-08 12:40:29 +08:00
|
|
|
test_line_count = 1 out &&
|
2018-05-24 15:04:35 +08:00
|
|
|
|
2018-05-24 15:04:38 +08:00
|
|
|
git rev-parse >expect \
|
|
|
|
A:a C:b B:b C:c B:c &&
|
|
|
|
git rev-parse >actual \
|
|
|
|
:1:a :2:b :3:b :2:c :3:c &&
|
2018-07-02 08:24:02 +08:00
|
|
|
test_cmp expect actual &&
|
2018-05-24 15:04:38 +08:00
|
|
|
|
2018-11-08 12:40:29 +08:00
|
|
|
# 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 &&
|
2018-05-24 15:04:35 +08:00
|
|
|
|
2018-11-08 12:40:29 +08:00
|
|
|
# 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
|
2018-05-24 15:04:35 +08:00
|
|
|
)
|
t6042: Add failing testcases for rename/rename/add-{source,dest} conflicts
Add testcases that cover three failures with current git merge, all
involving renaming one file on both sides of history:
Case 1:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. Adding a new file on one of those
sides of history whose name happens to match the rename source should not
cause the merge to suddenly succeed.
Case 2:
If a single file is renamed on both sides of history but renamed
identically, there should not be a conflict. This works fine. However,
if one of those sides also added a new file that happened to match the
rename source, then that file should be left alone. Currently, the
rename/rename conflict handling causes that new file to become untracked.
Case 3:
If a single file is renamed to two different filenames on different sides
of history, there should be a conflict. This works currently. However,
if those renames also involve rename/add conflicts (i.e. there are new
files on one side of history that match the destination of the rename of
the other side of history), then the resulting conflict should be recorded
in the index, showing that there were multiple files with a given filename.
Currently, git silently discards one of file versions.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-12 13:19:40 +08:00
|
|
|
'
|
|
|
|
|
2018-07-02 21:30:52 +08:00
|
|
|
# Testcase rad, rename/add/delete
|
|
|
|
# Commit O: foo
|
|
|
|
# Commit A: rm foo, add different bar
|
|
|
|
# Commit B: rename foo->bar
|
|
|
|
# Expected: CONFLICT (rename/add/delete), two-way merged bar
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rad () {
|
2018-07-02 21:30:52 +08:00
|
|
|
test_create_repo rad &&
|
|
|
|
(
|
|
|
|
cd rad &&
|
|
|
|
echo "original file" >foo &&
|
|
|
|
git add foo &&
|
|
|
|
git commit -m "original" &&
|
|
|
|
|
|
|
|
git branch O &&
|
|
|
|
git branch A &&
|
|
|
|
git branch B &&
|
|
|
|
|
|
|
|
git checkout A &&
|
|
|
|
git rm foo &&
|
|
|
|
echo "different file" >bar &&
|
|
|
|
git add bar &&
|
|
|
|
git commit -m "Remove foo, add bar" &&
|
|
|
|
|
|
|
|
git checkout B &&
|
|
|
|
git mv foo bar &&
|
|
|
|
git commit -m "rename foo to bar"
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
2018-07-02 21:30:52 +08:00
|
|
|
|
2020-10-27 01:01:36 +08:00
|
|
|
test_expect_merge_algorithm failure success 'rad-check: rename/add/delete conflict' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rad &&
|
2018-07-02 21:30:52 +08:00
|
|
|
(
|
|
|
|
cd rad &&
|
|
|
|
|
|
|
|
git checkout B^0 &&
|
|
|
|
test_must_fail git merge -s recursive A^0 >out 2>err &&
|
|
|
|
|
2020-08-11 06:29:17 +08:00
|
|
|
# Instead of requiring the output to contain one combined line
|
|
|
|
# CONFLICT (rename/add/delete)
|
|
|
|
# or perhaps two lines:
|
|
|
|
# CONFLICT (rename/add): new file collides with rename target
|
|
|
|
# CONFLICT (rename/delete): rename source removed on other side
|
|
|
|
# and instead of requiring "rename/add" instead of "add/add",
|
|
|
|
# be flexible in the type of console output message(s) reported
|
|
|
|
# for this particular case; we will be more stringent about the
|
|
|
|
# contents of the index and working directory.
|
|
|
|
test_i18ngrep "CONFLICT (.*/add)" out &&
|
|
|
|
test_i18ngrep "CONFLICT (rename.*/delete)" out &&
|
2018-07-02 21:30:52 +08:00
|
|
|
test_must_be_empty err &&
|
|
|
|
|
|
|
|
git ls-files -s >file_count &&
|
|
|
|
test_line_count = 2 file_count &&
|
|
|
|
git ls-files -u >file_count &&
|
|
|
|
test_line_count = 2 file_count &&
|
|
|
|
git ls-files -o >file_count &&
|
2020-08-11 06:29:12 +08:00
|
|
|
test_line_count = 3 file_count &&
|
2018-07-02 21:30:52 +08:00
|
|
|
|
|
|
|
git rev-parse >actual \
|
|
|
|
:2:bar :3:bar &&
|
|
|
|
git rev-parse >expect \
|
|
|
|
B:bar A:bar &&
|
|
|
|
|
2020-08-11 06:29:11 +08:00
|
|
|
test_path_is_missing foo &&
|
2018-07-02 21:30:52 +08:00
|
|
|
# bar should have two-way merged contents of the different
|
|
|
|
# versions of bar; check that content from both sides is
|
|
|
|
# present.
|
|
|
|
grep original bar &&
|
|
|
|
grep different bar
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2018-07-02 21:30:53 +08:00
|
|
|
# Testcase rrdd, rename/rename(2to1)/delete/delete
|
|
|
|
# Commit O: foo, bar
|
|
|
|
# Commit A: rename foo->baz, rm bar
|
|
|
|
# Commit B: rename bar->baz, rm foo
|
|
|
|
# Expected: CONFLICT (rename/rename/delete/delete), two-way merged baz
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rrdd () {
|
2018-07-02 21:30:53 +08:00
|
|
|
test_create_repo rrdd &&
|
|
|
|
(
|
|
|
|
cd rrdd &&
|
|
|
|
echo foo >foo &&
|
|
|
|
echo bar >bar &&
|
|
|
|
git add foo bar &&
|
|
|
|
git commit -m O &&
|
|
|
|
|
|
|
|
git branch O &&
|
|
|
|
git branch A &&
|
|
|
|
git branch B &&
|
|
|
|
|
|
|
|
git checkout A &&
|
|
|
|
git mv foo baz &&
|
|
|
|
git rm bar &&
|
|
|
|
git commit -m "Rename foo, remove bar" &&
|
|
|
|
|
|
|
|
git checkout B &&
|
|
|
|
git mv bar baz &&
|
|
|
|
git rm foo &&
|
|
|
|
git commit -m "Rename bar, remove foo"
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
2018-07-02 21:30:53 +08:00
|
|
|
|
2020-10-27 01:01:36 +08:00
|
|
|
test_expect_merge_algorithm failure success 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_rrdd &&
|
2018-07-02 21:30:53 +08:00
|
|
|
(
|
|
|
|
cd rrdd &&
|
|
|
|
|
|
|
|
git checkout A^0 &&
|
|
|
|
test_must_fail git merge -s recursive B^0 >out 2>err &&
|
|
|
|
|
2020-08-11 06:29:18 +08:00
|
|
|
# Instead of requiring the output to contain one combined line
|
|
|
|
# CONFLICT (rename/rename/delete/delete)
|
|
|
|
# or perhaps two lines:
|
|
|
|
# CONFLICT (rename/rename): ...
|
|
|
|
# CONFLICT (rename/delete): info about pair 1
|
|
|
|
# CONFLICT (rename/delete): info about pair 2
|
|
|
|
# and instead of requiring "rename/rename" instead of "add/add",
|
|
|
|
# be flexible in the type of console output message(s) reported
|
|
|
|
# for this particular case; we will be more stringent about the
|
|
|
|
# contents of the index and working directory.
|
|
|
|
test_i18ngrep "CONFLICT (\(.*\)/\1)" out &&
|
2018-07-02 21:30:53 +08:00
|
|
|
test_i18ngrep "CONFLICT (rename.*delete)" out &&
|
|
|
|
test_must_be_empty err &&
|
|
|
|
|
|
|
|
git ls-files -s >file_count &&
|
|
|
|
test_line_count = 2 file_count &&
|
|
|
|
git ls-files -u >file_count &&
|
|
|
|
test_line_count = 2 file_count &&
|
|
|
|
git ls-files -o >file_count &&
|
2020-08-11 06:29:12 +08:00
|
|
|
test_line_count = 3 file_count &&
|
2018-07-02 21:30:53 +08:00
|
|
|
|
|
|
|
git rev-parse >actual \
|
|
|
|
:2:baz :3:baz &&
|
|
|
|
git rev-parse >expect \
|
|
|
|
O:foo O:bar &&
|
|
|
|
|
2020-08-11 06:29:11 +08:00
|
|
|
test_path_is_missing foo &&
|
|
|
|
test_path_is_missing bar &&
|
2018-07-02 21:30:53 +08:00
|
|
|
# baz should have two-way merged contents of the original
|
|
|
|
# contents of foo and bar; check that content from both sides
|
|
|
|
# is present.
|
|
|
|
grep foo baz &&
|
|
|
|
grep bar baz
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2018-07-02 21:30:54 +08:00
|
|
|
# Testcase mod6, chains of rename/rename(1to2) and rename/rename(2to1)
|
|
|
|
# Commit O: one, three, five
|
|
|
|
# Commit A: one->two, three->four, five->six
|
|
|
|
# Commit B: one->six, three->two, five->four
|
|
|
|
# Expected: six CONFLICT(rename/rename) messages, each path in two of the
|
|
|
|
# multi-way merged contents found in two, four, six
|
|
|
|
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_mod6 () {
|
2018-07-02 21:30:54 +08:00
|
|
|
test_create_repo mod6 &&
|
|
|
|
(
|
|
|
|
cd mod6 &&
|
|
|
|
test_seq 11 19 >one &&
|
|
|
|
test_seq 31 39 >three &&
|
|
|
|
test_seq 51 59 >five &&
|
|
|
|
git add . &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m "O" &&
|
|
|
|
|
|
|
|
git branch O &&
|
|
|
|
git branch A &&
|
|
|
|
git branch B &&
|
|
|
|
|
|
|
|
git checkout A &&
|
|
|
|
test_seq 10 19 >one &&
|
|
|
|
echo 40 >>three &&
|
|
|
|
git add one three &&
|
|
|
|
git mv one two &&
|
|
|
|
git mv three four &&
|
|
|
|
git mv five six &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m "A" &&
|
|
|
|
|
|
|
|
git checkout B &&
|
|
|
|
echo 20 >>one &&
|
|
|
|
echo forty >>three &&
|
|
|
|
echo 60 >>five &&
|
|
|
|
git add one three five &&
|
|
|
|
git mv one six &&
|
|
|
|
git mv three two &&
|
|
|
|
git mv five four &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m "B"
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
2018-07-02 21:30:54 +08:00
|
|
|
|
2020-10-27 01:01:36 +08:00
|
|
|
test_expect_merge_algorithm failure success 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_mod6 &&
|
2018-07-02 21:30:54 +08:00
|
|
|
(
|
|
|
|
cd mod6 &&
|
|
|
|
|
|
|
|
git checkout A^0 &&
|
|
|
|
|
|
|
|
test_must_fail git merge -s recursive B^0 >out 2>err &&
|
|
|
|
|
|
|
|
test_i18ngrep "CONFLICT (rename/rename)" out &&
|
|
|
|
test_must_be_empty err &&
|
|
|
|
|
|
|
|
git ls-files -s >file_count &&
|
2020-08-11 06:29:14 +08:00
|
|
|
test_line_count = 9 file_count &&
|
2018-07-02 21:30:54 +08:00
|
|
|
git ls-files -u >file_count &&
|
2020-08-11 06:29:14 +08:00
|
|
|
test_line_count = 9 file_count &&
|
2018-07-02 21:30:54 +08:00
|
|
|
git ls-files -o >file_count &&
|
|
|
|
test_line_count = 3 file_count &&
|
|
|
|
|
|
|
|
test_seq 10 20 >merged-one &&
|
|
|
|
test_seq 51 60 >merged-five &&
|
|
|
|
# Determine what the merge of three would give us.
|
2020-08-11 06:29:14 +08:00
|
|
|
test_seq 31 39 >three-base &&
|
|
|
|
test_seq 31 40 >three-side-A &&
|
2018-07-02 21:30:54 +08:00
|
|
|
test_seq 31 39 >three-side-B &&
|
2020-08-11 06:29:14 +08:00
|
|
|
echo forty >>three-side-B &&
|
2018-07-02 21:30:54 +08:00
|
|
|
test_must_fail git merge-file \
|
2020-08-11 06:29:14 +08:00
|
|
|
-L "HEAD:four" \
|
2018-07-02 21:30:54 +08:00
|
|
|
-L "" \
|
2020-08-11 06:29:14 +08:00
|
|
|
-L "B^0:two" \
|
|
|
|
three-side-A three-base three-side-B &&
|
|
|
|
sed -e "s/^\([<=>]\)/\1\1/" three-side-A >merged-three &&
|
2018-07-02 21:30:54 +08:00
|
|
|
|
|
|
|
# Verify the index is as expected
|
|
|
|
git rev-parse >actual \
|
|
|
|
:2:two :3:two \
|
|
|
|
:2:four :3:four \
|
|
|
|
:2:six :3:six &&
|
|
|
|
git hash-object >expect \
|
|
|
|
merged-one merged-three \
|
|
|
|
merged-three merged-five \
|
|
|
|
merged-five merged-one &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
git cat-file -p :2:two >expect &&
|
|
|
|
git cat-file -p :3:two >other &&
|
2020-08-11 06:29:14 +08:00
|
|
|
>empty &&
|
2018-07-02 21:30:54 +08:00
|
|
|
test_must_fail git merge-file \
|
|
|
|
-L "HEAD" -L "" -L "B^0" \
|
|
|
|
expect empty other &&
|
|
|
|
test_cmp expect two &&
|
|
|
|
|
|
|
|
git cat-file -p :2:four >expect &&
|
|
|
|
git cat-file -p :3:four >other &&
|
|
|
|
test_must_fail git merge-file \
|
|
|
|
-L "HEAD" -L "" -L "B^0" \
|
|
|
|
expect empty other &&
|
|
|
|
test_cmp expect four &&
|
|
|
|
|
|
|
|
git cat-file -p :2:six >expect &&
|
|
|
|
git cat-file -p :3:six >other &&
|
|
|
|
test_must_fail git merge-file \
|
|
|
|
-L "HEAD" -L "" -L "B^0" \
|
|
|
|
expect empty other &&
|
|
|
|
test_cmp expect six
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2018-11-08 12:40:22 +08:00
|
|
|
test_conflicts_with_adds_and_renames() {
|
|
|
|
sideL=$1
|
|
|
|
sideR=$2
|
|
|
|
|
|
|
|
# Setup:
|
|
|
|
# L
|
|
|
|
# / \
|
2020-11-19 07:44:38 +08:00
|
|
|
# main ?
|
2018-11-08 12:40:22 +08:00
|
|
|
# \ /
|
|
|
|
# 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
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_collision_conflict () {
|
|
|
|
#test_expect_success "setup simple $sideL/$sideR conflict" '
|
2018-11-08 12:40:22 +08:00
|
|
|
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
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
#'
|
|
|
|
}
|
2018-11-08 12:40:22 +08:00
|
|
|
|
2018-11-08 12:40:27 +08:00
|
|
|
test_expect_success "check simple $sideL/$sideR conflict" '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_collision_conflict &&
|
2018-11-08 12:40:22 +08:00
|
|
|
(
|
|
|
|
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 \
|
2020-11-19 07:44:38 +08:00
|
|
|
main:irrelevant_file \
|
2018-11-08 12:40:22 +08:00
|
|
|
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
|
|
|
|
)
|
|
|
|
'
|
|
|
|
}
|
|
|
|
|
2018-11-08 12:40:27 +08:00
|
|
|
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
|
2018-11-08 12:40:22 +08:00
|
|
|
|
2018-11-08 12:40:23 +08:00
|
|
|
# Setup:
|
|
|
|
# L
|
|
|
|
# / \
|
2020-11-19 07:44:38 +08:00
|
|
|
# main ?
|
2018-11-08 12:40:23 +08:00
|
|
|
# \ /
|
|
|
|
# R
|
|
|
|
#
|
|
|
|
# Where:
|
2020-11-19 07:44:38 +08:00
|
|
|
# main has two files, named 'one' and 'two'.
|
2018-11-08 12:40:23 +08:00
|
|
|
# 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'.
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_nested_conflicts_from_rename_rename () {
|
2018-11-08 12:40:23 +08:00
|
|
|
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 &&
|
t6042: work around speed optimization on Windows
When Git determines whether a file has changed, it looks at the mtime,
at the file size, and to detect changes even if the mtime is the same
(on Windows, the mtime granularity is 100ns, read: if two files are
written within the same 100ns time slot, they have the same mtime) and
even if the file size is the same, Git also looks at the inode/device
numbers.
This design obviously comes from a Linux background, where `lstat()`
calls were designed to be cheap.
On Windows, there is no `lstat()`. It has to be emulated. And while
obtaining the mtime and the file size is not all that expensive (you can
get both with a single `GetFileAttributesW()` call), obtaining the
equivalent of the inode and device numbers is very expensive (it
requires a call to `GetFileInformationByHandle()`, which in turn
requires a file handle, which is *a lot* more expensive than one might
imagine).
As it is very uncommon for developers to modify files within 100ns time
slots, Git for Windows chooses not to fill inode/device numbers
properly, but simply sets them to 0.
However, in t6042 the files file_v1 and file_v2 are typically written
within the same 100ns time slot, and they do not differ in file size. So
the minor modification is not picked up.
Let's work around this issue by avoiding the `git mv` calls in the
'mod6-setup: chains of rename/rename(1to2) and rename/rename(2to1)' test
case. The target files are overwritten anyway, so it is not like we
really rename those files. This fixes the issue because `git add` will
now add the files as new files (as opposed to existing, just renamed
files).
Functionally, we do not change anything because we replace two `git mv
<old> <new>` calls (where `<new>` is completely overwritten and `git
add`ed later anyway) by `git rm <old>` calls (removing other files, too,
that are also completely overwritten and `git add`ed later).
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-17 16:29:21 +08:00
|
|
|
git rm one two &&
|
2018-11-08 12:40:23 +08:00
|
|
|
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 &&
|
t6042: work around speed optimization on Windows
When Git determines whether a file has changed, it looks at the mtime,
at the file size, and to detect changes even if the mtime is the same
(on Windows, the mtime granularity is 100ns, read: if two files are
written within the same 100ns time slot, they have the same mtime) and
even if the file size is the same, Git also looks at the inode/device
numbers.
This design obviously comes from a Linux background, where `lstat()`
calls were designed to be cheap.
On Windows, there is no `lstat()`. It has to be emulated. And while
obtaining the mtime and the file size is not all that expensive (you can
get both with a single `GetFileAttributesW()` call), obtaining the
equivalent of the inode and device numbers is very expensive (it
requires a call to `GetFileInformationByHandle()`, which in turn
requires a file handle, which is *a lot* more expensive than one might
imagine).
As it is very uncommon for developers to modify files within 100ns time
slots, Git for Windows chooses not to fill inode/device numbers
properly, but simply sets them to 0.
However, in t6042 the files file_v1 and file_v2 are typically written
within the same 100ns time slot, and they do not differ in file size. So
the minor modification is not picked up.
Let's work around this issue by avoiding the `git mv` calls in the
'mod6-setup: chains of rename/rename(1to2) and rename/rename(2to1)' test
case. The target files are overwritten anyway, so it is not like we
really rename those files. This fixes the issue because `git add` will
now add the files as new files (as opposed to existing, just renamed
files).
Functionally, we do not change anything because we replace two `git mv
<old> <new>` calls (where `<new>` is completely overwritten and `git
add`ed later anyway) by `git rm <old>` calls (removing other files, too,
that are also completely overwritten and `git add`ed later).
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-17 16:29:21 +08:00
|
|
|
git rm one two &&
|
2018-11-08 12:40:23 +08:00
|
|
|
mv -f file_v3 one &&
|
|
|
|
mv -f file_v6 three &&
|
|
|
|
git add one three &&
|
|
|
|
test_tick && git commit -m german
|
|
|
|
)
|
2019-10-23 05:22:51 +08:00
|
|
|
}
|
2018-11-08 12:40:23 +08:00
|
|
|
|
2018-11-08 12:40:27 +08:00
|
|
|
test_expect_success 'check nested conflicts from rename/rename(2to1)' '
|
2019-10-23 05:22:51 +08:00
|
|
|
test_setup_nested_conflicts_from_rename_rename &&
|
2018-11-08 12:40:23 +08:00
|
|
|
(
|
|
|
|
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
|
2020-11-19 07:44:38 +08:00
|
|
|
git cat-file -p main:one >base &&
|
2018-11-08 12:40:23 +08:00
|
|
|
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
|
2020-11-19 07:44:38 +08:00
|
|
|
git cat-file -p main:two >base &&
|
2018-11-08 12:40:23 +08:00
|
|
|
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
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2020-05-14 07:56:32 +08:00
|
|
|
# Testcase rename/rename(1to2) of a binary file
|
|
|
|
# Commit O: orig
|
|
|
|
# Commit A: orig-A
|
|
|
|
# Commit B: orig-B
|
|
|
|
# Expected: CONFLICT(rename/rename) message, three unstaged entries in the
|
|
|
|
# index, and contents of orig-[AB] at path orig-[AB]
|
|
|
|
test_setup_rename_rename_1_to_2_binary () {
|
|
|
|
test_create_repo rename_rename_1_to_2_binary &&
|
|
|
|
(
|
|
|
|
cd rename_rename_1_to_2_binary &&
|
|
|
|
|
|
|
|
echo '* binary' >.gitattributes &&
|
|
|
|
git add .gitattributes &&
|
|
|
|
|
|
|
|
test_seq 1 10 >orig &&
|
|
|
|
git add orig &&
|
|
|
|
git commit -m orig &&
|
|
|
|
|
|
|
|
git branch A &&
|
|
|
|
git branch B &&
|
|
|
|
|
|
|
|
git checkout A &&
|
|
|
|
git mv orig orig-A &&
|
|
|
|
test_seq 1 11 >orig-A &&
|
|
|
|
git add orig-A &&
|
|
|
|
git commit -m orig-A &&
|
|
|
|
|
|
|
|
git checkout B &&
|
|
|
|
git mv orig orig-B &&
|
|
|
|
test_seq 0 10 >orig-B &&
|
|
|
|
git add orig-B &&
|
|
|
|
git commit -m orig-B
|
|
|
|
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
test_expect_success 'rename/rename(1to2) with a binary file' '
|
|
|
|
test_setup_rename_rename_1_to_2_binary &&
|
|
|
|
(
|
|
|
|
cd rename_rename_1_to_2_binary &&
|
|
|
|
|
|
|
|
git checkout A^0 &&
|
|
|
|
|
|
|
|
test_must_fail git merge -s recursive B^0 &&
|
|
|
|
|
|
|
|
# Make sure the index has the right number of entries
|
|
|
|
git ls-files -s >actual &&
|
|
|
|
test_line_count = 4 actual &&
|
|
|
|
|
|
|
|
git rev-parse A:orig-A B:orig-B >expect &&
|
|
|
|
git hash-object orig-A orig-B >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2011-08-12 13:19:34 +08:00
|
|
|
test_done
|