Skip to content

Commit 7808709

Browse files
derrickstoleegitster
authored andcommitted
ls-files: add --sparse option
Existing callers to 'git ls-files' are expecting file names, not directories. It is best to expand a sparse index to show all of the contained files in this case. However, expert users may want to inspect the contents of the index itself including which directories are sparse. Add a --sparse option to allow users to request this information. During testing, I noticed that options such as --modified did not affect the output when the files in question were outside the sparse-checkout definition. Tests are added to document this preexisting behavior and how it remains unchanged with the sparse index and the --sparse option. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5a4e054 commit 7808709

File tree

3 files changed

+106
-2
lines changed

3 files changed

+106
-2
lines changed

Documentation/git-ls-files.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ Both the <eolinfo> in the index ("i/<eolinfo>")
187187
and in the working tree ("w/<eolinfo>") are shown for regular files,
188188
followed by the ("attr/<eolattr>").
189189

190+
--sparse::
191+
If the index is sparse, show the sparse directories without expanding
192+
to the contained files. Sparse directories will be shown with a
193+
trailing slash, such as "x/" for a sparse directory "x".
194+
190195
\--::
191196
Do not interpret any more arguments as options.
192197

builtin/ls-files.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ static int debug_mode;
3737
static int show_eol;
3838
static int recurse_submodules;
3939
static int skipping_duplicates;
40+
static int show_sparse_dirs;
4041

4142
static const char *prefix;
4243
static int max_prefix_len;
@@ -315,8 +316,10 @@ static void show_files(struct repository *repo, struct dir_struct *dir)
315316

316317
if (!(show_cached || show_stage || show_deleted || show_modified))
317318
return;
318-
/* TODO: audit for interaction with sparse-index. */
319-
ensure_full_index(repo->index);
319+
320+
if (!show_sparse_dirs)
321+
ensure_full_index(repo->index);
322+
320323
for (i = 0; i < repo->index->cache_nr; i++) {
321324
const struct cache_entry *ce = repo->index->cache[i];
322325
struct stat st;
@@ -670,13 +673,18 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
670673
OPT_BOOL(0, "debug", &debug_mode, N_("show debugging data")),
671674
OPT_BOOL(0, "deduplicate", &skipping_duplicates,
672675
N_("suppress duplicate entries")),
676+
OPT_BOOL(0, "sparse", &show_sparse_dirs,
677+
N_("show sparse directories in the presence of a sparse index")),
673678
OPT_END()
674679
};
675680
int ret = 0;
676681

677682
if (argc == 2 && !strcmp(argv[1], "-h"))
678683
usage_with_options(ls_files_usage, builtin_ls_files_options);
679684

685+
prepare_repo_settings(the_repository);
686+
the_repository->settings.command_requires_full_index = 0;
687+
680688
prefix = cmd_prefix;
681689
if (prefix)
682690
prefix_len = strlen(prefix);

t/t1092-sparse-checkout-compatibility.sh

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,12 @@ test_expect_success 'sparse-index is expanded and converted back' '
816816
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \
817817
git -C sparse-index reset -- folder1/a &&
818818
test_region index convert_to_sparse trace2.txt &&
819+
test_region index ensure_full_index trace2.txt &&
820+
821+
# ls-files expands on read, but does not write.
822+
rm trace2.txt &&
823+
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
824+
git -C sparse-index ls-files &&
819825
test_region index ensure_full_index trace2.txt
820826
'
821827

@@ -871,6 +877,7 @@ test_expect_success 'sparse-index is not expanded' '
871877
init_repos &&
872878
873879
ensure_not_expanded status &&
880+
ensure_not_expanded ls-files --sparse &&
874881
ensure_not_expanded commit --allow-empty -m empty &&
875882
echo >>sparse-index/a &&
876883
ensure_not_expanded commit -a -m a &&
@@ -1019,6 +1026,90 @@ test_expect_success 'sparse index is not expanded: fetch/pull' '
10191026
ensure_not_expanded pull full base
10201027
'
10211028

1029+
test_expect_success 'ls-files' '
1030+
init_repos &&
1031+
1032+
# Use a smaller sparse-checkout for reduced output
1033+
test_sparse_match git sparse-checkout set &&
1034+
1035+
# Behavior agrees by default. Sparse index is expanded.
1036+
test_all_match git ls-files &&
1037+
1038+
# With --sparse, the sparse index data changes behavior.
1039+
git -C sparse-index ls-files --sparse >actual &&
1040+
1041+
cat >expect <<-\EOF &&
1042+
a
1043+
deep/
1044+
e
1045+
folder1-
1046+
folder1.x
1047+
folder1/
1048+
folder10
1049+
folder2/
1050+
g
1051+
x/
1052+
z
1053+
EOF
1054+
1055+
test_cmp expect actual &&
1056+
1057+
# With --sparse and no sparse index, nothing changes.
1058+
git -C sparse-checkout ls-files >dense &&
1059+
git -C sparse-checkout ls-files --sparse >sparse &&
1060+
test_cmp dense sparse &&
1061+
1062+
# Set up a strange condition of having a file edit
1063+
# outside of the sparse-checkout cone. This is just
1064+
# to verify that sparse-checkout and sparse-index
1065+
# behave the same in this case.
1066+
write_script edit-content <<-\EOF &&
1067+
mkdir folder1 &&
1068+
echo content >>folder1/a
1069+
EOF
1070+
run_on_sparse ../edit-content &&
1071+
1072+
# ls-files does not currently notice modified files whose
1073+
# cache entries are marked SKIP_WORKTREE. This may change
1074+
# in the future, but here we test that sparse index does
1075+
# not accidentally create a change of behavior.
1076+
test_sparse_match git ls-files --modified &&
1077+
test_must_be_empty sparse-checkout-out &&
1078+
test_must_be_empty sparse-index-out &&
1079+
1080+
git -C sparse-index ls-files --sparse --modified >sparse-index-out &&
1081+
test_must_be_empty sparse-index-out &&
1082+
1083+
# Add folder1 to the sparse-checkout cone and
1084+
# check that ls-files shows the expanded files.
1085+
test_sparse_match git sparse-checkout add folder1 &&
1086+
test_sparse_match git ls-files --modified &&
1087+
1088+
test_all_match git ls-files &&
1089+
git -C sparse-index ls-files --sparse >actual &&
1090+
1091+
cat >expect <<-\EOF &&
1092+
a
1093+
deep/
1094+
e
1095+
folder1-
1096+
folder1.x
1097+
folder1/0/0/0
1098+
folder1/0/1
1099+
folder1/a
1100+
folder10
1101+
folder2/
1102+
g
1103+
x/
1104+
z
1105+
EOF
1106+
1107+
test_cmp expect actual &&
1108+
1109+
# Double-check index expansion is avoided
1110+
ensure_not_expanded ls-files --sparse
1111+
'
1112+
10221113
# NEEDSWORK: a sparse-checkout behaves differently from a full checkout
10231114
# in this scenario, but it shouldn't.
10241115
test_expect_success 'reset mixed and checkout orphan' '

0 commit comments

Comments
 (0)