From 56bfd762e5e602031eab8ce881b8ab0c50d2cfcc Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Wed, 8 Sep 2010 00:40:40 -0600 Subject: t3509: Add rename + D/F conflict testcase that recursive strategy fails When one side of a file rename matches a directory name on the other side, the recursive merge strategy will fail. This is true even if the merge is trivially resolvable. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t3509-cherry-pick-merge-df.sh | 66 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 't') diff --git a/t/t3509-cherry-pick-merge-df.sh b/t/t3509-cherry-pick-merge-df.sh index a5ccdbf8fc..eb5826f30e 100755 --- a/t/t3509-cherry-pick-merge-df.sh +++ b/t/t3509-cherry-pick-merge-df.sh @@ -32,4 +32,70 @@ test_expect_success SYMLINKS 'Cherry-pick succeeds with rename across D/F confli git cherry-pick branch ' +test_expect_success 'Setup rename with file on one side matching directory name on other' ' + git checkout --orphan nick-testcase && + git rm -rf . && + + >empty && + git add empty && + git commit -m "Empty file" && + + git checkout -b simple && + mv empty file && + mkdir empty && + mv file empty && + git add empty/file && + git commit -m "Empty file under empty dir" && + + echo content >newfile && + git add newfile && + git commit -m "New file" +' + +test_expect_success 'Cherry-pick succeeds with was_a_dir/file -> was_a_dir (resolve)' ' + git reset --hard && + git checkout -q nick-testcase^0 && + git cherry-pick --strategy=resolve simple +' + +test_expect_failure 'Cherry-pick succeeds with was_a_dir/file -> was_a_dir (recursive)' ' + git reset --hard && + git checkout -q nick-testcase^0 && + git cherry-pick --strategy=recursive simple +' + +test_expect_success 'Setup rename with file on one side matching different dirname on other' ' + git reset --hard && + git checkout --orphan mergeme && + git rm -rf . && + + mkdir sub && + mkdir othersub && + echo content > sub/file && + echo foo > othersub/whatever && + git add -A && + git commit -m "Common commmit" && + + git rm -rf othersub && + git mv sub/file othersub && + git commit -m "Commit to merge" && + + git checkout -b newhead mergeme~1 && + >independent-change && + git add independent-change && + git commit -m "Completely unrelated change" +' + +test_expect_success 'Cherry-pick with rename to different D/F conflict succeeds (resolve)' ' + git reset --hard && + git checkout -q newhead^0 && + git cherry-pick --strategy=resolve mergeme +' + +test_expect_failure 'Cherry-pick with rename to different D/F conflict succeeds (recursive)' ' + git reset --hard && + git checkout -q newhead^0 && + git cherry-pick --strategy=recursive mergeme +' + test_done -- cgit v1.2.3 From 86273e5764ab7faaa84c3de1a428ed24a6cfdf1f Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Wed, 8 Sep 2010 00:40:41 -0600 Subject: merge-recursive: D/F conflicts where was_a_dir/file -> was_a_dir In merge-recursive.c, whenever there was a rename where a file name on one side of the rename matches a directory name on the other side of the merge, then the very first check that string_list_has_string(&o->current_directory_set, ren1_dst) would trigger forcing it into marking it as a rename/directory conflict. However, if the path is only renamed on one side and a simple three-way merge between the separate files resolves cleanly, then we don't need to mark it as a rename/directory conflict. So, we can simply move the check for rename/directory conflicts after we've verified that there isn't a rename/rename conflict and that a threeway content merge doesn't work. This changes the particular error message one gets in the case where the directory name that a file on one side of the rename matches is not also part of the rename pair. For example, with commits containing the files: COMMON -> (HEAD, MERGE ) --------- --------------- ------- sub/file1 -> (sub/file1, newsub) -> (newsub/newfile, ) then previously when one tried to merge MERGE into HEAD, one would get CONFLICT (rename/directory): Rename sub/file1->newsub in HEAD directory newsub added in merge Renaming sub/file1 to newsub~HEAD instead Adding newsub/newfile Automatic merge failed; fix conflicts and then commit the result. After this patch, the error message will instead become: Removing newsub Adding newsub/newfile CONFLICT (file/directory): There is a directory with name newsub in merge. Adding newsub as newsub~HEAD Automatic merge failed; fix conflicts and then commit the result. That makes more sense to me, because git can't know that there's a conflict until after it's tried resolving paths involving newsub/newfile to see if they are still in the way at the end (and if newsub/newfile is not in the way at the end, there should be no conflict at all, which did not hold with git previously). Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t3509-cherry-pick-merge-df.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/t3509-cherry-pick-merge-df.sh b/t/t3509-cherry-pick-merge-df.sh index eb5826f30e..948ca1bce6 100755 --- a/t/t3509-cherry-pick-merge-df.sh +++ b/t/t3509-cherry-pick-merge-df.sh @@ -58,7 +58,7 @@ test_expect_success 'Cherry-pick succeeds with was_a_dir/file -> was_a_dir (reso git cherry-pick --strategy=resolve simple ' -test_expect_failure 'Cherry-pick succeeds with was_a_dir/file -> was_a_dir (recursive)' ' +test_expect_success 'Cherry-pick succeeds with was_a_dir/file -> was_a_dir (recursive)' ' git reset --hard && git checkout -q nick-testcase^0 && git cherry-pick --strategy=recursive simple @@ -92,7 +92,7 @@ test_expect_success 'Cherry-pick with rename to different D/F conflict succeeds git cherry-pick --strategy=resolve mergeme ' -test_expect_failure 'Cherry-pick with rename to different D/F conflict succeeds (recursive)' ' +test_expect_success 'Cherry-pick with rename to different D/F conflict succeeds (recursive)' ' git reset --hard && git checkout -q newhead^0 && git cherry-pick --strategy=recursive mergeme -- cgit v1.2.3 From 8a1c0d322e9b6963f3be6949475983d517d79796 Mon Sep 17 00:00:00 2001 From: "Schalk, Ken" Date: Mon, 20 Sep 2010 02:28:34 -0600 Subject: t3030: Add a testcase for resolvable rename/add conflict with symlinks d5af510 (RE: [PATCH] Avoid rename/add conflict when contents are identical 2010-09-01) avoided erroring out in a rename/add conflict when the contents were identical. A simpler fix could have handled that particular testcase, but it would not correctly handle the case where a symlink is involved. Add another testcase using symlinks, to avoid breaking that case. Signed-off-by: Ken Schalk Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t3030-merge-recursive.sh | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 't') diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index e66e550b24..3935c4b1c4 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -25,6 +25,10 @@ test_expect_success 'setup 1' ' git branch submod && git branch copy && git branch rename && + if test_have_prereq SYMLINKS + then + git branch rename-ln + fi && echo hello >>a && cp a d/e && @@ -255,7 +259,16 @@ test_expect_success 'setup 8' ' git mv a e && git add e && test_tick && - git commit -m "rename a->e" + git commit -m "rename a->e" && + if test_have_prereq SYMLINKS + then + git checkout rename-ln && + git mv a e && + ln -s e a && + git add a e && + test_tick && + git commit -m "rename a->e, symlink a->e" + fi ' test_expect_success 'setup 9' ' @@ -615,4 +628,26 @@ test_expect_success 'merge-recursive copy vs. rename' ' test_cmp expected actual ' +if test_have_prereq SYMLINKS +then + test_expect_success 'merge-recursive rename vs. rename/symlink' ' + + git checkout -f rename && + git merge rename-ln && + ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( + echo "100644 blob $o0 b" + echo "100644 blob $o0 c" + echo "100644 blob $o0 d/e" + echo "100644 blob $o0 e" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o0 0 d/e" + echo "100644 $o0 0 e" + ) >expected && + test_cmp expected actual + ' +fi + + test_done -- cgit v1.2.3 From df0b99f00458dd0d442b17d78dd4c171a89f7bb2 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:28:36 -0600 Subject: t6032: Add a test checking for excessive output from merge Previous D/F fixes I submitted (5a2580d and ae74548) had caused merge to become excessively spammy, which was fixed in 96ecac6 (merge-recursive: Avoid excessive output for and reprocessing of renames 2010-08-20). Add a new test to avoid repeating that mistake with my several upcoming changes. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6032-merge-large-rename.sh | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 't') diff --git a/t/t6032-merge-large-rename.sh b/t/t6032-merge-large-rename.sh index eac5ebac24..fdb6c25371 100755 --- a/t/t6032-merge-large-rename.sh +++ b/t/t6032-merge-large-rename.sh @@ -70,4 +70,34 @@ test_expect_success 'set merge.renamelimit to 5' ' test_rename 5 ok test_rename 6 fail +test_expect_success 'setup large simple rename' ' + git config --unset merge.renamelimit && + git config --unset diff.renamelimit && + + git reset --hard initial && + for i in $(count 200); do + make_text foo bar baz >$i + done && + git add . && + git commit -m create-files && + + git branch simple-change && + git checkout -b simple-rename && + + mkdir builtin && + git mv [0-9]* builtin/ && + git commit -m renamed && + + git checkout simple-change && + >unrelated-change && + git add unrelated-change && + git commit -m unrelated-change +' + +test_expect_success 'massive simple rename does not spam added files' ' + unset GIT_MERGE_VERBOSITY && + git merge --no-stat simple-rename | grep -v Removing >output && + test 5 -gt "$(wc -l < output)" +' + test_done -- cgit v1.2.3 From af6e17519978eed17c406206e1afc9f0501abf77 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:28:37 -0600 Subject: t6022: Add test combinations of {content conflict?, D/F conflict remains?} Add testing of the various ways that a renamed file to a path involved in a directory/file conflict may be involved in. This includes whether or not there are conflicts of the contents of the renamed file (if the file was modified on both sides of history), and whether the directory from the other side of the merge will disappear as a result of the merge or not. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6022-merge-rename.sh | 128 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) (limited to 't') diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index b66544b76d..a992206077 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -3,6 +3,11 @@ test_description='Merge-recursive merging renames' . ./test-lib.sh +modify () { + sed -e "$1" <"$2" >"$2.x" && + mv "$2.x" "$2" +} + test_expect_success setup \ ' cat >A <<\EOF && @@ -341,4 +346,127 @@ test_expect_success 'merge of identical changes in a renamed file' ' GIT_MERGE_VERBOSITY=3 git merge change+rename | grep "^Skipped B" ' +test_expect_success 'setup for rename + d/f conflicts' ' + git reset --hard && + git checkout --orphan dir-in-way && + git rm -rf . && + + mkdir sub && + mkdir dir && + printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >sub/file && + echo foo >dir/file-in-the-way && + git add -A && + git commit -m "Common commmit" && + + echo 11 >>sub/file && + echo more >>dir/file-in-the-way && + git add -u && + git commit -m "Commit to merge, with dir in the way" && + + git checkout -b dir-not-in-way && + git reset --soft HEAD^ && + git rm -rf dir && + git commit -m "Commit to merge, with dir removed" -- dir sub/file && + + git checkout -b renamed-file-has-no-conflicts dir-in-way~1 && + git rm -rf dir && + git rm sub/file && + printf "1\n2\n3\n4\n5555\n6\n7\n8\n9\n10\n" >dir && + git add dir && + git commit -m "Independent change" && + + git checkout -b renamed-file-has-conflicts dir-in-way~1 && + git rm -rf dir && + git mv sub/file dir && + echo 12 >>dir && + git add dir && + git commit -m "Conflicting change" +' + +printf "1\n2\n3\n4\n5555\n6\n7\n8\n9\n10\n11\n" >expected + +test_expect_success 'Rename+D/F conflict; renamed file merges + dir not in way' ' + git reset --hard && + git checkout -q renamed-file-has-no-conflicts^0 && + git merge --strategy=recursive dir-not-in-way && + git diff --quiet && + test -f dir && + test_cmp expected dir +' + +test_expect_failure 'Rename+D/F conflict; renamed file merges but dir in way' ' + git reset --hard && + rm -rf dir~* && + git checkout -q renamed-file-has-no-conflicts^0 && + test_must_fail git merge --strategy=recursive dir-in-way >output && + + grep "CONFLICT (delete/modify): dir/file-in-the-way" output && + grep "Auto-merging dir" output && + grep "Adding as dir~HEAD instead" output && + + test 2 = "$(git ls-files -u | wc -l)" && + test 2 = "$(git ls-files -u dir/file-in-the-way | wc -l)" && + + test_must_fail git diff --quiet && + test_must_fail git diff --cached --quiet && + + test -f dir/file-in-the-way && + test -f dir~HEAD && + test_cmp expected dir~HEAD +' + +cat >expected <<\EOF && +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +<<<<<<< HEAD +12 +======= +11 +>>>>>>> dir-not-in-way +EOF + +test_expect_failure 'Rename+D/F conflict; renamed file cannot merge, dir not in way' ' + git reset --hard && + rm -rf dir~* && + git checkout -q renamed-file-has-conflicts^0 && + test_must_fail git merge --strategy=recursive dir-not-in-way && + + test 3 = "$(git ls-files -u | wc -l)" && + test 3 = "$(git ls-files -u dir | wc -l)" && + + test_must_fail git diff --quiet && + test_must_fail git diff --cached --quiet && + + test -f dir && + test_cmp expected dir +' + +test_expect_failure 'Rename+D/F conflict; renamed file cannot merge and dir in the way' ' + modify s/dir-not-in-way/dir-in-way/ expected && + + git reset --hard && + rm -rf dir~* && + git checkout -q renamed-file-has-conflicts^0 && + test_must_fail git merge --strategy=recursive dir-in-way && + + test 5 = "$(git ls-files -u | wc -l)" && + test 3 = "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" && + test 2 = "$(git ls-files -u dir/file-in-the-way | wc -l)" && + + test_must_fail git diff --quiet && + test_must_fail git diff --cached --quiet && + + test -f dir/file-in-the-way && + test -f dir~HEAD && + test_cmp expected dir~HEAD +' + test_done -- cgit v1.2.3 From 3398f2f58317e1a22093a0149a5eae1fe208b024 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:28:38 -0600 Subject: t6022: Add tests for reversing order of merges when D/F conflicts present When merging two branches with some path involved in a D/F conflict, the choice of which branch to merge into the other matters for (at least) two reasons: (1) whether the working copy has a directory full of files that is in the way of a file, or a file exists that is in the way of a directory of files, (2) when the directory full of files does not disappear due to the merge, what files at the same paths should be renamed to (e.g. filename~HEAD vs. filename~otherbranch). Add some tests that reverse the merge order of two other tests, and which verify the contents are as expected (namely, that the results are identical other than modified-for-uniqueness filenames involving branch names). Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6022-merge-rename.sh | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 't') diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index a992206077..2839dfb5e0 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -415,6 +415,28 @@ test_expect_failure 'Rename+D/F conflict; renamed file merges but dir in way' ' test_cmp expected dir~HEAD ' +test_expect_failure 'Same as previous, but merged other way' ' + git reset --hard && + rm -rf dir~* && + git checkout -q dir-in-way^0 && + test_must_fail git merge --strategy=recursive renamed-file-has-no-conflicts >output 2>errors && + + ! grep "error: refusing to lose untracked file at" errors && + grep "CONFLICT (delete/modify): dir/file-in-the-way" output && + grep "Auto-merging dir" output && + grep "Adding as dir~renamed-file-has-no-conflicts instead" output && + + test 2 = "$(git ls-files -u | wc -l)" && + test 2 = "$(git ls-files -u dir/file-in-the-way | wc -l)" && + + test_must_fail git diff --quiet && + test_must_fail git diff --cached --quiet && + + test -f dir/file-in-the-way && + test -f dir~renamed-file-has-no-conflicts && + test_cmp expected dir~renamed-file-has-no-conflicts +' + cat >expected <<\EOF && 1 2 @@ -469,4 +491,40 @@ test_expect_failure 'Rename+D/F conflict; renamed file cannot merge and dir in t test_cmp expected dir~HEAD ' +cat >expected <<\EOF && +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +<<<<<<< HEAD +11 +======= +12 +>>>>>>> renamed-file-has-conflicts +EOF + +test_expect_failure 'Same as previous, but merged other way' ' + git reset --hard && + rm -rf dir~* && + git checkout -q dir-in-way^0 && + test_must_fail git merge --strategy=recursive renamed-file-has-conflicts && + + test 5 = "$(git ls-files -u | wc -l)" && + test 3 = "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" && + test 2 = "$(git ls-files -u dir/file-in-the-way | wc -l)" && + + test_must_fail git diff --quiet && + test_must_fail git diff --cached --quiet && + + test -f dir/file-in-the-way && + test -f dir~renamed-file-has-conflicts && + test_cmp expected dir~renamed-file-has-conflicts +' + test_done -- cgit v1.2.3 From 588504b694133cba85982fbace532d2156f859eb Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:28:39 -0600 Subject: t6022: Add tests with both rename source & dest involved in D/F conflicts Having the source of a rename be involved in a directory/file conflict does not currently pose any difficulties to the current merge-recursive algorithm (in contrast to destinations of renames and D/F conflicts). However, combining the two seemed like good testcases to include for completeness. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6022-merge-rename.sh | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 't') diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index 2839dfb5e0..2af863c126 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -527,4 +527,42 @@ test_expect_failure 'Same as previous, but merged other way' ' test_cmp expected dir~renamed-file-has-conflicts ' +test_expect_success 'setup both rename source and destination involved in D/F conflict' ' + git reset --hard && + git checkout --orphan rename-dest && + git rm -rf . && + git clean -fdqx && + + mkdir one && + echo stuff >one/file && + git add -A && + git commit -m "Common commmit" && + + git mv one/file destdir && + git commit -m "Renamed to destdir" && + + git checkout -b source-conflict HEAD~1 && + git rm -rf one && + mkdir destdir && + touch one destdir/foo && + git add -A && + git commit -m "Conflicts in the way" +' + +test_expect_failure 'both rename source and destination involved in D/F conflict' ' + git reset --hard && + rm -rf dir~* && + git checkout -q rename-dest^0 && + test_must_fail git merge --strategy=recursive source-conflict && + + test 1 = "$(git ls-files -u | wc -l)" && + + test_must_fail git diff --quiet && + + test -f destdir/foo && + test -f one && + test -f destdir~HEAD && + test "stuff" = "$(cat destdir~HEAD)" +' + test_done -- cgit v1.2.3 From 52304ecddf9458dcf4321c89c96a5e1bc025676d Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:28:40 -0600 Subject: t6022: Add paired rename+D/F conflict: (two/file, one/file) -> (one, two) An interesting testcase is having two files each in their own subdirectory getting renamed to the toplevel at the directory pathname of the other. Questions arise as to whether the order of operations matters and whether the directories can correctly get out of the way and make room for the new files. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6022-merge-rename.sh | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 't') diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index 2af863c126..a38b383c89 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -565,4 +565,67 @@ test_expect_failure 'both rename source and destination involved in D/F conflict test "stuff" = "$(cat destdir~HEAD)" ' +test_expect_success 'setup pair rename to parent of other (D/F conflicts)' ' + git reset --hard && + git checkout --orphan rename-two && + git rm -rf . && + git clean -fdqx && + + mkdir one && + mkdir two && + echo stuff >one/file && + echo other >two/file && + git add -A && + git commit -m "Common commmit" && + + git rm -rf one && + git mv two/file one && + git commit -m "Rename two/file -> one" && + + git checkout -b rename-one HEAD~1 && + git rm -rf two && + git mv one/file two && + rm -r one && + git commit -m "Rename one/file -> two" +' + +test_expect_failure 'pair rename to parent of other (D/F conflicts) w/ untracked dir' ' + git checkout -q rename-one^0 && + mkdir one && + test_must_fail git merge --strategy=recursive rename-two && + + test 2 = "$(git ls-files -u | wc -l)" && + test 1 = "$(git ls-files -u one | wc -l)" && + test 1 = "$(git ls-files -u two | wc -l)" && + + test_must_fail git diff --quiet && + + test 4 = $(find . | grep -v .git | wc -l) && + + test -d one && + test -f one~rename-two && + test -f two && + test "other" = $(cat one~rename-two) && + test "stuff" = $(cat two) +' + +test_expect_success 'pair rename to parent of other (D/F conflicts) w/ clean start' ' + git reset --hard && + git clean -fdqx && + test_must_fail git merge --strategy=recursive rename-two && + + test 2 = "$(git ls-files -u | wc -l)" && + test 1 = "$(git ls-files -u one | wc -l)" && + test 1 = "$(git ls-files -u two | wc -l)" && + + test_must_fail git diff --quiet && + + test 3 = $(find . | grep -v .git | wc -l) && + + test -f one && + test -f two && + test "other" = $(cat one) && + test "stuff" = $(cat two) +' + test_done -- cgit v1.2.3 From 707983484b7dcdd5fe3e09b30d0fdf6dac89c940 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:28:41 -0600 Subject: t6022: Add tests for rename/rename combined with D/F conflicts Add tests where one file is renamed to two different paths in different sides of history, and where each of the new files matches the name of a directory from the opposite side of history. Include tests for both the case where the merge results in those directories not being cleanly removed, and where those directories are cleanly removed during the merge. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6022-merge-rename.sh | 79 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 't') diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index a38b383c89..02dea16459 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -628,4 +628,83 @@ test_expect_success 'pair rename to parent of other (D/F conflicts) w/ clean sta test "stuff" = $(cat two) ' +test_expect_success 'setup rename of one file to two, with directories in the way' ' + git reset --hard && + git checkout --orphan first-rename && + git rm -rf . && + git clean -fdqx && + + echo stuff >original && + git add -A && + git commit -m "Common commmit" && + + mkdir two && + >two/file && + git add two/file && + git mv original one && + git commit -m "Put two/file in the way, rename to one" && + + git checkout -b second-rename HEAD~1 && + mkdir one && + >one/file && + git add one/file && + git mv original two && + git commit -m "Put one/file in the way, rename to two" +' + +test_expect_failure 'check handling of differently renamed file with D/F conflicts' ' + git checkout -q first-rename^0 && + test_must_fail git merge --strategy=recursive second-rename && + + test 5 = "$(git ls-files -s | wc -l)" && + test 3 = "$(git ls-files -u | wc -l)" && + test 1 = "$(git ls-files -u one | wc -l)" && + test 1 = "$(git ls-files -u two | wc -l)" && + test 1 = "$(git ls-files -u original | wc -l)" && + test 2 = "$(git ls-files -o | wc -l)" && + + test -f one/file && + test -f two/file && + test -f one~HEAD && + test -f two~second-rename && + ! test -f original +' + +test_expect_success 'setup rename one file to two; directories moving out of the way' ' + git reset --hard && + git checkout --orphan first-rename-redo && + git rm -rf . && + git clean -fdqx && + + echo stuff >original && + mkdir one two && + touch one/file two/file && + git add -A && + git commit -m "Common commmit" && + + git rm -rf one && + git mv original one && + git commit -m "Rename to one" && + + git checkout -b second-rename-redo HEAD~1 && + git rm -rf two && + git mv original two && + git commit -m "Rename to two" +' + +test_expect_failure 'check handling of differently renamed file with D/F conflicts' ' + git checkout -q first-rename-redo^0 && + test_must_fail git merge --strategy=recursive second-rename-redo && + + test 3 = "$(git ls-files -u | wc -l)" && + test 1 = "$(git ls-files -u one | wc -l)" && + test 1 = "$(git ls-files -u two | wc -l)" && + test 1 = "$(git ls-files -u original | wc -l)" && + test 0 = "$(git ls-files -o | wc -l)" && + + test -f one && + test -f two && + ! test -f original +' + test_done -- cgit v1.2.3 From d09c0a3935c6f28b1e7710f3f08a6ff5dec50f73 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:28:42 -0600 Subject: t6020: Modernize style a bit Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6020-merge-df.sh | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 't') diff --git a/t/t6020-merge-df.sh b/t/t6020-merge-df.sh index 490d397114..8662207d29 100755 --- a/t/t6020-merge-df.sh +++ b/t/t6020-merge-df.sh @@ -6,21 +6,26 @@ test_description='Test merge with directory/file conflicts' . ./test-lib.sh -test_expect_success 'prepare repository' \ -'echo "Hello" > init && -git add init && -git commit -m "Initial commit" && -git branch B && -mkdir dir && -echo "foo" > dir/foo && -git add dir/foo && -git commit -m "File: dir/foo" && -git checkout B && -echo "file dir" > dir && -git add dir && -git commit -m "File: dir"' - -test_expect_code 1 'Merge with d/f conflicts' 'git merge "merge msg" B master' +test_expect_success 'prepare repository' ' + echo Hello >init && + git add init && + git commit -m initial && + + git branch B && + mkdir dir && + echo foo >dir/foo && + git add dir/foo && + git commit -m "File: dir/foo" && + + git checkout B && + echo file dir >dir && + git add dir && + git commit -m "File: dir" +' + +test_expect_success 'Merge with d/f conflicts' ' + test_must_fail git merge master +' test_expect_success 'F/D conflict' ' git reset --hard && -- cgit v1.2.3 From fa0ae3b1ddeeb8c872f3804950fa95b5fc8b4138 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:28:43 -0600 Subject: t6020: Add a testcase for modify/delete + directory/file conflict Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6020-merge-df.sh | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 't') diff --git a/t/t6020-merge-df.sh b/t/t6020-merge-df.sh index 8662207d29..bc9db1a0f0 100755 --- a/t/t6020-merge-df.sh +++ b/t/t6020-merge-df.sh @@ -50,4 +50,51 @@ test_expect_success 'F/D conflict' ' git merge master ' +test_expect_success 'setup modify/delete + directory/file conflict' ' + git checkout --orphan modify && + git rm -rf . && + git clean -fdqx && + + printf "a\nb\nc\nd\ne\nf\ng\nh\n" >letters && + git add letters && + git commit -m initial && + + echo i >>letters && + git add letters && + git commit -m modified && + + git checkout -b delete HEAD^ && + git rm letters && + mkdir letters && + >letters/file && + git add letters && + git commit -m deleted +' + +test_expect_failure 'modify/delete + directory/file conflict' ' + git checkout delete^0 && + test_must_fail git merge modify && + + test 3 = $(git ls-files -s | wc -l) && + test 2 = $(git ls-files -u | wc -l) && + test 1 = $(git ls-files -o | wc -l) && + + test -f letters/file && + test -f letters~modify +' + +test_expect_failure 'modify/delete + directory/file conflict; other way' ' + git reset --hard && + git clean -f && + git checkout modify^0 && + test_must_fail git merge delete && + + test 3 = $(git ls-files -s | wc -l) && + test 2 = $(git ls-files -u | wc -l) && + test 1 = $(git ls-files -o | wc -l) && + + test -f letters/file && + test -f letters~HEAD +' + test_done -- cgit v1.2.3 From c976260d0f3d3f99dc3594e3f98436bfd920dc97 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:28:44 -0600 Subject: t6036: Test index and worktree state, not just that merge fails c94736a (merge-recursive: don't segfault while handling rename clashes 2009-07-30) added this testcase with an interesting corner case test, which previously had cased git to segfault. This test ensures that the segfault does not return and that the merge correctly fails; just add some checks that verify the state of the index and worktree after the merge are correct. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6036-recursive-corner-cases.sh | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 't') diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh index b874141658..1755073735 100755 --- a/t/t6036-recursive-corner-cases.sh +++ b/t/t6036-recursive-corner-cases.sh @@ -14,7 +14,7 @@ test_description='recursive merge corner cases' # R1 R2 # -test_expect_success setup ' +test_expect_success 'setup basic criss-cross + rename with no modifications' ' ten="0 1 2 3 4 5 6 7 8 9" for i in $ten do @@ -45,11 +45,29 @@ test_expect_success setup ' git tag R2 ' -test_expect_success merge ' +test_expect_success 'merge simple rename+criss-cross with no modifications' ' git reset --hard && git checkout L2^0 && - test_must_fail git merge -s recursive R2^0 + test_must_fail git merge -s recursive R2^0 && + + test 5 = $(git ls-files -s | wc -l) && + test 3 = $(git ls-files -u | wc -l) && + test 0 = $(git ls-files -o | wc -l) && + + test $(git rev-parse :0:one) = $(git rev-parse L2:one) && + test $(git rev-parse :0:two) = $(git rev-parse R2:two) && + test $(git rev-parse :2:three) = $(git rev-parse L2:three) && + test $(git rev-parse :3:three) = $(git rev-parse R2:three) && + + cp two merged && + >empty && + test_must_fail git merge-file \ + -L "Temporary merge branch 2" \ + -L "" \ + -L "Temporary merge branch 1" \ + merged empty one && + test $(git rev-parse :1:three) = $(git hash-object merged) ' test_done -- cgit v1.2.3 From 583942df098b04f545fb6bbe7b0d1590cc7b7b1d Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:28:45 -0600 Subject: t6036: Add a second testcase similar to the first but with content changes c94736a (merge-recursive: don't segfault while handling rename clashes 2009-07-30) added t6036 with a testcase that involved dual renames and a criss-cross merge. Add a test that is nearly identical, but which also involves content modification -- a case git currently does not merge correctly. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6036-recursive-corner-cases.sh | 76 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) (limited to 't') diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh index 1755073735..9206c22ffb 100755 --- a/t/t6036-recursive-corner-cases.sh +++ b/t/t6036-recursive-corner-cases.sh @@ -70,4 +70,80 @@ test_expect_success 'merge simple rename+criss-cross with no modifications' ' test $(git rev-parse :1:three) = $(git hash-object merged) ' +# +# Same as before, but modify L1 slightly: +# +# L1m L2 +# o---o +# / \ / \ +# o X ? +# \ / \ / +# o---o +# R1 R2 +# + +test_expect_success 'setup criss-cross + rename merges with basic modification' ' + git rm -rf . && + git clean -fdqx && + rm -rf .git && + git init && + + ten="0 1 2 3 4 5 6 7 8 9" + for i in $ten + do + echo line $i in a sample file + done >one && + for i in $ten + do + echo line $i in another sample file + done >two && + git add one two && + test_tick && git commit -m initial && + + git branch L1 && + git checkout -b R1 && + git mv one three && + echo more >>two && + git add two && + test_tick && git commit -m R1 && + + git checkout L1 && + git mv two three && + test_tick && git commit -m L1 && + + git checkout L1^0 && + test_tick && git merge -s ours R1 && + git tag L2 && + + git checkout R1^0 && + test_tick && git merge -s ours L1 && + git tag R2 +' + +test_expect_failure 'merge criss-cross + rename merges with basic modification' ' + git reset --hard && + git checkout L2^0 && + + test_must_fail git merge -s recursive R2^0 && + + test 5 = $(git ls-files -s | wc -l) && + test 3 = $(git ls-files -u | wc -l) && + test 0 = $(git ls-files -o | wc -l) && + + test $(git rev-parse :0:one) = $(git rev-parse L2:one) && + test $(git rev-parse :0:two) = $(git rev-parse R2:two) && + test $(git rev-parse :2:three) = $(git rev-parse L2:three) && + test $(git rev-parse :3:three) = $(git rev-parse R2:three) && + + head -n 10 two >merged && + cp one merge-me && + >empty && + test_must_fail git merge-file \ + -L "Temporary merge branch 2" \ + -L "" \ + -L "Temporary merge branch 1" \ + merged empty merge-me && + test $(git rev-parse :1:three) = $(git hash-object merged) +' + test_done -- cgit v1.2.3 From f63622c0a9665913f7ebade27910d8094ab4f9c4 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:28:46 -0600 Subject: t6036: Add testcase for undetected conflict If merging two lines of development involves a rename/add conflict, and two different people make such a merge but resolve it differently, and then someone tries to merge the resulting two merges, then they should clearly get a conflict due to the different resolutions from the previous developers. However, in some such cases the conflict would not be detected and git would silently accept one of the two versions being merged as the final merge resolution. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6036-recursive-corner-cases.sh | 85 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 't') diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh index 9206c22ffb..6c2b2bfa67 100755 --- a/t/t6036-recursive-corner-cases.sh +++ b/t/t6036-recursive-corner-cases.sh @@ -146,4 +146,89 @@ test_expect_failure 'merge criss-cross + rename merges with basic modification' test $(git rev-parse :1:three) = $(git hash-object merged) ' +# +# For the next test, we start with three commits in two lines of development +# which setup a rename/add conflict: +# Commit A: File 'a' exists +# Commit B: Rename 'a' -> 'new_a' +# Commit C: Modify 'a', create different 'new_a' +# Later, two different people merge and resolve differently: +# Commit D: Merge B & C, ignoring separately created 'new_a' +# Commit E: Merge B & C making use of some piece of secondary 'new_a' +# Finally, someone goes to merge D & E. Does git detect the conflict? +# +# B D +# o---o +# / \ / \ +# A o X ? F +# \ / \ / +# o---o +# C E +# + +test_expect_success 'setup differently handled merges of rename/add conflict' ' + git rm -rf . && + git clean -fdqx && + rm -rf .git && + git init && + + printf "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n" >a && + git add a && + test_tick && git commit -m A && + + git branch B && + git checkout -b C && + echo 10 >>a && + echo "other content" >>new_a && + git add a new_a && + test_tick && git commit -m C && + + git checkout B && + git mv a new_a && + test_tick && git commit -m B && + + git checkout B^0 && + test_must_fail git merge C && + git clean -f && + test_tick && git commit -m D && + git tag D && + + git checkout C^0 && + test_must_fail git merge B && + rm new_a~HEAD new_a && + printf "Incorrectly merged content" >>new_a && + git add -u && + test_tick && git commit -m E && + git tag E +' + +test_expect_failure 'git detects differently handled merges conflict' ' + git reset --hard && + git checkout D^0 && + + git merge -s recursive E^0 && { + echo "BAD: should have conflicted" + test "Incorrectly merged content" = "$(cat new_a)" && + echo "BAD: Silently accepted wrong content" + return 1 + } + + test 3 = $(git ls-files -s | wc -l) && + test 3 = $(git ls-files -u | wc -l) && + test 0 = $(git ls-files -o | wc -l) && + + test $(git rev-parse :2:new_a) = $(git rev-parse D:new_a) && + test $(git rev-parse :3:new_a) = $(git rev-parse E:new_a) && + + git cat-file -p B:new_a >>merged && + git cat-file -p C:new_a >>merge-me && + >empty && + test_must_fail git merge-file \ + -L "Temporary merge branch 2" \ + -L "" \ + -L "Temporary merge branch 1" \ + merged empty merge-me && + test $(git rev-parse :1:new_a) = $(git hash-object merged) +' + test_done -- cgit v1.2.3 From 2a669c341a857f53d946dec762e6f22a54b12dd2 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:28:59 -0600 Subject: merge-recursive: Avoid doubly merging rename/add conflict contents When a commit moves A to B while another commit created B (or moved C to B), and these two different commits serve as different merge-bases for a later merge, c94736a (merge-recursive: don't segfault while handling rename clashes 2009-07-30) added some special code to avoid segfaults. Since that commit, the two versions of B are merged in place (which could be potentially conflicting) and the intermediate result is used as the virtual ancestor. However, right before this special merge, try_merge was turned on, meaning that process_renames() would try an alternative merge that ignores the 'add' part of the conflict, and, if the merge is clean, store that as the new virtual ancestor. This could cause incorrect merging of criss-cross merges; it would typically result in just recording a slightly confusing merge base, but in some cases it could cause silent acceptance of one side of a merge as the final resolution when a conflict should have been flagged. When we do a special merge for such a rename/add conflict between merge-bases, turn try_merge off to avoid an inappropriate second merge. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6036-recursive-corner-cases.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh index 6c2b2bfa67..a2e5c5c08f 100755 --- a/t/t6036-recursive-corner-cases.sh +++ b/t/t6036-recursive-corner-cases.sh @@ -120,7 +120,7 @@ test_expect_success 'setup criss-cross + rename merges with basic modification' git tag R2 ' -test_expect_failure 'merge criss-cross + rename merges with basic modification' ' +test_expect_success 'merge criss-cross + rename merges with basic modification' ' git reset --hard && git checkout L2^0 && @@ -202,7 +202,7 @@ test_expect_success 'setup differently handled merges of rename/add conflict' ' git tag E ' -test_expect_failure 'git detects differently handled merges conflict' ' +test_expect_success 'git detects differently handled merges conflict' ' git reset --hard && git checkout D^0 && -- cgit v1.2.3 From 07413c5a3115df424bee1ebe627676df0734f787 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:29:00 -0600 Subject: merge-recursive: Move handling of double rename of one file to two Move the handling of rename/rename conflicts where one file is renamed to two different files, from process_renames() to process_df_entry(). Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6022-merge-rename.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't') diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index 02dea16459..1f29c0a94d 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -652,7 +652,7 @@ test_expect_success 'setup rename of one file to two, with directories in the wa git commit -m "Put one/file in the way, rename to two" ' -test_expect_failure 'check handling of differently renamed file with D/F conflicts' ' +test_expect_success 'check handling of differently renamed file with D/F conflicts' ' git checkout -q first-rename^0 && test_must_fail git merge --strategy=recursive second-rename && -- cgit v1.2.3 From 882fd11aff6f0e8add77e75924678cce875a0eaf Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:29:03 -0600 Subject: merge-recursive: Delay content merging for renames Move the handling of content merging for renames from process_renames() to process_df_entry(). Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6022-merge-rename.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't') diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index 1f29c0a94d..edbfa477c1 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -455,7 +455,7 @@ cat >expected <<\EOF && >>>>>>> dir-not-in-way EOF -test_expect_failure 'Rename+D/F conflict; renamed file cannot merge, dir not in way' ' +test_expect_success 'Rename+D/F conflict; renamed file cannot merge, dir not in way' ' git reset --hard && rm -rf dir~* && git checkout -q renamed-file-has-conflicts^0 && -- cgit v1.2.3 From a0de2f6bd3b79f7ab61ea90f795b964a7f7f3d6d Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:29:05 -0600 Subject: conflict_rename_delete(): Check whether D/F conflicts are still present If all the paths below some directory involved in a D/F conflict were not removed during the rest of the merge, then the contents of the file whose path conflicted needs to be recorded in file with an alternative filename. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6022-merge-rename.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index edbfa477c1..9bf190e03f 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -549,7 +549,7 @@ test_expect_success 'setup both rename source and destination involved in D/F co git commit -m "Conflicts in the way" ' -test_expect_failure 'both rename source and destination involved in D/F conflict' ' +test_expect_success 'both rename source and destination involved in D/F conflict' ' git reset --hard && rm -rf dir~* && git checkout -q rename-dest^0 && @@ -589,7 +589,7 @@ test_expect_success 'setup pair rename to parent of other (D/F conflicts)' ' git commit -m "Rename one/file -> two" ' -test_expect_failure 'pair rename to parent of other (D/F conflicts) w/ untracked dir' ' +test_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' ' git checkout -q rename-one^0 && mkdir one && test_must_fail git merge --strategy=recursive rename-two && -- cgit v1.2.3 From 2adc7dcc111636ed16601dc7516ced1c5cfda088 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:29:06 -0600 Subject: conflict_rename_rename_1to2(): Fix checks for presence of D/F conflicts This function is called from process_df_entry(), near the end of the merge. Rather than just checking whether one of the sides of the merge had a directory at the same path as one of our files, check whether that directory is still present by this point of our merge. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6022-merge-rename.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't') diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index 9bf190e03f..0b6700242c 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -692,7 +692,7 @@ test_expect_success 'setup rename one file to two; directories moving out of the git commit -m "Rename to two" ' -test_expect_failure 'check handling of differently renamed file with D/F conflicts' ' +test_expect_success 'check handling of differently renamed file with D/F conflicts' ' git checkout -q first-rename-redo^0 && test_must_fail git merge --strategy=recursive second-rename-redo && -- cgit v1.2.3 From 4ab9a157d06956ce5a1060a28404cbade3039fa2 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:29:07 -0600 Subject: merge_content(): Check whether D/F conflicts are still present If all the paths below some directory involved in a D/F conflict were not removed during the rest of the merge, then the contents of the file whose path conflicted needs to be recorded in file with an alternative filename. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6022-merge-rename.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 't') diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index 0b6700242c..422092e11c 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -394,7 +394,7 @@ test_expect_success 'Rename+D/F conflict; renamed file merges + dir not in way' test_cmp expected dir ' -test_expect_failure 'Rename+D/F conflict; renamed file merges but dir in way' ' +test_expect_success 'Rename+D/F conflict; renamed file merges but dir in way' ' git reset --hard && rm -rf dir~* && git checkout -q renamed-file-has-no-conflicts^0 && @@ -415,7 +415,7 @@ test_expect_failure 'Rename+D/F conflict; renamed file merges but dir in way' ' test_cmp expected dir~HEAD ' -test_expect_failure 'Same as previous, but merged other way' ' +test_expect_success 'Same as previous, but merged other way' ' git reset --hard && rm -rf dir~* && git checkout -q dir-in-way^0 && @@ -471,7 +471,7 @@ test_expect_success 'Rename+D/F conflict; renamed file cannot merge, dir not in test_cmp expected dir ' -test_expect_failure 'Rename+D/F conflict; renamed file cannot merge and dir in the way' ' +test_expect_success 'Rename+D/F conflict; renamed file cannot merge and dir in the way' ' modify s/dir-not-in-way/dir-in-way/ expected && git reset --hard && @@ -509,7 +509,7 @@ cat >expected <<\EOF && >>>>>>> renamed-file-has-conflicts EOF -test_expect_failure 'Same as previous, but merged other way' ' +test_expect_success 'Same as previous, but merged other way' ' git reset --hard && rm -rf dir~* && git checkout -q dir-in-way^0 && -- cgit v1.2.3 From 84a08a47b9559e76df96645c536845f31ba4dc7b Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:29:08 -0600 Subject: handle_delete_modify(): Check whether D/F conflicts are still present If all the paths below some directory involved in a D/F conflict were not removed during the rest of the merge, then the contents of the file whose path conflicted needs to be recorded in file with an alternative filename. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6020-merge-df.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't') diff --git a/t/t6020-merge-df.sh b/t/t6020-merge-df.sh index bc9db1a0f0..7b1ce82707 100755 --- a/t/t6020-merge-df.sh +++ b/t/t6020-merge-df.sh @@ -71,7 +71,7 @@ test_expect_success 'setup modify/delete + directory/file conflict' ' git commit -m deleted ' -test_expect_failure 'modify/delete + directory/file conflict' ' +test_expect_success 'modify/delete + directory/file conflict' ' git checkout delete^0 && test_must_fail git merge modify && -- cgit v1.2.3 From ef02b317212443036be6007bba3a1a5946460dc9 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 20 Sep 2010 02:29:09 -0600 Subject: merge-recursive: Make room for directories in D/F conflicts When there are unmerged entries present, make sure to check for D/F conflicts first and remove any files present in HEAD that would be in the way of creating files below the correspondingly named directory. Such files will be processed again at the end of the merge in process_df_entry(); at that time we will be able to tell if we need to and can reinstate the file, whether we need to place its contents in a different file due to the directory still being present, etc. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t6020-merge-df.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't') diff --git a/t/t6020-merge-df.sh b/t/t6020-merge-df.sh index 7b1ce82707..b129f1dbd5 100755 --- a/t/t6020-merge-df.sh +++ b/t/t6020-merge-df.sh @@ -83,7 +83,7 @@ test_expect_success 'modify/delete + directory/file conflict' ' test -f letters~modify ' -test_expect_failure 'modify/delete + directory/file conflict; other way' ' +test_expect_success 'modify/delete + directory/file conflict; other way' ' git reset --hard && git clean -f && git checkout modify^0 && -- cgit v1.2.3 From 9f6cea97c97ee505bd6771db7df69f04df9b4fc4 Mon Sep 17 00:00:00 2001 From: Brian Gernhardt Date: Mon, 8 Nov 2010 16:29:26 -0500 Subject: t6022: Use -eq not = to test output of wc -l When comparing numbers such as "3" to "$(wc -l)", we should check for numerical equality using -eq instead of string equality using = because some implementations of wc output extra whitespace. Signed-off-by: Brian Gernhardt Signed-off-by: Junio C Hamano --- t/t6022-merge-rename.sh | 64 ++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 't') diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index 422092e11c..66473f088e 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -404,8 +404,8 @@ test_expect_success 'Rename+D/F conflict; renamed file merges but dir in way' ' grep "Auto-merging dir" output && grep "Adding as dir~HEAD instead" output && - test 2 = "$(git ls-files -u | wc -l)" && - test 2 = "$(git ls-files -u dir/file-in-the-way | wc -l)" && + test 2 -eq "$(git ls-files -u | wc -l)" && + test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" && test_must_fail git diff --quiet && test_must_fail git diff --cached --quiet && @@ -426,8 +426,8 @@ test_expect_success 'Same as previous, but merged other way' ' grep "Auto-merging dir" output && grep "Adding as dir~renamed-file-has-no-conflicts instead" output && - test 2 = "$(git ls-files -u | wc -l)" && - test 2 = "$(git ls-files -u dir/file-in-the-way | wc -l)" && + test 2 -eq "$(git ls-files -u | wc -l)" && + test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" && test_must_fail git diff --quiet && test_must_fail git diff --cached --quiet && @@ -461,8 +461,8 @@ test_expect_success 'Rename+D/F conflict; renamed file cannot merge, dir not in git checkout -q renamed-file-has-conflicts^0 && test_must_fail git merge --strategy=recursive dir-not-in-way && - test 3 = "$(git ls-files -u | wc -l)" && - test 3 = "$(git ls-files -u dir | wc -l)" && + test 3 -eq "$(git ls-files -u | wc -l)" && + test 3 -eq "$(git ls-files -u dir | wc -l)" && test_must_fail git diff --quiet && test_must_fail git diff --cached --quiet && @@ -479,9 +479,9 @@ test_expect_success 'Rename+D/F conflict; renamed file cannot merge and dir in t git checkout -q renamed-file-has-conflicts^0 && test_must_fail git merge --strategy=recursive dir-in-way && - test 5 = "$(git ls-files -u | wc -l)" && - test 3 = "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" && - test 2 = "$(git ls-files -u dir/file-in-the-way | wc -l)" && + test 5 -eq "$(git ls-files -u | wc -l)" && + test 3 -eq "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" && + test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" && test_must_fail git diff --quiet && test_must_fail git diff --cached --quiet && @@ -515,9 +515,9 @@ test_expect_success 'Same as previous, but merged other way' ' git checkout -q dir-in-way^0 && test_must_fail git merge --strategy=recursive renamed-file-has-conflicts && - test 5 = "$(git ls-files -u | wc -l)" && - test 3 = "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" && - test 2 = "$(git ls-files -u dir/file-in-the-way | wc -l)" && + test 5 -eq "$(git ls-files -u | wc -l)" && + test 3 -eq "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" && + test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" && test_must_fail git diff --quiet && test_must_fail git diff --cached --quiet && @@ -555,7 +555,7 @@ test_expect_success 'both rename source and destination involved in D/F conflict git checkout -q rename-dest^0 && test_must_fail git merge --strategy=recursive source-conflict && - test 1 = "$(git ls-files -u | wc -l)" && + test 1 -eq "$(git ls-files -u | wc -l)" && test_must_fail git diff --quiet && @@ -594,13 +594,13 @@ test_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked mkdir one && test_must_fail git merge --strategy=recursive rename-two && - test 2 = "$(git ls-files -u | wc -l)" && - test 1 = "$(git ls-files -u one | wc -l)" && - test 1 = "$(git ls-files -u two | wc -l)" && + test 2 -eq "$(git ls-files -u | wc -l)" && + test 1 -eq "$(git ls-files -u one | wc -l)" && + test 1 -eq "$(git ls-files -u two | wc -l)" && test_must_fail git diff --quiet && - test 4 = $(find . | grep -v .git | wc -l) && + test 4 -eq $(find . | grep -v .git | wc -l) && test -d one && test -f one~rename-two && @@ -614,13 +614,13 @@ test_expect_success 'pair rename to parent of other (D/F conflicts) w/ clean sta git clean -fdqx && test_must_fail git merge --strategy=recursive rename-two && - test 2 = "$(git ls-files -u | wc -l)" && - test 1 = "$(git ls-files -u one | wc -l)" && - test 1 = "$(git ls-files -u two | wc -l)" && + test 2 -eq "$(git ls-files -u | wc -l)" && + test 1 -eq "$(git ls-files -u one | wc -l)" && + test 1 -eq "$(git ls-files -u two | wc -l)" && test_must_fail git diff --quiet && - test 3 = $(find . | grep -v .git | wc -l) && + test 3 -eq $(find . | grep -v .git | wc -l) && test -f one && test -f two && @@ -656,12 +656,12 @@ test_expect_success 'check handling of differently renamed file with D/F conflic git checkout -q first-rename^0 && test_must_fail git merge --strategy=recursive second-rename && - test 5 = "$(git ls-files -s | wc -l)" && - test 3 = "$(git ls-files -u | wc -l)" && - test 1 = "$(git ls-files -u one | wc -l)" && - test 1 = "$(git ls-files -u two | wc -l)" && - test 1 = "$(git ls-files -u original | wc -l)" && - test 2 = "$(git ls-files -o | wc -l)" && + test 5 -eq "$(git ls-files -s | wc -l)" && + test 3 -eq "$(git ls-files -u | wc -l)" && + test 1 -eq "$(git ls-files -u one | wc -l)" && + test 1 -eq "$(git ls-files -u two | wc -l)" && + test 1 -eq "$(git ls-files -u original | wc -l)" && + test 2 -eq "$(git ls-files -o | wc -l)" && test -f one/file && test -f two/file && @@ -696,11 +696,11 @@ test_expect_success 'check handling of differently renamed file with D/F conflic git checkout -q first-rename-redo^0 && test_must_fail git merge --strategy=recursive second-rename-redo && - test 3 = "$(git ls-files -u | wc -l)" && - test 1 = "$(git ls-files -u one | wc -l)" && - test 1 = "$(git ls-files -u two | wc -l)" && - test 1 = "$(git ls-files -u original | wc -l)" && - test 0 = "$(git ls-files -o | wc -l)" && + test 3 -eq "$(git ls-files -u | wc -l)" && + test 1 -eq "$(git ls-files -u one | wc -l)" && + test 1 -eq "$(git ls-files -u two | wc -l)" && + test 1 -eq "$(git ls-files -u original | wc -l)" && + test 0 -eq "$(git ls-files -o | wc -l)" && test -f one && test -f two && -- cgit v1.2.3