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
maint
Junio C Hamano 2025-09-08 14:54:34 -07:00
commit 576e0b6eb3
2 changed files with 23 additions and 3 deletions

View File

@ -414,14 +414,21 @@ static void show_files(struct repository *repo, struct dir_struct *dir)
if (!(show_cached || show_stage || show_deleted || show_modified)) if (!(show_cached || show_stage || show_deleted || show_modified))
return; return;


if (!show_sparse_dirs)
ensure_full_index(repo->index);

for (i = 0; i < repo->index->cache_nr; i++) { for (i = 0; i < repo->index->cache_nr; i++) {
const struct cache_entry *ce = repo->index->cache[i]; const struct cache_entry *ce = repo->index->cache[i];
struct stat st; struct stat st;
int stat_err; 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); construct_fullname(&fullname, repo, ce);


if ((dir->flags & DIR_SHOW_IGNORED) && if ((dir->flags & DIR_SHOW_IGNORED) &&

View File

@ -1506,6 +1506,8 @@ test_expect_success 'sparse-index is not expanded' '
ensure_not_expanded reset --hard && ensure_not_expanded reset --hard &&
ensure_not_expanded restore -s rename-out-to-out -- deep/deeper1 && ensure_not_expanded restore -s rename-out-to-out -- deep/deeper1 &&


ensure_not_expanded ls-files deep/deeper1 &&

echo >>sparse-index/README.md && echo >>sparse-index/README.md &&
ensure_not_expanded add -A && ensure_not_expanded add -A &&
echo >>sparse-index/extra.txt && echo >>sparse-index/extra.txt &&
@ -1607,6 +1609,17 @@ test_expect_success 'describe tested on all' '
test_all_match git describe --dirty 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' ' test_expect_success 'sparse-index is not expanded: describe' '
init_repos && init_repos &&