diff mbox series

[v1,1/7] t7002: add tests for moving from in-cone to out-of-cone

Message ID 20220719132809.409247-2-shaoxuan.yuan02@gmail.com (mailing list archive)
State Superseded
Headers show
Series mv: from in-cone to out-of-cone | expand

Commit Message

Shaoxuan Yuan July 19, 2022, 1:28 p.m. UTC
Add corresponding tests to test that user can move an in-cone <source>
to out-of-cone <destination> when --sparse is supplied.

Such <source> can be either clean or dirty, and moving it results in
different behaviors:

A clean move should move the <source> to the <destination>, both in the
working tree and the index, then remove the resulted path from the
working tree, and turn on its CE_SKIP_WORKTREE bit.

A dirty move should move the <source> to the <destination>, both in the
working tree and the index, but should *not* remove the resulted path
from the working tree and should *not* turn on its CE_SKIP_WORKTREE bit.
Instead advise user to "git add" this path and run "git sparse-checkout
reapply" to re-sparsify that path.

Also make sure that if <destination> exists in the index (existing
check for if <destination> is in the worktree is not enough in
in-to-out moves), warn user against the overwrite. And Git should force
the overwrite when supplied with -f or --force.

Signed-off-by: Shaoxuan Yuan <shaoxuan.yuan02@gmail.com>
---
 t/t7002-mv-sparse-checkout.sh | 148 +++++++++++++++++++++++++++++++++-
 1 file changed, 147 insertions(+), 1 deletion(-)

Comments

Ævar Arnfjörð Bjarmason July 19, 2022, 2:52 p.m. UTC | #1
On Tue, Jul 19 2022, Shaoxuan Yuan wrote:

> +	! grep -x "H sub/d" actual &&
> +	grep -x "S folder1/d" actual

This *might* be a portability problem, but probably not. It's listed in
POSIX:
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html

But it appears we have no "grep" use of the "-x" option in-tree, at
least from what I found with grepping..
Derrick Stolee July 19, 2022, 5:36 p.m. UTC | #2
On 7/19/2022 10:52 AM, Ævar Arnfjörð Bjarmason wrote:
> 
> On Tue, Jul 19 2022, Shaoxuan Yuan wrote:
> 
>> +	! grep -x "H sub/d" actual &&
>> +	grep -x "S folder1/d" actual
> 
> This *might* be a portability problem, but probably not. It's listed in
> POSIX:
> https://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html
> 
> But it appears we have no "grep" use of the "-x" option in-tree, at
> least from what I found with grepping..

It is helpful to recommend a working alternative when pointing out
an issue like this.

Here, the '-x' option means to match the entire line.

Would using ^ and $ help here?

	! grep "^H sub/d\$" actual &&
	grep "^S folder1/d\$" actual

I haven't tested this, but hopefully the idea is sound. If not,
then you could make the names be sufficiently unique that
whole-lines are the only way they could match. We do have some
expectation about what lines are possible in this index, since
we constructed the example repo from scratch.

Thanks,
-Stolee
Junio C Hamano July 19, 2022, 6:30 p.m. UTC | #3
Derrick Stolee <derrickstolee@github.com> writes:

> On 7/19/2022 10:52 AM, Ævar Arnfjörð Bjarmason wrote:
>> 
>> On Tue, Jul 19 2022, Shaoxuan Yuan wrote:
>> 
>>> +	! grep -x "H sub/d" actual &&
>>> +	grep -x "S folder1/d" actual
>> 
>> This *might* be a portability problem, but probably not. It's listed in
>> POSIX:
>> https://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html
>> 
>> But it appears we have no "grep" use of the "-x" option in-tree, at
>> least from what I found with grepping..
>
> It is helpful to recommend a working alternative when pointing out
> an issue like this.
>
> Here, the '-x' option means to match the entire line.
>
> Would using ^ and $ help here?

Yup, that would be quite reasonable and removes the need to use,
learn about, or have your readers wonder about the "-x" option; I do
not think I saw a grep that did not understand the option, though.

Thanks.
diff mbox series

Patch

diff --git a/t/t7002-mv-sparse-checkout.sh b/t/t7002-mv-sparse-checkout.sh
index 71fe29690f..c27fcdbfd0 100755
--- a/t/t7002-mv-sparse-checkout.sh
+++ b/t/t7002-mv-sparse-checkout.sh
@@ -28,12 +28,25 @@  test_expect_success 'setup' "
 	updated in the index:
 	EOF
 
-	cat >sparse_hint <<-EOF
+	cat >sparse_hint <<-EOF &&
 	hint: If you intend to update such entries, try one of the following:
 	hint: * Use the --sparse option.
 	hint: * Disable or modify the sparsity rules.
 	hint: Disable this message with \"git config advice.updateSparsePath false\"
 	EOF
+
+	cat >dirty_error_header <<-EOF &&
+	The following paths have been moved outside the
+	sparse-checkout definition but are not sparse due to local
+	modifications.
+	EOF
+
+	cat >dirty_hint <<-EOF
+	hint: To correct the sparsity of these paths, do the following:
+	hint: * Use \"git add --sparse <paths>\" to update the index
+	hint: * Use \"git sparse-checkout reapply\" to apply the sparsity rules
+	hint: Disable this message with \"git config advice.updateSparsePath false\"
+	EOF
 "
 
 test_expect_success 'mv refuses to move sparse-to-sparse' '
@@ -290,4 +303,137 @@  test_expect_success 'move sparse file to existing destination with --force and -
 	test_cmp expect sub/file1
 '
 
