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 <derrickstolee@github.com>
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
const char *end, *slash;
/*
- * We default to accepting a path if there are no patterns or
- * they are of the wrong type.
+ * We default to accepting a path if the path is empty, there are no
+ * patterns, or the patterns are of the wrong type.
*/
- if (init_sparse_checkout_patterns(istate) ||
+ if (!*path ||
+ init_sparse_checkout_patterns(istate) ||
(require_cone_mode &&
!istate->sparse_checkout_patterns->use_cone_patterns))
return 1;
test_sparse_match git ls-files --stage
'
+test_expect_success 'root directory cannot be sparse' '
+ init_repos &&
+
+ # Remove all in-cone files and directories from the index, collapse index
+ # with `git sparse-checkout reapply`
+ git -C sparse-index rm -r . &&
+ git -C sparse-index sparse-checkout reapply &&
+
+ # Verify sparse directories still present, root directory is not sparse
+ cat >expect <<-EOF &&
+ folder1/
+ folder2/
+ x/
+ EOF
+ git -C sparse-index ls-files --sparse >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'status with options' '
init_repos &&
test_sparse_match ls &&