Subject: Re: [PATCH v2] add, rm, mv: fix bug that prevents the update of non-sparse dirs

From: Sean Christopherson <[email-masked]>
Date: Wed, 27 Oct 2021 17:36:15 +0000

On Mon, Oct 25, 2021, Matheus Tavares wrote:
> - Changed the tests to use trailing slash to make sure they cover the corner
>   case described above.

...

> diff --git a/t/t3705-add-sparse-checkout.sh b/t/t3705-add-sparse-checkout.sh
> index 5b904988d4..54f3db4304 100755
> --- a/t/t3705-add-sparse-checkout.sh
> +++ b/t/t3705-add-sparse-checkout.sh
> @@ -214,4 +214,22 @@ test_expect_success 'add allows sparse entries with --sparse' '
>  	test_must_be_empty stderr
>  '
>  
> +test_expect_success 'can add files from non-sparse dir' '
> +	git sparse-checkout set w !/x y/ &&

Aha!  I re-discovered out the original problematic pattern that led me to omitting
the trailing slash.

Sparse checkout doesn't play nice with "/", e.g. "git sparse-checkout set /"
results in an empty working directory.  Using "/*/" omits top-level files, which
is expected, thus the only pattern that works for "include everything relative to
the top-level directory" is "/*".  And to workaround the bug being fixed here, it
requires adding both "/*" and "/*/" to sparse-checkout.

The docs clearly state that "/*" is the full pattern set, but on the other hand
I don't see anything that states that "/" isn't supported.  Part of the confusion
is that the asterisk is not needed for sub-directories, and a trailing slash for
sub-directories even results in different matching behavior per gitignore docs.
The omission of a trailing slash is also reinforced by the git-sparse-checkout
docs' examples.

If "/" can't be handled for some reason, it would helpful to explictly call that
out in the docs, e.g. git-sparse-checkout and/or the gitignore pattern docs.

Thanks!

> +	mkdir -p w x/y &&
> +	touch w/f x/y/f &&
> +	git add w/f x/y/f 2>stderr &&
> +	test_must_be_empty stderr
> +'
> +
> +test_expect_success 'refuse to add non-skip-worktree file from sparse dir' '
> +	git sparse-checkout set !/x y/ !x/y/z &&
> +	mkdir -p x/y/z &&
> +	touch x/y/z/f &&
> +	test_must_fail git add x/y/z/f 2>stderr &&
> +	echo x/y/z/f | cat sparse_error_header - sparse_hint >expect &&
> +	test_cmp expect stderr
> +