diff --git a/dir.c b/dir.c index 1339b1a4b2477d..2a801fcae905ed 100644 --- a/dir.c +++ b/dir.c @@ -1420,7 +1420,7 @@ enum pattern_match_result path_matches_pattern_list( struct path_pattern *pattern; struct strbuf parent_pathname = STRBUF_INIT; int result = NOT_MATCHED; - const char *slash_pos; + size_t slash_pos; /* * The virtual file system data is used to prevent git from traversing @@ -1461,10 +1461,11 @@ enum pattern_match_result path_matches_pattern_list( */ if (parent_pathname.len > 0 && parent_pathname.buf[parent_pathname.len - 1] == '/') { - slash_pos = parent_pathname.buf + parent_pathname.len - 1; + slash_pos = parent_pathname.len - 1; strbuf_add(&parent_pathname, "-", 1); } else { - slash_pos = strrchr(parent_pathname.buf, '/'); + const char *slash_ptr = strrchr(parent_pathname.buf, '/'); + slash_pos = slash_ptr ? slash_ptr - parent_pathname.buf : 0; } if (hashmap_contains_path(&pl->recursive_hashmap, @@ -1473,13 +1474,13 @@ enum pattern_match_result path_matches_pattern_list( goto done; } - if (slash_pos == parent_pathname.buf) { + if (!slash_pos) { /* include every file in root */ result = MATCHED; goto done; } - strbuf_setlen(&parent_pathname, slash_pos - parent_pathname.buf); + strbuf_setlen(&parent_pathname, slash_pos); if (hashmap_contains_path(&pl->parent_hashmap, &parent_pathname)) { result = MATCHED; diff --git a/repo-settings.c b/repo-settings.c index 237dbfe61d6fbf..586034739832f8 100644 --- a/repo-settings.c +++ b/repo-settings.c @@ -96,9 +96,9 @@ void prepare_repo_settings(struct repository *r) r->settings.command_requires_full_index = 1; /* - * Initialize this as off. + * Initialize this as on. */ - r->settings.sparse_index = 0; - if (!repo_config_get_bool(r, "index.sparse", &value) && value) - r->settings.sparse_index = 1; + r->settings.sparse_index = 1; + if (!repo_config_get_bool(r, "index.sparse", &value) && !value) + r->settings.sparse_index = 0; } diff --git a/sparse-index.c b/sparse-index.c index 489306029dc36d..c56543b37a00b8 100644 --- a/sparse-index.c +++ b/sparse-index.c @@ -108,7 +108,7 @@ int set_sparse_index_config(struct repository *repo, int enable) char *config_path = repo_git_path(repo, "config.worktree"); res = git_config_set_in_file_gently(config_path, "index.sparse", - enable ? "true" : NULL); + enable ? "true" : "false"); free(config_path); prepare_repo_settings(repo); @@ -130,7 +130,8 @@ static int index_has_unmerged_entries(struct index_state *istate) int convert_to_sparse(struct index_state *istate) { int test_env; - if (istate->split_index || istate->sparse_index || + + if (istate->split_index || istate->sparse_index || !istate->cache_nr || !core_apply_sparse_checkout || !core_sparse_checkout_cone) return 0; @@ -158,10 +159,16 @@ int convert_to_sparse(struct index_state *istate) return 0; } - if (!istate->sparse_checkout_patterns->use_cone_patterns) { - warning(_("attempting to use sparse-index without cone mode")); - return -1; - } + /* + * 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. @@ -170,10 +177,17 @@ int convert_to_sparse(struct index_state *istate) if (index_has_unmerged_entries(istate)) return 0; - if (cache_tree_update(istate, 0)) { - warning(_("unable to update cache-tree, staying full")); - return -1; - } + /* Clear and recompute the cache-tree */ + cache_tree_free(&istate->cache_tree); + /* + * 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); diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index 38fc8340f5c9b7..92613f381c7d23 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -215,7 +215,7 @@ test_expect_success 'sparse-index enabled and disabled' ' test-tool -C repo read-cache --table >cache && ! grep " tree " cache && git -C repo config --list >config && - ! grep index.sparse config + test_cmp_config -C repo false index.sparse ' test_expect_success 'cone mode: init and set' ' diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index 0fb2a42749b0e6..b7dc5569b6e43f 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -118,6 +118,7 @@ init_repos () { git -C sparse-index reset --hard && # initialize sparse-checkout definitions + git -C sparse-checkout config index.sparse false && git -C sparse-checkout sparse-checkout init --cone && git -C sparse-checkout sparse-checkout set deep && git -C sparse-index sparse-checkout init --cone --sparse-index && diff --git a/t/t7817-grep-sparse-checkout.sh b/t/t7817-grep-sparse-checkout.sh index 590b99bbb6f7bb..547bae48619c12 100755 --- a/t/t7817-grep-sparse-checkout.sh +++ b/t/t7817-grep-sparse-checkout.sh @@ -49,7 +49,7 @@ test_expect_success 'setup' ' echo "text" >B/b && git add A B && git commit -m sub && - git sparse-checkout init --cone && + git sparse-checkout init --cone --no-sparse-index && git sparse-checkout set B ) &&