Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions builtin/am.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "lockfile.h"
#include "cache-tree.h"
#include "refs.h"
#include "repo-settings.h"
#include "commit.h"
#include "diff.h"
#include "unpack-trees.h"
Expand Down Expand Up @@ -2464,6 +2465,9 @@ int cmd_am(int argc,
/* Ensure a valid committer ident can be constructed */
git_committer_info(IDENT_STRICT);

prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 1;

if (repo_read_index_preload(the_repository, NULL, 0) < 0)
die(_("failed to read the index"));

Expand Down
4 changes: 4 additions & 0 deletions builtin/grep.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,10 @@ static int grep_submodule(struct grep_opt *opt,
*
* Note that this list is not exhaustive.
*/
/* not yet verified whether subrepo can use the sparse index */
prepare_repo_settings(subrepo);
subrepo->settings.command_requires_full_index = 1;

repo_read_gitmodules(subrepo, 0);

/*
Expand Down
18 changes: 17 additions & 1 deletion builtin/mv.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
#include "string-list.h"
#include "parse-options.h"
#include "read-cache-ll.h"
#include "repo-settings.h"

#include "setup.h"
#include "strvec.h"
#include "submodule.h"
#include "entry.h"
#include "sparse-index.h"

static const char * const builtin_mv_usage[] = {
N_("git mv [-v] [-f] [-n] [-k] <source> <destination>"),
Expand Down Expand Up @@ -152,7 +154,11 @@ static int empty_dir_has_sparse_contents(const char *name)
int pos = index_name_pos(the_repository->index, with_slash, length);
const struct cache_entry *ce;

if (pos < 0) {
if (pos >= 0) {
ce = the_repository->index->cache[pos];
if (S_ISSPARSEDIR(ce->ce_mode))
ret = 1;
} else {
pos = -pos - 1;
if (pos >= the_repository->index->cache_nr)
goto free_return;
Expand Down Expand Up @@ -247,10 +253,16 @@ int cmd_mv(int argc,
if (--argc < 1)
usage_with_options(builtin_mv_usage, builtin_mv_options);

prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;

repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);
if (repo_read_index(the_repository) < 0)
die(_("index file corrupt"));

if (ignore_sparse)
ensure_full_index(the_repository->index);

internal_prefix_pathspec(&sources, prefix, argv, argc, 0);
CALLOC_ARRAY(modes, argc);

Expand Down Expand Up @@ -313,6 +325,10 @@ int cmd_mv(int argc,
if (!path_in_sparse_checkout(src_w_slash, the_repository->index) &&
empty_dir_has_sparse_contents(src)) {
free(src_w_slash);
if (!ignore_sparse) {
string_list_append(&only_match_skip_worktree, src);
goto act_on_entry;
}
modes[i] |= SKIP_WORKTREE_DIR;
goto dir_check;
}
Expand Down
5 changes: 5 additions & 0 deletions builtin/submodule--helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "read-cache.h"
#include "setup.h"
#include "sparse-index.h"
#include "repo-settings.h"
#include "submodule.h"
#include "submodule-config.h"
#include "string-list.h"
Expand Down Expand Up @@ -3832,5 +3833,9 @@ int cmd_submodule__helper(int argc,
};
argc = parse_options(argc, argv, prefix, options, usage, 0);

/* not yet verified whether this can use the sparse index */
prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 1;

return fn(argc, argv, prefix, repo);
}
4 changes: 2 additions & 2 deletions read-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -2189,7 +2189,7 @@ static void set_new_index_sparsity(struct index_state *istate)
* repo settings.
*/
prepare_repo_settings(istate->repo);
if (!istate->repo->settings.command_requires_full_index &&
if (!repo_settings_get_command_requires_full_index(istate->repo) &&
is_sparse_index_allowed(istate, 0))
istate->sparse_index = 1;
}
Expand Down Expand Up @@ -2321,7 +2321,7 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
* settings and other properties of the index (if necessary).
*/
prepare_repo_settings(istate->repo);
if (istate->repo->settings.command_requires_full_index)
if (repo_settings_get_command_requires_full_index(istate->repo))
ensure_full_index(istate);
else
ensure_correct_sparsity(istate);
Expand Down
23 changes: 15 additions & 8 deletions repo-settings.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "git-compat-util.h"
#include "config.h"
#include "gettext.h"
#include "repo-settings.h"
#include "repository.h"
#include "midx.h"
Expand Down Expand Up @@ -131,14 +132,6 @@ void prepare_repo_settings(struct repository *r)
die("unknown fetch negotiation algorithm '%s'", strval);
}

