git/t/t3401-rebase-and-am-rename.sh

214 lines
4 KiB
Bash
Raw Normal View History

#!/bin/sh
test_description='git rebase + directory rename tests'
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh
test_expect_success 'setup testcase where directory rename should be detected' '
test_create_repo dir-rename &&
(
cd dir-rename &&
mkdir x &&
test_seq 1 10 >x/a &&
test_seq 11 20 >x/b &&
test_seq 21 30 >x/c &&
test_write_lines a b c d e f g h i >l &&
git add x l &&
git commit -m "Initial" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv x y &&
git mv l letters &&
git commit -m "Rename x to y, l to letters" &&
git checkout B &&
echo j >>l &&
test_seq 31 40 >x/d &&
git add l x/d &&
git commit -m "Modify l, add x/d"
)
'
test_expect_success 'rebase --interactive: directory rename detected' '
(
cd dir-rename &&
git checkout B^0 &&
set_fake_editor &&
merge-recursive: switch directory rename detection default When all of x/a, x/b, and x/c have moved to z/a, z/b, and z/c on one branch, there is a question about whether x/d added on a different branch should remain at x/d or appear at z/d when the two branches are merged. There are different possible viewpoints here: A) The file was placed at x/d; it's unrelated to the other files in x/ so it doesn't matter that all the files from x/ moved to z/ on one branch; x/d should still remain at x/d. B) x/d is related to the other files in x/, and x/ was renamed to z/; therefore x/d should be moved to z/d. Since there was no ability to detect directory renames prior to git-2.18, users experienced (A) regardless of context. Choice (B) was implemented in git-2.18, with no option to go back to (A), and has been in use since. However, one user reported that the merge results did not match their expectations, making the change of default problematic, especially since there was no notice printed when directory rename detection moved files. Note that there is also a third possibility here: C) There are different answers depending on the context and content that cannot be determined by git, so this is a conflict. Use a higher stage in the index to record the conflict and notify the user of the potential issue instead of silently selecting a resolution for them. Add an option for users to specify their preference for whether to use directory rename detection, and default to (C). Even when directory rename detection is on, add notice messages about files moved into new directories. As a sidenote, x/d did not have to be a new file here; it could have already existed at some other path and been renamed to x/d, with directory rename detection just renaming it again to z/d. Thus, it's not just new files, but also a modification to all rename types (normal renames, rename/add, rename/delete, rename/rename(1to1), rename/rename(1to2), and rename/rename(2to1)). Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-05 15:00:26 +00:00
FAKE_LINES="1" git -c merge.directoryRenames=true rebase --interactive A &&
git ls-files -s >out &&
test_line_count = 5 out &&
test_path_is_file y/d &&
test_path_is_missing x/d
)
'
rebase: rename the two primary rebase backends Two related changes, with separate rationale for each: Rename the 'interactive' backend to 'merge' because: * 'interactive' as a name caused confusion; this backend has been used for many kinds of non-interactive rebases, and will probably be used in the future for more non-interactive rebases than interactive ones given that we are making it the default. * 'interactive' is not the underlying strategy; merging is. * the directory where state is stored is not called .git/rebase-interactive but .git/rebase-merge. Rename the 'am' backend to 'apply' because: * Few users are familiar with git-am as a reference point. * Related to the above, the name 'am' makes sentences in the documentation harder for users to read and comprehend (they may read it as the verb from "I am"); avoiding this difficult places a large burden on anyone writing documentation about this backend to be very careful with quoting and sentence structure and often forces annoying redundancy to try to avoid such problems. * Users stumble over pronunciation ("am" as in "I am a person not a backend" or "am" as in "the first and thirteenth letters in the alphabet in order are "A-M"); this may drive confusion when one user tries to explain to another what they are doing. * While "am" is the tool driving this backend, the tool driving git-am is git-apply, and since we are driving towards lower-level tools for the naming of the merge backend we may as well do so here too. * The directory where state is stored has never been called .git/rebase-am, it was always called .git/rebase-apply. For all the reasons listed above: * Modify the documentation to refer to the backends with the new names * Provide a brief note in the documentation connecting the new names to the old names in case users run across the old names anywhere (e.g. in old release notes or older versions of the documentation) * Change the (new) --am command line flag to --apply * Rename some enums, variables, and functions to reinforce the new backend names for us as well. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-02-15 21:36:41 +00:00
test_expect_failure 'rebase --apply: directory rename detected' '
(
cd dir-rename &&
git checkout B^0 &&
rebase: rename the two primary rebase backends Two related changes, with separate rationale for each: Rename the 'interactive' backend to 'merge' because: * 'interactive' as a name caused confusion; this backend has been used for many kinds of non-interactive rebases, and will probably be used in the future for more non-interactive rebases than interactive ones given that we are making it the default. * 'interactive' is not the underlying strategy; merging is. * the directory where state is stored is not called .git/rebase-interactive but .git/rebase-merge. Rename the 'am' backend to 'apply' because: * Few users are familiar with git-am as a reference point. * Related to the above, the name 'am' makes sentences in the documentation harder for users to read and comprehend (they may read it as the verb from "I am"); avoiding this difficult places a large burden on anyone writing documentation about this backend to be very careful with quoting and sentence structure and often forces annoying redundancy to try to avoid such problems. * Users stumble over pronunciation ("am" as in "I am a person not a backend" or "am" as in "the first and thirteenth letters in the alphabet in order are "A-M"); this may drive confusion when one user tries to explain to another what they are doing. * While "am" is the tool driving this backend, the tool driving git-am is git-apply, and since we are driving towards lower-level tools for the naming of the merge backend we may as well do so here too. * The directory where state is stored has never been called .git/rebase-am, it was always called .git/rebase-apply. For all the reasons listed above: * Modify the documentation to refer to the backends with the new names * Provide a brief note in the documentation connecting the new names to the old names in case users run across the old names anywhere (e.g. in old release notes or older versions of the documentation) * Change the (new) --am command line flag to --apply * Rename some enums, variables, and functions to reinforce the new backend names for us as well. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-02-15 21:36:41 +00:00
git -c merge.directoryRenames=true rebase --apply A &&
git ls-files -s >out &&
test_line_count = 5 out &&
test_path_is_file y/d &&
test_path_is_missing x/d
)
'
test_expect_success 'rebase --merge: directory rename detected' '
(
cd dir-rename &&
git checkout B^0 &&
merge-recursive: switch directory rename detection default When all of x/a, x/b, and x/c have moved to z/a, z/b, and z/c on one branch, there is a question about whether x/d added on a different branch should remain at x/d or appear at z/d when the two branches are merged. There are different possible viewpoints here: A) The file was placed at x/d; it's unrelated to the other files in x/ so it doesn't matter that all the files from x/ moved to z/ on one branch; x/d should still remain at x/d. B) x/d is related to the other files in x/, and x/ was renamed to z/; therefore x/d should be moved to z/d. Since there was no ability to detect directory renames prior to git-2.18, users experienced (A) regardless of context. Choice (B) was implemented in git-2.18, with no option to go back to (A), and has been in use since. However, one user reported that the merge results did not match their expectations, making the change of default problematic, especially since there was no notice printed when directory rename detection moved files. Note that there is also a third possibility here: C) There are different answers depending on the context and content that cannot be determined by git, so this is a conflict. Use a higher stage in the index to record the conflict and notify the user of the potential issue instead of silently selecting a resolution for them. Add an option for users to specify their preference for whether to use directory rename detection, and default to (C). Even when directory rename detection is on, add notice messages about files moved into new directories. As a sidenote, x/d did not have to be a new file here; it could have already existed at some other path and been renamed to x/d, with directory rename detection just renaming it again to z/d. Thus, it's not just new files, but also a modification to all rename types (normal renames, rename/add, rename/delete, rename/rename(1to1), rename/rename(1to2), and rename/rename(2to1)). Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-05 15:00:26 +00:00
git -c merge.directoryRenames=true rebase --merge A &&
git ls-files -s >out &&
test_line_count = 5 out &&
test_path_is_file y/d &&
test_path_is_missing x/d
)
'
test_expect_failure 'am: directory rename detected' '
(
cd dir-rename &&
git checkout A^0 &&
git format-patch -1 B &&
merge-recursive: switch directory rename detection default When all of x/a, x/b, and x/c have moved to z/a, z/b, and z/c on one branch, there is a question about whether x/d added on a different branch should remain at x/d or appear at z/d when the two branches are merged. There are different possible viewpoints here: A) The file was placed at x/d; it's unrelated to the other files in x/ so it doesn't matter that all the files from x/ moved to z/ on one branch; x/d should still remain at x/d. B) x/d is related to the other files in x/, and x/ was renamed to z/; therefore x/d should be moved to z/d. Since there was no ability to detect directory renames prior to git-2.18, users experienced (A) regardless of context. Choice (B) was implemented in git-2.18, with no option to go back to (A), and has been in use since. However, one user reported that the merge results did not match their expectations, making the change of default problematic, especially since there was no notice printed when directory rename detection moved files. Note that there is also a third possibility here: C) There are different answers depending on the context and content that cannot be determined by git, so this is a conflict. Use a higher stage in the index to record the conflict and notify the user of the potential issue instead of silently selecting a resolution for them. Add an option for users to specify their preference for whether to use directory rename detection, and default to (C). Even when directory rename detection is on, add notice messages about files moved into new directories. As a sidenote, x/d did not have to be a new file here; it could have already existed at some other path and been renamed to x/d, with directory rename detection just renaming it again to z/d. Thus, it's not just new files, but also a modification to all rename types (normal renames, rename/add, rename/delete, rename/rename(1to1), rename/rename(1to2), and rename/rename(2to1)). Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-05 15:00:26 +00:00
git -c merge.directoryRenames=true am --3way 0001*.patch &&
git ls-files -s >out &&
test_line_count = 5 out &&
test_path_is_file y/d &&
test_path_is_missing x/d
)
'
test_expect_success 'setup testcase where directory rename should NOT be detected' '
test_create_repo no-dir-rename &&
(
cd no-dir-rename &&
mkdir x &&
test_seq 1 10 >x/a &&
test_seq 11 20 >x/b &&
test_seq 21 30 >x/c &&
echo original >project_info &&
git add x project_info &&
git commit -m "Initial" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
echo v2 >project_info &&
git add project_info &&
git commit -m "Modify project_info" &&
git checkout B &&
mkdir y &&
git mv x/c y/c &&
echo v1 >project_info &&
git add project_info &&
git commit -m "Rename x/c to y/c, modify project_info"
)
'
test_expect_success 'rebase --interactive: NO directory rename' '
test_when_finished "git -C no-dir-rename rebase --abort" &&
(
cd no-dir-rename &&
git checkout B^0 &&
set_fake_editor &&
test_must_fail env FAKE_LINES="1" git rebase --interactive A &&
git ls-files -s >out &&
test_line_count = 6 out &&
test_path_is_file x/a &&
test_path_is_file x/b &&
test_path_is_missing x/c
)
'
test_expect_success 'rebase (am): NO directory rename' '
test_when_finished "git -C no-dir-rename rebase --abort" &&
(
cd no-dir-rename &&
git checkout B^0 &&
set_fake_editor &&
test_must_fail git rebase A &&
git ls-files -s >out &&
test_line_count = 6 out &&
test_path_is_file x/a &&
test_path_is_file x/b &&
test_path_is_missing x/c
)
'
test_expect_success 'rebase --merge: NO directory rename' '
test_when_finished "git -C no-dir-rename rebase --abort" &&
(
cd no-dir-rename &&
git checkout B^0 &&
set_fake_editor &&
test_must_fail git rebase --merge A &&
git ls-files -s >out &&
test_line_count = 6 out &&
test_path_is_file x/a &&
test_path_is_file x/b &&
test_path_is_missing x/c
)
'
test_expect_success 'am: NO directory rename' '
test_when_finished "git -C no-dir-rename am --abort" &&
(
cd no-dir-rename &&
git checkout A^0 &&
git format-patch -1 B &&
test_must_fail git am --3way 0001*.patch &&
git ls-files -s >out &&
test_line_count = 6 out &&
test_path_is_file x/a &&
test_path_is_file x/b &&
test_path_is_missing x/c
)
'
test_done