read-cache: set sparsity when index is new

When the index read in 'do_read_index()' does not exist on-disk, mark the index "sparse" if the executing command does not require a full index and sparse index is otherwise enabled. Some commands (such as 'git stash -u') implicitly create a new index (when the 'GIT_INDEX_FILE' variable points to a non-existent file) and perform some operation on it. However, when this index is created, it isn't created with the same sparsity settings as the repo index. As a result, while these indexes may be sparse during the operation, they are always expanded before being written to disk. We can avoid that expansion by defaulting the index to "sparse", in which case it will only be expanded if the full index is needed. Note that the function 'set_new_index_sparsity()' is created despite having only a single caller because additional callers will be added in a subsequent patch. Signed-off-by: Victoria Dye <vdye@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Victoria Dye committed May 10, 2022 at 23:32 UTC 491df5f679f0381f529b967df25476ab944406ab
2 files changed +18 -2
read-cache.c
+17 -1
@@ -2260,6 +2260,20 @@ static unsigned long load_cache_entries_threaded(struct index_state *istate, con
2260 return consumed;
2261 }
2262
2263 +static void set_new_index_sparsity(struct index_state *istate)
2264 +{
2265 + /*
2266 + * If the index's repo exists, mark it sparse according to
2267 + * repo settings.
2268 + */
2269 + if (istate->repo) {
2270 + prepare_repo_settings(istate->repo);
2271 + if (!istate->repo->settings.command_requires_full_index &&
2272 + is_sparse_index_allowed(istate, 0))
2273 + istate->sparse_index = 1;
2274 + }
2275 +}
2276 +
2277 /* remember to discard_cache() before reading a different cache! */
2278 int do_read_index(struct index_state *istate, const char *path, int must_exist)
2279 {
@@ -2281,8 +2295,10 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
2295 istate->timestamp.nsec = 0;
2296 fd = open(path, O_RDONLY);
2297 if (fd < 0) {
2284 - if (!must_exist && errno == ENOENT)
2298 + if (!must_exist && errno == ENOENT) {
2299 + set_new_index_sparsity(istate);
2300 return 0;
2301 + }
2302 die_errno(_("%s: index file open failed"), path);
2303 }
2304
t/t1092-sparse-checkout-compatibility.sh
+1 -1
@@ -1389,7 +1389,7 @@ test_expect_success 'sparse-index is not expanded: stash' '
1389 ensure_not_expanded stash drop stash@{0} &&
1390
1391 echo >>sparse-index/deep/new &&
1392 - ! ensure_not_expanded stash -u &&
1392 + ensure_not_expanded stash -u &&
1393 (
1394 WITHOUT_UNTRACKED_TXT=1 &&
1395 ! ensure_not_expanded stash pop