/*
* This setting guards all index reads to require a full index
* over a sparse index. After suitable guards are placed in the
* codebase around uses of the index, this setting will be
* removed.
*/
r->settings.command_requires_full_index = 1;

if (!repo_config_get_ulong(r, "core.deltabasecachelimit", &ulongval))
r->settings.delta_base_cache_limit = ulongval;

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

int repo_settings_get_command_requires_full_index(struct repository *r)
{
if (r->settings.command_requires_full_index >= 0)
return r->settings.command_requires_full_index;

if (git_env_bool("GIT_ALLOW_SPARSE_INDEX_WITHOUT_DECLARATION", 0)) {
r->settings.command_requires_full_index = 1;
return 1;
}

die(_("command has not declared sparse-index compatibility;\n"
"set GIT_ALLOW_SPARSE_INDEX_WITHOUT_DECLARATION=1 to bypass"));
}

void repo_settings_clear(struct repository *r)
{
struct repo_settings empty = REPO_SETTINGS_INIT;
Expand Down
2 changes: 2 additions & 0 deletions repo-settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ struct repo_settings {
char *hooks_path;
};
#define REPO_SETTINGS_INIT { \
.command_requires_full_index = -1, \
.shared_repository = -1, \
.index_version = -1, \
.core_untracked_cache = UNTRACKED_CACHE_KEEP, \
Expand All @@ -85,6 +86,7 @@ struct repo_settings {

void prepare_repo_settings(struct repository *r);
void repo_settings_clear(struct repository *r);
int repo_settings_get_command_requires_full_index(struct repository *r);

/* Read the value for "core.logAllRefUpdates". */
enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo);
Expand Down
2 changes: 1 addition & 1 deletion repository.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ int repo_read_index(struct repository *repo)
res = read_index_from(repo->index, repo->index_file, repo->gitdir);

prepare_repo_settings(repo);
if (repo->settings.command_requires_full_index)
if (repo_settings_get_command_requires_full_index(repo))
ensure_full_index(repo->index);

/*
Expand Down
18 changes: 18 additions & 0 deletions t/t1092-sparse-checkout-compatibility.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1558,6 +1558,24 @@ test_expect_success 'sparse-index is not expanded' '
)
'

test_expect_success 'sparse-index is not expanded: git mv' '
init_repos &&

ensure_not_expanded mv deep/a deep/renamed-a &&
ensure_not_expanded mv deep/deeper2 deep/moved-deeper2 &&

ensure_not_expanded reset --hard &&

# mv of a sparse directory without --sparse should fail with
# a useful hint, without expanding the index.
run_sparse_index_trace2 ! mv folder1 deep &&
test_region ! index ensure_full_index trace2.txt &&
grep "Use the --sparse option" sparse-index-error &&

ensure_not_expanded reset --hard &&
ensure_expanded mv --sparse folder1 deep
'

test_expect_success 'sparse-index is not expanded: merge conflict in cone' '
init_repos &&

Expand Down
2 changes: 1 addition & 1 deletion t/t7002-mv-sparse-checkout.sh
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ test_expect_success 'refuse to move out-of-cone directory without --sparse' '

test_must_fail git mv folder1 sub 2>stderr &&
cat sparse_error_header >expect &&
echo folder1/file1 >>expect &&
echo folder1 >>expect &&
cat sparse_hint >>expect &&
test_cmp expect stderr
'
Expand Down
4 changes: 2 additions & 2 deletions unpack-trees.c
Original file line number Diff line number Diff line change
Expand Up @@ -1906,7 +1906,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
trace2_region_enter("unpack_trees", "unpack_trees", the_repository);

prepare_repo_settings(repo);
if (repo->settings.command_requires_full_index) {
if (repo_settings_get_command_requires_full_index(repo)) {
ensure_full_index(o->src_index);
if (o->dst_index)
ensure_full_index(o->dst_index);
Expand Down Expand Up @@ -1964,7 +1964,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
o->internal.result.fsmonitor_has_run_once = o->src_index->fsmonitor_has_run_once;

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

Expand Down
Loading