Skip to content

Commit 287fd17

Browse files
vdyegitster
authored andcommitted
sparse-index: prevent repo root from becoming sparse
Prevent the repository root from being collapsed into a sparse directory by treating an empty path as "inside the sparse-checkout". When collapsing a sparse index (e.g. in 'git sparse-checkout reapply'), the root directory typically could not become a sparse directory due to the presence of in-cone root-level files and directories. However, if no such in-cone files or directories were present, there was no explicit check signaling that the "repository root path" (an empty string, in the case of 'convert_to_sparse(...)') was in-cone, and a sparse directory index entry would be created from the repository root directory. The documentation in Documentation/git-sparse-checkout.txt explicitly states that the files in the root directory are expected to be in-cone for a cone-mode sparse-checkout. Collapsing the root into a sparse directory entry violates that assumption, as sparse directory entries are expected to be outside the sparse cone and have SKIP_WORKTREE enabled. This invalid state in turn causes issues with commands that interact with the index, e.g. 'git status'. Treating an empty (root) path as in-cone prevents the creation of a root sparse directory in 'convert_to_sparse(...)'. Because the repository root is otherwise never compared with sparse patterns (in both cone-mode and non-cone sparse-checkouts), the new check does not cause additional changes to how sparse patterns are applied. Helped-by: Derrick Stolee <[email protected]> Signed-off-by: Victoria Dye <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent dab1b79 commit 287fd17

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

dir.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,10 +1463,11 @@ static int path_in_sparse_checkout_1(const char *path,
14631463
const char *end, *slash;
14641464

14651465
/*
1466-
* We default to accepting a path if there are no patterns or
1467-
* they are of the wrong type.
1466+
* We default to accepting a path if the path is empty, there are no
1467+
* patterns, or the patterns are of the wrong type.
14681468
*/
1469-
if (init_sparse_checkout_patterns(istate) ||
1469+
if (!*path ||
1470+
init_sparse_checkout_patterns(istate) ||
14701471
(require_cone_mode &&
14711472
!istate->sparse_checkout_patterns->use_cone_patterns))
14721473
return 1;

t/t1092-sparse-checkout-compatibility.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,24 @@ test_expect_success 'expanded in-memory index matches full index' '
244244
test_sparse_match git ls-files --stage
245245
'
246246

247+
test_expect_success 'root directory cannot be sparse' '
248+
init_repos &&
249+
250+
# Remove all in-cone files and directories from the index, collapse index
251+
# with `git sparse-checkout reapply`
252+
git -C sparse-index rm -r . &&
253+
git -C sparse-index sparse-checkout reapply &&
254+
255+
# Verify sparse directories still present, root directory is not sparse
256+
cat >expect <<-EOF &&
257+
folder1/
258+
folder2/
259+
x/
260+
EOF
261+
git -C sparse-index ls-files --sparse >actual &&
262+
test_cmp expect actual
263+
'
264+
247265
test_expect_success 'status with options' '
248266
init_repos &&
249267
test_sparse_match ls &&

0 commit comments

Comments
 (0)