]> git.ipfire.org Git - thirdparty/git.git/commitdiff
sparse-index: complete partial expansion
authorDerrick Stolee <dstolee@microsoft.com>
Mon, 23 May 2022 13:48:44 +0000 (13:48 +0000)
committerJunio C Hamano <gitster@pobox.com>
Mon, 23 May 2022 18:08:21 +0000 (11:08 -0700)
To complete the implementation of expand_to_pattern_list(), we need to
detect when a sparse directory entry should remain sparse. This avoids a
full expansion, so we now need to use the PARTIALLY_SPARSE mode to
indicate this state.

There still are no callers to this method, but we will add one in the
next change.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
sparse-index.c

index a881f851810f60cfd7a1a039adfade8f9cf7a332..2c0a18380f10461196e492d919b350a618fb296b 100644 (file)
@@ -308,8 +308,24 @@ void expand_index(struct index_state *istate, struct pattern_list *pl)
         * continue. A NULL pattern set indicates a full expansion to a
         * full index.
         */
-       if (pl && !pl->use_cone_patterns)
+       if (pl && !pl->use_cone_patterns) {
                pl = NULL;
+       } else {
+               /*
+                * We might contract file entries into sparse-directory
+                * entries, and for that we will need the cache tree to
+                * be recomputed.
+                */
+               cache_tree_free(&istate->cache_tree);
+
+               /*
+                * If there is a problem creating the cache tree, then we
+                * need to expand to a full index since we cannot satisfy
+                * the current request as a sparse index.
+                */
+               if (cache_tree_update(istate, 0))
+                       pl = NULL;
+       }
 
        if (!istate->repo)
                istate->repo = the_repository;
@@ -327,8 +343,14 @@ void expand_index(struct index_state *istate, struct pattern_list *pl)
        full = xcalloc(1, sizeof(struct index_state));
        memcpy(full, istate, sizeof(struct index_state));
 
+       /*
+        * This slightly-misnamed 'full' index might still be sparse if we
+        * are only modifying the list of sparse directories. This hinges
+        * on whether we have a non-NULL pattern list.
+        */
+       full->sparse_index = pl ? INDEX_PARTIALLY_SPARSE : INDEX_EXPANDED;
+
        /* then change the necessary things */
-       full->sparse_index = 0;
        full->cache_alloc = (3 * istate->cache_alloc) / 2;
        full->cache_nr = 0;
        ALLOC_ARRAY(full->cache, full->cache_alloc);
@@ -340,11 +362,22 @@ void expand_index(struct index_state *istate, struct pattern_list *pl)
                struct cache_entry *ce = istate->cache[i];
                struct tree *tree;
                struct pathspec ps;
+               int dtype;
 
                if (!S_ISSPARSEDIR(ce->ce_mode)) {
                        set_index_entry(full, full->cache_nr++, ce);
                        continue;
                }
+
+               /* We now have a sparse directory entry. Should we expand? */
+               if (pl &&
+                   path_matches_pattern_list(ce->name, ce->ce_namelen,
+                                             NULL, &dtype,
+                                             pl, istate) == NOT_MATCHED) {
+                       set_index_entry(full, full->cache_nr++, ce);
+                       continue;
+               }
+
                if (!(ce->ce_flags & CE_SKIP_WORKTREE))
                        warning(_("index entry is a directory, but not sparse (%08x)"),
                                ce->ce_flags);
@@ -370,7 +403,7 @@ void expand_index(struct index_state *istate, struct pattern_list *pl)
        /* Copy back into original index. */
        memcpy(&istate->name_hash, &full->name_hash, sizeof(full->name_hash));
        memcpy(&istate->dir_hash, &full->dir_hash, sizeof(full->dir_hash));
-       istate->sparse_index = 0;
+       istate->sparse_index = pl ? INDEX_PARTIALLY_SPARSE : INDEX_EXPANDED;
        free(istate->cache);
        istate->cache = full->cache;
        istate->cache_nr = full->cache_nr;