aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-09-08 14:54:34 -0700
committerJunio C Hamano <gitster@pobox.com>2025-09-08 14:54:35 -0700
commit576e0b6eb34f8989f07ae77db10baf1c75125c47 (patch)
treec2962bfd758f54f9c54ca6c032080d19c7d9ce54
parent4a7ebb9138b47bdc469fd8c8a97a753714fd5d92 (diff)
parent681f26bccc017371ae6ee20db55e3edb52420a25 (diff)
downloadgit-576e0b6eb34f8989f07ae77db10baf1c75125c47.tar.gz
Merge branch 'ds/ls-files-lazy-unsparse'
"git ls-files <pathspec>..." should not necessarily have to expand the index fully if a sparsified directory is excluded by the pathspec; the code is taught to expand the index on demand to avoid this. * ds/ls-files-lazy-unsparse: ls-files: conditionally leave index sparse
-rw-r--r--builtin/ls-files.c13
-rwxr-xr-xt/t1092-sparse-checkout-compatibility.sh13
2 files changed, 23 insertions, 3 deletions
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index c06a6f33e4..b148607f7a 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -414,14 +414,21 @@ static void show_files(struct repository *repo, struct dir_struct *dir)
if (!(show_cached || show_stage || show_deleted || show_modified))
return;
- if (!show_sparse_dirs)
- ensure_full_index(repo->index);
-
for (i = 0; i < repo->index->cache_nr; i++) {
const struct cache_entry *ce = repo->index->cache[i];
struct stat st;
int stat_err;
+ if (S_ISSPARSEDIR(ce->ce_mode) && !show_sparse_dirs) {
+ /*
+ * This is the first time we've hit a sparse dir,
+ * so expansion will leave the first 'i' entries
+ * alone.
+ */
+ ensure_full_index(repo->index);
+ ce = repo->index->cache[i];
+ }
+
construct_fullname(&fullname, repo, ce);
if ((dir->flags & DIR_SHOW_IGNORED) &&
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
index d8101139b4..b0f691c151 100755
--- a/t/t1092-sparse-checkout-compatibility.sh
+++ b/t/t1092-sparse-checkout-compatibility.sh
@@ -1506,6 +1506,8 @@ test_expect_success 'sparse-index is not expanded' '
ensure_not_expanded reset --hard &&
ensure_not_expanded restore -s rename-out-to-out -- deep/deeper1 &&
+ ensure_not_expanded ls-files deep/deeper1 &&
+
echo >>sparse-index/README.md &&
ensure_not_expanded add -A &&
echo >>sparse-index/extra.txt &&
@@ -1607,6 +1609,17 @@ test_expect_success 'describe tested on all' '
test_all_match git describe --dirty
'
+test_expect_success 'ls-files filtering and expansion' '
+ init_repos &&
+
+ # This filtering will hit a sparse directory midway
+ # through the iteration.
+ test_all_match git ls-files deep &&
+
+ # This pathspec will filter the index to only a sparse
+ # directory.
+ test_all_match git ls-files folder1
+'
test_expect_success 'sparse-index is not expanded: describe' '
init_repos &&