Skip to content

Commit 695dc7b

Browse files
committed
sparse-index: require commands to declare compatibility
3c31623 (sparse-index: add guard to ensure full index, 2021-01-08) introduced command_requires_full_index as scaffolding: every command starts by expanding the sparse index, and commands opt out one by one by setting the field to 0. Because the default is 1, a command that never touches the field silently gets full expansion -- there is no signal that it was forgotten rather than intentionally left. Change the default to a sentinel (-1) and add an accessor that dies if a command reaches index reading without declaring a value. An environment variable GIT_ALLOW_SPARSE_INDEX_WITHOUT_DECLARATION=1 bypasses the check as a safety net. Both the safety net and the field itself are meant to be removed once no commands require full expansion from the start. Four commands that never declared this field are surfaced and explicitly set to 1 to preserve existing behavior: - git-am - git-mv - git-submodule--helper - grep's submodule path This is a pure refactoring with no behavior change. Signed-off-by: Kristofer Karlsson <krka@spotify.com>
1 parent 600fe74 commit 695dc7b

9 files changed

Lines changed: 39 additions & 13 deletions

File tree

builtin/am.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "lockfile.h"
2424
#include "cache-tree.h"
2525
#include "refs.h"
26+
#include "repo-settings.h"
2627
#include "commit.h"
2728
#include "diff.h"
2829
#include "unpack-trees.h"
@@ -2464,6 +2465,9 @@ int cmd_am(int argc,
24642465
/* Ensure a valid committer ident can be constructed */
24652466
git_committer_info(IDENT_STRICT);
24662467

2468+
prepare_repo_settings(the_repository);
2469+
the_repository->settings.command_requires_full_index = 1;
2470+
24672471
if (repo_read_index_preload(the_repository, NULL, 0) < 0)
24682472
die(_("failed to read the index"));
24692473

builtin/grep.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,10 @@ static int grep_submodule(struct grep_opt *opt,
500500
*
501501
* Note that this list is not exhaustive.
502502
*/
503+
/* not yet verified whether subrepo can use the sparse index */
504+
prepare_repo_settings(subrepo);
505+
subrepo->settings.command_requires_full_index = 1;
506+
503507
repo_read_gitmodules(subrepo, 0);
504508

505509
/*

builtin/mv.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "string-list.h"
2323
#include "parse-options.h"
2424
#include "read-cache-ll.h"
25+
#include "repo-settings.h"
2526

2627
#include "setup.h"
2728
#include "strvec.h"
@@ -247,6 +248,9 @@ int cmd_mv(int argc,
247248
if (--argc < 1)
248249
usage_with_options(builtin_mv_usage, builtin_mv_options);
249250

251+
prepare_repo_settings(the_repository);
252+
the_repository->settings.command_requires_full_index = 1;
253+
250254
repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);
251255
if (repo_read_index(the_repository) < 0)
252256
die(_("index file corrupt"));

builtin/submodule--helper.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "read-cache.h"
1717
#include "setup.h"
1818
#include "sparse-index.h"
19+
#include "repo-settings.h"
1920
#include "submodule.h"
2021
#include "submodule-config.h"
2122
#include "string-list.h"
@@ -3832,5 +3833,9 @@ int cmd_submodule__helper(int argc,
38323833
};
38333834
argc = parse_options(argc, argv, prefix, options, usage, 0);
38343835

3836+
/* not yet verified whether this can use the sparse index */
3837+
prepare_repo_settings(the_repository);
3838+
the_repository->settings.command_requires_full_index = 1;
3839+
38353840
return fn(argc, argv, prefix, repo);
38363841
}

read-cache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,7 +2189,7 @@ static void set_new_index_sparsity(struct index_state *istate)
21892189
* repo settings.
21902190
*/
21912191
prepare_repo_settings(istate->repo);
2192-
if (!istate->repo->settings.command_requires_full_index &&
2192+
if (!repo_settings_get_command_requires_full_index(istate->repo) &&
21932193
is_sparse_index_allowed(istate, 0))
21942194
istate->sparse_index = 1;
21952195
}
@@ -2321,7 +2321,7 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
23212321
* settings and other properties of the index (if necessary).
23222322
*/
23232323
prepare_repo_settings(istate->repo);
2324-
if (istate->repo->settings.command_requires_full_index)
2324+
if (repo_settings_get_command_requires_full_index(istate->repo))
23252325
ensure_full_index(istate);
23262326
else
23272327
ensure_correct_sparsity(istate);

repo-settings.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "git-compat-util.h"
22
#include "config.h"
3+
#include "gettext.h"
34
#include "repo-settings.h"
45
#include "repository.h"
56
#include "midx.h"
@@ -131,14 +132,6 @@ void prepare_repo_settings(struct repository *r)
131132
die("unknown fetch negotiation algorithm '%s'", strval);
132133
}
133134

