]> git.ipfire.org Git - thirdparty/git.git/blobdiff - sparse-index.c
Merge branch 'ew/midx-doc-update'
[thirdparty/git.git] / sparse-index.c
index 56eb65dc349a7aede46d17dae9c17ce86ce96f05..7b7ff79e0443a89d37409620a0fd6b04ef9cdc10 100644 (file)
@@ -33,19 +33,14 @@ static int convert_to_sparse_rec(struct index_state *istate,
 {
        int i, can_convert = 1;
        int start_converted = num_converted;
-       enum pattern_match_result match;
-       int dtype = DT_UNKNOWN;
        struct strbuf child_path = STRBUF_INIT;
-       struct pattern_list *pl = istate->sparse_checkout_patterns;
 
        /*
         * Is the current path outside of the sparse cone?
         * Then check if the region can be replaced by a sparse
         * directory entry (everything is sparse and merged).
         */
-       match = path_matches_pattern_list(ct_path, ct_pathlen,
-                                         NULL, &dtype, pl, istate);
-       if (match != NOT_MATCHED)
+       if (path_in_sparse_checkout(ct_path, istate))
                can_convert = 0;
 
        for (i = start; can_convert && i < end; i++) {
@@ -127,41 +122,51 @@ static int index_has_unmerged_entries(struct index_state *istate)
        return 0;
 }
 
-int convert_to_sparse(struct index_state *istate)
+int convert_to_sparse(struct index_state *istate, int flags)
 {
        int test_env;
-       if (istate->split_index || istate->sparse_index ||
+       if (istate->sparse_index || !istate->cache_nr ||
            !core_apply_sparse_checkout || !core_sparse_checkout_cone)
                return 0;
 
        if (!istate->repo)
                istate->repo = the_repository;
 
-       /*
-        * The GIT_TEST_SPARSE_INDEX environment variable triggers the
-        * index.sparse config variable to be on.
-        */
-       test_env = git_env_bool("GIT_TEST_SPARSE_INDEX", -1);
-       if (test_env >= 0)
-               set_sparse_index_config(istate->repo, test_env);
-
-       /*
-        * Only convert to sparse if index.sparse is set.
-        */
-       prepare_repo_settings(istate->repo);
-       if (!istate->repo->settings.sparse_index)
-               return 0;
+       if (!(flags & SPARSE_INDEX_MEMORY_ONLY)) {
+               /*
+                * The sparse index is not (yet) integrated with a split index.
+                */
+               if (istate->split_index)
+                       return 0;
+               /*
+                * The GIT_TEST_SPARSE_INDEX environment variable triggers the
+                * index.sparse config variable to be on.
+                */
+               test_env = git_env_bool("GIT_TEST_SPARSE_INDEX", -1);
+               if (test_env >= 0)
+                       set_sparse_index_config(istate->repo, test_env);
 
-       if (!istate->sparse_checkout_patterns) {
-               istate->sparse_checkout_patterns = xcalloc(1, sizeof(struct pattern_list));
-               if (get_sparse_checkout_patterns(istate->sparse_checkout_patterns) < 0)
+               /*
+                * Only convert to sparse if index.sparse is set.
+                */
+               prepare_repo_settings(istate->repo);
+               if (!istate->repo->settings.sparse_index)
                        return 0;
        }
 
-       if (!istate->sparse_checkout_patterns->use_cone_patterns) {
-               warning(_("attempting to use sparse-index without cone mode"));
-               return -1;
-       }
+       if (init_sparse_checkout_patterns(istate))
+               return 0;
+
+       /*
+        * We need cone-mode patterns to use sparse-index. If a user edits
+        * their sparse-checkout file manually, then we can detect during
+        * parsing that they are not actually using cone-mode patterns and
+        * hence we need to abort this conversion _without error_. Warnings
+        * already exist in the pattern parsing to inform the user of their
+        * bad patterns.
+        */
+       if (!istate->sparse_checkout_patterns->use_cone_patterns)
+               return 0;
 
        /*
         * NEEDSWORK: If we have unmerged entries, then stay full.
@@ -172,10 +177,15 @@ int convert_to_sparse(struct index_state *istate)
 
        /* Clear and recompute the cache-tree */
        cache_tree_free(&istate->cache_tree);
-       if (cache_tree_update(istate, 0)) {
-               warning(_("unable to update cache-tree, staying full"));
-               return -1;
-       }
+       /*
+        * Silently return if there is a problem with the cache tree update,
+        * which might just be due to a conflict state in some entry.
+        *
+        * This might create new tree objects, so be sure to use
+        * WRITE_TREE_MISSING_OK.
+        */
+       if (cache_tree_update(istate, WRITE_TREE_MISSING_OK))
+               return 0;
 
        remove_fsmonitor(istate);