+test_expect_failure 'move clean path from in-cone to out-of-cone' '
+	test_when_finished "cleanup_sparse_checkout" &&
+	setup_sparse_checkout &&
+
+	test_must_fail git mv sub/d folder1 2>stderr &&
+	cat sparse_error_header >expect &&
+	echo "folder1/d" >>expect &&
+	cat sparse_hint >>expect &&
+	test_cmp expect stderr &&
+
+	git mv --sparse sub/d folder1 2>stderr &&
+	test_must_be_empty stderr &&
+
+	test_path_is_missing sub/d &&
+	test_path_is_missing folder1/d &&
+	git ls-files -t >actual &&
+	! grep -x "H sub/d" actual &&
+	grep -x "S folder1/d" actual
+'
+
+test_expect_failure 'move clean path from in-cone to out-of-cone overwrite' '
+	test_when_finished "cleanup_sparse_checkout" &&
+	setup_sparse_checkout &&
+	echo "sub/file1 overwrite" >sub/file1 &&
+	git add sub/file1 &&
+
+	test_must_fail git mv sub/file1 folder1 2>stderr &&
+	cat sparse_error_header >expect &&
+	echo "folder1/file1" >>expect &&
+	cat sparse_hint >>expect &&
+	test_cmp expect stderr &&
+
+	test_must_fail git mv --sparse sub/file1 folder1 2>stderr &&
+	echo "fatal: destination exists in the index, source=sub/file1, destination=folder1/file1" \
+	>expect &&
+	test_cmp expect stderr &&
+
+	git mv --sparse -f sub/file1 folder1 2>stderr &&
+	test_must_be_empty stderr &&
+
+	test_path_is_missing sub/file1 &&
+	test_path_is_missing folder1/file1 &&
+	git ls-files -t >actual &&
+	! grep -x "H sub/file1" actual &&
+	grep -x "S folder1/file1" actual &&
+
+	# compare file content before move and after move
+	echo "sub/file1 overwrite" >expect &&
+	git ls-files -s -- folder1/file1 | awk "{print \$2}" >oid &&
+	git cat-file blob $(cat oid) >actual &&
+	test_cmp expect actual
+'
+
+test_expect_failure 'move dirty path from in-cone to out-of-cone' '
+	test_when_finished "cleanup_sparse_checkout" &&
+	setup_sparse_checkout &&
+	echo "modified" >>sub/d &&
+
+	test_must_fail git mv sub/d folder1 2>stderr &&
+	cat sparse_error_header >expect &&
+	echo "folder1/d" >>expect &&
+	cat sparse_hint >>expect &&
+	test_cmp expect stderr &&
+
+	git mv --sparse sub/d folder1 2>stderr &&
+	cat dirty_error_header >expect &&
+	echo "folder1/d" >>expect &&
+	cat dirty_hint >>expect &&
+	test_cmp expect stderr &&
+
+	test_path_is_missing sub/d &&
+	test_path_is_file folder1/d &&
+	git ls-files -t >actual &&
+	! grep -x "H sub/d" actual &&
+	grep -x "H folder1/d" actual
+'
+
+test_expect_failure 'move dir from in-cone to out-of-cone' '
+	test_when_finished "cleanup_sparse_checkout" &&
+	setup_sparse_checkout &&
+
+	test_must_fail git mv sub/dir folder1 2>stderr &&
+	cat sparse_error_header >expect &&
+	echo "folder1/dir/e" >>expect &&
+	cat sparse_hint >>expect &&
+	test_cmp expect stderr &&
+
+	git mv --sparse sub/dir folder1 2>stderr &&
+	test_must_be_empty stderr &&
+
+	test_path_is_missing sub/dir &&
+	test_path_is_missing folder1 &&
+	git ls-files -t >actual &&
+	! grep -x "H sub/dir/e" actual &&
+	grep -x "S folder1/dir/e" actual
+'
+
+test_expect_failure 'move partially-dirty dir from in-cone to out-of-cone' '
+	test_when_finished "cleanup_sparse_checkout" &&
+	setup_sparse_checkout &&
+	touch sub/dir/e2 sub/dir/e3 &&
+	git add sub/dir/e2 sub/dir/e3 &&
+	echo "modified" >>sub/dir/e2 &&
+	echo "modified" >>sub/dir/e3 &&
+
+	test_must_fail git mv sub/dir folder1 2>stderr &&
+	cat sparse_error_header >expect &&
+	echo "folder1/dir/e" >>expect &&
+	echo "folder1/dir/e2" >>expect &&
+	echo "folder1/dir/e3" >>expect &&
+	cat sparse_hint >>expect &&
+	test_cmp expect stderr &&
+
+	git mv --sparse sub/dir folder1 2>stderr &&
+	cat dirty_error_header >expect &&
+	echo "folder1/dir/e2" >>expect &&
+	echo "folder1/dir/e3" >>expect &&
+	cat dirty_hint >>expect &&
+	test_cmp expect stderr &&
+
+	test_path_is_missing sub/dir &&
+	test_path_is_missing folder1/dir/e &&
+	test_path_is_file folder1/dir/e2 &&
+	test_path_is_file folder1/dir/e3 &&
+	git ls-files -t >actual &&
+	! grep -x "H sub/dir/e" actual &&
+	! grep -x "H sub/dir/e2" actual &&
+	! grep -x "H sub/dir/e3" actual &&
+	grep -x "S folder1/dir/e" actual &&
+	grep -x "H folder1/dir/e2" actual &&
+	grep -x "H folder1/dir/e3" actual
+'
+
 test_done