@ -1,4 +1,5 @@
@@ -1,4 +1,5 @@
#include "builtin.h"
#include "cache.h"
#include "config.h"
#include "dir.h"
#include "parse-options.h"
@ -401,6 +402,7 @@ static int update_modes(int *cone_mode, int *sparse_index)
@@ -401,6 +402,7 @@ static int update_modes(int *cone_mode, int *sparse_index)
core_sparse_checkout_cone = 1;
} else {
mode = MODE_ALL_PATTERNS;
core_sparse_checkout_cone = 0;
}
if (record_mode && set_config(mode))
return 1;
@ -681,18 +683,76 @@ static int modify_pattern_list(int argc, const char **argv, int use_stdin,
@@ -681,18 +683,76 @@ static int modify_pattern_list(int argc, const char **argv, int use_stdin,
return result;
}
static void sanitize_paths(int argc, const char **argv,
const char *prefix, int skip_checks)
{
int i;
if (!argc)
return;
if (prefix && *prefix && core_sparse_checkout_cone) {
/*
* The args are not pathspecs, so unfortunately we
* cannot imitate how cmd_add() uses parse_pathspec().
*/
int prefix_len = strlen(prefix);
for (i = 0; i < argc; i++)
argv[i] = prefix_path(prefix, prefix_len, argv[i]);
}
if (skip_checks)
return;
if (prefix && *prefix && !core_sparse_checkout_cone)
die(_("please run from the toplevel directory in non-cone mode"));
if (core_sparse_checkout_cone) {
for (i = 0; i < argc; i++) {
if (argv[i][0] == '/')
die(_("specify directories rather than patterns (no leading slash)"));
if (argv[i][0] == '!')
die(_("specify directories rather than patterns. If your directory starts with a '!', pass --skip-checks"));
if (strpbrk(argv[i], "*?[]"))
die(_("specify directories rather than patterns. If your directory really has any of '*?[]\\' in it, pass --skip-checks"));
}
}
for (i = 0; i < argc; i++) {
struct cache_entry *ce;
struct index_state *index = the_repository->index;
int pos = index_name_pos(index, argv[i], strlen(argv[i]));
if (pos < 0)
continue;
ce = index->cache[pos];
if (S_ISSPARSEDIR(ce->ce_mode))
continue;
if (core_sparse_checkout_cone)
die(_("'%s' is not a directory; to treat it as a directory anyway, rerun with --skip-checks"), argv[i]);
else
warning(_("pass a leading slash before paths such as '%s' if you want a single file (see NON-CONE PROBLEMS in the git-sparse-checkout manual)."), argv[i]);
}
}
static char const * const builtin_sparse_checkout_add_usage[] = {
N_("git sparse-checkout add (--stdin | <patterns>)"),
N_("git sparse-checkout add [--skip-checks] (--stdin | <patterns>)"),
NULL
};
static struct sparse_checkout_add_opts {
int skip_checks;
int use_stdin;
} add_opts;
static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
{
static struct option builtin_sparse_checkout_add_options[] = {
OPT_BOOL_F(0, "skip-checks", &add_opts.skip_checks,
N_("skip some sanity checks on the given paths that might give false positives"),
PARSE_OPT_NONEG),
OPT_BOOL(0, "stdin", &add_opts.use_stdin,
N_("read patterns from standard in")),
OPT_END(),
@ -708,17 +768,20 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
@@ -708,17 +768,20 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
builtin_sparse_checkout_add_usage,
PARSE_OPT_KEEP_UNKNOWN);
sanitize_paths(argc, argv, prefix, add_opts.skip_checks);
return modify_pattern_list(argc, argv, add_opts.use_stdin, ADD);
}
static char const * const builtin_sparse_checkout_set_usage[] = {
N_("git sparse-checkout set [--[no-]cone] [--[no-]sparse-index] (--stdin | <patterns>)"),
N_("git sparse-checkout set [--[no-]cone] [--[no-]sparse-index] [--skip-checks] (--stdin | <patterns>)"),
NULL
};
static struct sparse_checkout_set_opts {
int cone_mode;
int sparse_index;
int skip_checks;
int use_stdin;
} set_opts;
@ -732,6 +795,9 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
@@ -732,6 +795,9 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
N_("initialize the sparse-checkout in cone mode")),
OPT_BOOL(0, "sparse-index", &set_opts.sparse_index,
N_("toggle the use of a sparse index")),
OPT_BOOL_F(0, "skip-checks", &set_opts.skip_checks,
N_("skip some sanity checks on the given paths that might give false positives"),
PARSE_OPT_NONEG),
OPT_BOOL_F(0, "stdin", &set_opts.use_stdin,
N_("read patterns from standard in"),
PARSE_OPT_NONEG),
@ -759,6 +825,8 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
@@ -759,6 +825,8 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
if (!core_sparse_checkout_cone && argc == 0) {
argv = default_patterns;
argc = default_patterns_nr;
} else {
sanitize_paths(argc, argv, prefix, set_opts.skip_checks);
}
return modify_pattern_list(argc, argv, set_opts.use_stdin, REPLACE);
@ -787,15 +855,15 @@ static int sparse_checkout_reapply(int argc, const char **argv)
@@ -787,15 +855,15 @@ static int sparse_checkout_reapply(int argc, const char **argv)
if (!core_apply_sparse_checkout)
die(_("must be in a sparse-checkout to reapply sparsity patterns"));
reapply_opts.cone_mode = -1;
reapply_opts.sparse_index = -1;
argc = parse_options(argc, argv, NULL,
builtin_sparse_checkout_reapply_options,
builtin_sparse_checkout_reapply_usage, 0);
repo_read_index(the_repository);
reapply_opts.cone_mode = -1;
reapply_opts.sparse_index = -1;
if (update_modes(&reapply_opts.cone_mode, &reapply_opts.sparse_index))
return 1;