134-
/*
135-
* This setting guards all index reads to require a full index
136-
* over a sparse index. After suitable guards are placed in the
137-
* codebase around uses of the index, this setting will be
138-
* removed.
139-
*/
140-
r->settings.command_requires_full_index = 1;
141-
142135
if (!repo_config_get_ulong(r, "core.deltabasecachelimit", &ulongval))
143136
r->settings.delta_base_cache_limit = ulongval;
144137

@@ -156,6 +149,20 @@ void prepare_repo_settings(struct repository *r)
156149
r->settings.packed_git_limit = ulongval;
157150
}
158151

152+
int repo_settings_get_command_requires_full_index(struct repository *r)
153+
{
154+
if (r->settings.command_requires_full_index >= 0)
155+
return r->settings.command_requires_full_index;
156+
157+
if (git_env_bool("GIT_ALLOW_SPARSE_INDEX_WITHOUT_DECLARATION", 0)) {
158+
r->settings.command_requires_full_index = 1;
159+
return 1;
160+
}
161+
162+
die(_("command has not declared sparse-index compatibility;\n"
163+
"set GIT_ALLOW_SPARSE_INDEX_WITHOUT_DECLARATION=1 to bypass"));
164+
}
165+
159166
void repo_settings_clear(struct repository *r)
160167
{
161168
struct repo_settings empty = REPO_SETTINGS_INIT;

repo-settings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ struct repo_settings {
7272
char *hooks_path;
7373
};
7474
#define REPO_SETTINGS_INIT { \
75+
.command_requires_full_index = -1, \
7576
.shared_repository = -1, \
7677
.index_version = -1, \
7778
.core_untracked_cache = UNTRACKED_CACHE_KEEP, \
@@ -85,6 +86,7 @@ struct repo_settings {
8586

8687
void prepare_repo_settings(struct repository *r);
8788
void repo_settings_clear(struct repository *r);
89+
int repo_settings_get_command_requires_full_index(struct repository *r);
8890

8991
/* Read the value for "core.logAllRefUpdates". */
9092
enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo);

repository.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ int repo_read_index(struct repository *repo)
465465
res = read_index_from(repo->index, repo->index_file, repo->gitdir);
466466

467467
prepare_repo_settings(repo);
468-
if (repo->settings.command_requires_full_index)
468+
if (repo_settings_get_command_requires_full_index(repo))
469469
ensure_full_index(repo->index);
470470

471471
/*

unpack-trees.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1906,7 +1906,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
19061906
trace2_region_enter("unpack_trees", "unpack_trees", the_repository);
19071907

19081908
prepare_repo_settings(repo);
1909-
if (repo->settings.command_requires_full_index) {
1909+
if (repo_settings_get_command_requires_full_index(repo)) {
19101910
ensure_full_index(o->src_index);
19111911
if (o->dst_index)
19121912
ensure_full_index(o->dst_index);
@@ -1964,7 +1964,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
19641964
o->internal.result.fsmonitor_has_run_once = o->src_index->fsmonitor_has_run_once;
19651965

19661966
if (!o->src_index->initialized &&
1967-
!repo->settings.command_requires_full_index &&
1967+
!repo_settings_get_command_requires_full_index(repo) &&
19681968
is_sparse_index_allowed(&o->internal.result, 0))
19691969
o->internal.result.sparse_index = 1;
19701970

0 commit comments

Comments
 (0)