Merge branch 'en/sparse-checkout-set'
The "init" and "set" subcommands in "git sparse-checkout" have been
unified for a better user experience and performance.
* en/sparse-checkout-set:
sparse-checkout: remove stray trailing space
clone: avoid using deprecated `sparse-checkout init`
Documentation: clarify/correct a few sparsity related statements
git-sparse-checkout.txt: update to document init/set/reapply changes
sparse-checkout: enable reapply to take --[no-]{cone,sparse-index}
sparse-checkout: enable `set` to initialize sparse-checkout mode
sparse-checkout: split out code for tweaking settings config
sparse-checkout: disallow --no-stdin as an argument to set
sparse-checkout: add sanity-checks on initial sparsity state
sparse-checkout: break apart functions for sparse_checkout_(set|add)
sparse-checkout: pass use_stdin as a parameter instead of as a global
maint
commit
2dc94da374
|
|
@ -167,10 +167,10 @@ objects from the source repository into a pack in the cloned repository.
|
||||||
configuration variables are created.
|
configuration variables are created.
|
||||||
|
|
||||||
--sparse::
|
--sparse::
|
||||||
Initialize the sparse-checkout file so the working
|
Employ a sparse-checkout, with only files in the toplevel
|
||||||
directory starts with only the files in the root
|
directory initially being present. The
|
||||||
of the repository. The sparse-checkout file can be
|
linkgit:git-sparse-checkout[1] command can be used to grow the
|
||||||
modified to grow the working directory as needed.
|
working directory as needed.
|
||||||
|
|
||||||
--filter=<filter-spec>::
|
--filter=<filter-spec>::
|
||||||
Use the partial clone feature and request that the server sends
|
Use the partial clone feature and request that the server sends
|
||||||
|
|
|
||||||
|
|
@ -30,28 +30,36 @@ COMMANDS
|
||||||
'list'::
|
'list'::
|
||||||
Describe the patterns in the sparse-checkout file.
|
Describe the patterns in the sparse-checkout file.
|
||||||
|
|
||||||
'init'::
|
'set'::
|
||||||
Enable the `core.sparseCheckout` setting. If the
|
Enable the necessary config settings
|
||||||
sparse-checkout file does not exist, then populate it with
|
(extensions.worktreeConfig, core.sparseCheckout,
|
||||||
patterns that match every file in the root directory and
|
core.sparseCheckoutCone) if they are not already enabled, and
|
||||||
no other directories, then will remove all directories tracked
|
write a set of patterns to the sparse-checkout file from the
|
||||||
by Git. Add patterns to the sparse-checkout file to
|
list of arguments following the 'set' subcommand. Update the
|
||||||
repopulate the working directory.
|
working directory to match the new patterns.
|
||||||
+
|
+
|
||||||
To avoid interfering with other worktrees, it first enables the
|
When the `--stdin` option is provided, the patterns are read from
|
||||||
`extensions.worktreeConfig` setting and makes sure to set the
|
standard in as a newline-delimited list instead of from the arguments.
|
||||||
`core.sparseCheckout` setting in the worktree-specific config file.
|
|
||||||
+
|
+
|
||||||
When `--cone` is provided, the `core.sparseCheckoutCone` setting is
|
When `--cone` is passed or `core.sparseCheckoutCone` is enabled, the
|
||||||
also set, allowing for better performance with a limited set of
|
input list is considered a list of directories instead of
|
||||||
patterns (see 'CONE PATTERN SET' below).
|
sparse-checkout patterns. This allows for better performance with a
|
||||||
|
limited set of patterns (see 'CONE PATTERN SET' below). Note that the
|
||||||
|
set command will write patterns to the sparse-checkout file to include
|
||||||
|
all files contained in those directories (recursively) as well as
|
||||||
|
files that are siblings of ancestor directories. The input format
|
||||||
|
matches the output of `git ls-tree --name-only`. This includes
|
||||||
|
interpreting pathnames that begin with a double quote (") as C-style
|
||||||
|
quoted strings. This may become the default in the future; --no-cone
|
||||||
|
can be passed to request non-cone mode.
|
||||||
+
|
+
|
||||||
Use the `--[no-]sparse-index` option to toggle the use of the sparse
|
Use the `--[no-]sparse-index` option to use a sparse index (the
|
||||||
index format. This reduces the size of the index to be more closely
|
default is to not use it). A sparse index reduces the size of the
|
||||||
aligned with your sparse-checkout definition. This can have significant
|
index to be more closely aligned with your sparse-checkout
|
||||||
performance advantages for commands such as `git status` or `git add`.
|
definition. This can have significant performance advantages for
|
||||||
This feature is still experimental. Some commands might be slower with
|
commands such as `git status` or `git add`. This feature is still
|
||||||
a sparse index until they are properly integrated with the feature.
|
experimental. Some commands might be slower with a sparse index until
|
||||||
|
they are properly integrated with the feature.
|
||||||
+
|
+
|
||||||
**WARNING:** Using a sparse index requires modifying the index in a way
|
**WARNING:** Using a sparse index requires modifying the index in a way
|
||||||
that is not completely understood by external tools. If you have trouble
|
that is not completely understood by external tools. If you have trouble
|
||||||
|
|
@ -60,23 +68,6 @@ to rewrite your index to not be sparse. Older versions of Git will not
|
||||||
understand the sparse directory entries index extension and may fail to
|
understand the sparse directory entries index extension and may fail to
|
||||||
interact with your repository until it is disabled.
|
interact with your repository until it is disabled.
|
||||||
|
|
||||||
'set'::
|
|
||||||
Write a set of patterns to the sparse-checkout file, as given as
|
|
||||||
a list of arguments following the 'set' subcommand. Update the
|
|
||||||
working directory to match the new patterns. Enable the
|
|
||||||
core.sparseCheckout config setting if it is not already enabled.
|
|
||||||
+
|
|
||||||
When the `--stdin` option is provided, the patterns are read from
|
|
||||||
standard in as a newline-delimited list instead of from the arguments.
|
|
||||||
+
|
|
||||||
When `core.sparseCheckoutCone` is enabled, the input list is considered a
|
|
||||||
list of directories instead of sparse-checkout patterns. The command writes
|
|
||||||
patterns to the sparse-checkout file to include all files contained in those
|
|
||||||
directories (recursively) as well as files that are siblings of ancestor
|
|
||||||
directories. The input format matches the output of `git ls-tree --name-only`.
|
|
||||||
This includes interpreting pathnames that begin with a double quote (") as
|
|
||||||
C-style quoted strings.
|
|
||||||
|
|
||||||
'add'::
|
'add'::
|
||||||
Update the sparse-checkout file to include additional patterns.
|
Update the sparse-checkout file to include additional patterns.
|
||||||
By default, these patterns are read from the command-line arguments,
|
By default, these patterns are read from the command-line arguments,
|
||||||
|
|
@ -93,12 +84,35 @@ C-style quoted strings.
|
||||||
cases, it can make sense to run `git sparse-checkout reapply` later
|
cases, it can make sense to run `git sparse-checkout reapply` later
|
||||||
after cleaning up affected paths (e.g. resolving conflicts, undoing
|
after cleaning up affected paths (e.g. resolving conflicts, undoing
|
||||||
or committing changes, etc.).
|
or committing changes, etc.).
|
||||||
|
+
|
||||||
|
The `reapply` command can also take `--[no-]cone` and `--[no-]sparse-index`
|
||||||
|
flags, with the same meaning as the flags from the `set` command, in order
|
||||||
|
to change which sparsity mode you are using without needing to also respecify
|
||||||
|
all sparsity paths.
|
||||||
|
|
||||||
'disable'::
|
'disable'::
|
||||||
Disable the `core.sparseCheckout` config setting, and restore the
|
Disable the `core.sparseCheckout` config setting, and restore the
|
||||||
working directory to include all files. Leaves the sparse-checkout
|
working directory to include all files.
|
||||||
file intact so a later 'git sparse-checkout init' command may
|
|
||||||
return the working directory to the same state.
|
'init'::
|
||||||
|
Deprecated command that behaves like `set` with no specified paths.
|
||||||
|
May be removed in the future.
|
||||||
|
+
|
||||||
|
Historically, `set` did not handle all the necessary config settings,
|
||||||
|
which meant that both `init` and `set` had to be called. Invoking
|
||||||
|
both meant the `init` step would first remove nearly all tracked files
|
||||||
|
(and in cone mode, ignored files too), then the `set` step would add
|
||||||
|
many of the tracked files (but not ignored files) back. In addition
|
||||||
|
to the lost files, the performance and UI of this combination was
|
||||||
|
poor.
|
||||||
|
+
|
||||||
|
Also, historically, `init` would not actually initialize the
|
||||||
|
sparse-checkout file if it already existed. This meant it was
|
||||||
|
possible to return to a sparse-checkout without remembering which
|
||||||
|
paths to pass to a subsequent 'set' or 'add' command. However,
|
||||||
|
`--cone` and `--sparse-index` options would not be remembered across
|
||||||
|
the disable command, so the easy restore of calling a plain `init`
|
||||||
|
decreased in utility.
|
||||||
|
|
||||||
SPARSE CHECKOUT
|
SPARSE CHECKOUT
|
||||||
---------------
|
---------------
|
||||||
|
|
@ -107,7 +121,7 @@ SPARSE CHECKOUT
|
||||||
It uses the skip-worktree bit (see linkgit:git-update-index[1]) to tell
|
It uses the skip-worktree bit (see linkgit:git-update-index[1]) to tell
|
||||||
Git whether a file in the working directory is worth looking at. If
|
Git whether a file in the working directory is worth looking at. If
|
||||||
the skip-worktree bit is set, then the file is ignored in the working
|
the skip-worktree bit is set, then the file is ignored in the working
|
||||||
directory. Git will not populate the contents of those files, which
|
directory. Git will avoid populating the contents of those files, which
|
||||||
makes a sparse checkout helpful when working in a repository with many
|
makes a sparse checkout helpful when working in a repository with many
|
||||||
files, but only a few are important to the current user.
|
files, but only a few are important to the current user.
|
||||||
|
|
||||||
|
|
@ -117,10 +131,8 @@ directory, it updates the skip-worktree bits in the index based
|
||||||
on this file. The files matching the patterns in the file will
|
on this file. The files matching the patterns in the file will
|
||||||
appear in the working directory, and the rest will not.
|
appear in the working directory, and the rest will not.
|
||||||
|
|
||||||
To enable the sparse-checkout feature, run `git sparse-checkout init` to
|
To enable the sparse-checkout feature, run `git sparse-checkout set` to
|
||||||
initialize a simple sparse-checkout file and enable the `core.sparseCheckout`
|
set the patterns you want to use.
|
||||||
config setting. Then, run `git sparse-checkout set` to modify the patterns in
|
|
||||||
the sparse-checkout file.
|
|
||||||
|
|
||||||
To repopulate the working directory with all files, use the
|
To repopulate the working directory with all files, use the
|
||||||
`git sparse-checkout disable` command.
|
`git sparse-checkout disable` command.
|
||||||
|
|
|
||||||
|
|
@ -633,7 +633,7 @@ static int git_sparse_checkout_init(const char *repo)
|
||||||
{
|
{
|
||||||
struct strvec argv = STRVEC_INIT;
|
struct strvec argv = STRVEC_INIT;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
strvec_pushl(&argv, "-C", repo, "sparse-checkout", "init", NULL);
|
strvec_pushl(&argv, "-C", repo, "sparse-checkout", "set", NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must apply the setting in the current process
|
* We must apply the setting in the current process
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,9 @@ static int sparse_checkout_list(int argc, const char **argv)
|
||||||
char *sparse_filename;
|
char *sparse_filename;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
if (!core_apply_sparse_checkout)
|
||||||
|
die(_("this worktree is not sparse"));
|
||||||
|
|
||||||
argc = parse_options(argc, argv, NULL,
|
argc = parse_options(argc, argv, NULL,
|
||||||
builtin_sparse_checkout_list_options,
|
builtin_sparse_checkout_list_options,
|
||||||
builtin_sparse_checkout_list_usage, 0);
|
builtin_sparse_checkout_list_usage, 0);
|
||||||
|
|
@ -380,6 +383,41 @@ static int set_config(enum sparse_checkout_mode mode)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int update_modes(int *cone_mode, int *sparse_index)
|
||||||
|
{
|
||||||
|
int mode, record_mode;
|
||||||
|
|
||||||
|
/* Determine if we need to record the mode; ensure sparse checkout on */
|
||||||
|
record_mode = (*cone_mode != -1) || !core_apply_sparse_checkout;
|
||||||
|
|
||||||
|
/* If not specified, use previous definition of cone mode */
|
||||||
|
if (*cone_mode == -1 && core_apply_sparse_checkout)
|
||||||
|
*cone_mode = core_sparse_checkout_cone;
|
||||||
|
|
||||||
|
/* Set cone/non-cone mode appropriately */
|
||||||
|
core_apply_sparse_checkout = 1;
|
||||||
|
if (*cone_mode == 1) {
|
||||||
|
mode = MODE_CONE_PATTERNS;
|
||||||
|
core_sparse_checkout_cone = 1;
|
||||||
|
} else {
|
||||||
|
mode = MODE_ALL_PATTERNS;
|
||||||
|
}
|
||||||
|
if (record_mode && set_config(mode))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Set sparse-index/non-sparse-index mode if specified */
|
||||||
|
if (*sparse_index >= 0) {
|
||||||
|
if (set_sparse_index_config(the_repository, *sparse_index) < 0)
|
||||||
|
die(_("failed to modify sparse-index config"));
|
||||||
|
|
||||||
|
/* force an index rewrite */
|
||||||
|
repo_read_index(the_repository);
|
||||||
|
the_repository->index->updated_workdir = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static char const * const builtin_sparse_checkout_init_usage[] = {
|
static char const * const builtin_sparse_checkout_init_usage[] = {
|
||||||
N_("git sparse-checkout init [--cone] [--[no-]sparse-index]"),
|
N_("git sparse-checkout init [--cone] [--[no-]sparse-index]"),
|
||||||
NULL
|
NULL
|
||||||
|
|
@ -396,7 +434,6 @@ static int sparse_checkout_init(int argc, const char **argv)
|
||||||
char *sparse_filename;
|
char *sparse_filename;
|
||||||
int res;
|
int res;
|
||||||
struct object_id oid;
|
struct object_id oid;
|
||||||
int mode;
|
|
||||||
struct strbuf pattern = STRBUF_INIT;
|
struct strbuf pattern = STRBUF_INIT;
|
||||||
|
|
||||||
static struct option builtin_sparse_checkout_init_options[] = {
|
static struct option builtin_sparse_checkout_init_options[] = {
|
||||||
|
|
@ -409,19 +446,14 @@ static int sparse_checkout_init(int argc, const char **argv)
|
||||||
|
|
||||||
repo_read_index(the_repository);
|
repo_read_index(the_repository);
|
||||||
|
|
||||||
|
init_opts.cone_mode = -1;
|
||||||
init_opts.sparse_index = -1;
|
init_opts.sparse_index = -1;
|
||||||
|
|
||||||
argc = parse_options(argc, argv, NULL,
|
argc = parse_options(argc, argv, NULL,
|
||||||
builtin_sparse_checkout_init_options,
|
builtin_sparse_checkout_init_options,
|
||||||
builtin_sparse_checkout_init_usage, 0);
|
builtin_sparse_checkout_init_usage, 0);
|
||||||
|
|
||||||
if (init_opts.cone_mode) {
|
if (update_modes(&init_opts.cone_mode, &init_opts.sparse_index))
|
||||||
mode = MODE_CONE_PATTERNS;
|
|
||||||
core_sparse_checkout_cone = 1;
|
|
||||||
} else
|
|
||||||
mode = MODE_ALL_PATTERNS;
|
|
||||||
|
|
||||||
if (set_config(mode))
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
memset(&pl, 0, sizeof(pl));
|
memset(&pl, 0, sizeof(pl));
|
||||||
|
|
@ -429,17 +461,6 @@ static int sparse_checkout_init(int argc, const char **argv)
|
||||||
sparse_filename = get_sparse_checkout_filename();
|
sparse_filename = get_sparse_checkout_filename();
|
||||||
res = add_patterns_from_file_to_list(sparse_filename, "", 0, &pl, NULL, 0);
|
res = add_patterns_from_file_to_list(sparse_filename, "", 0, &pl, NULL, 0);
|
||||||
|
|
||||||
if (init_opts.sparse_index >= 0) {
|
|
||||||
if (set_sparse_index_config(the_repository, init_opts.sparse_index) < 0)
|
|
||||||
die(_("failed to modify sparse-index config"));
|
|
||||||
|
|
||||||
/* force an index rewrite */
|
|
||||||
repo_read_index(the_repository);
|
|
||||||
the_repository->index->updated_workdir = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
core_apply_sparse_checkout = 1;
|
|
||||||
|
|
||||||
/* If we already have a sparse-checkout file, use it. */
|
/* If we already have a sparse-checkout file, use it. */
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
free(sparse_filename);
|
free(sparse_filename);
|
||||||
|
|
@ -515,17 +536,9 @@ static void strbuf_to_cone_pattern(struct strbuf *line, struct pattern_list *pl)
|
||||||
insert_recursive_pattern(pl, line);
|
insert_recursive_pattern(pl, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char const * const builtin_sparse_checkout_set_usage[] = {
|
|
||||||
N_("git sparse-checkout (set|add) (--stdin | <patterns>)"),
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct sparse_checkout_set_opts {
|
|
||||||
int use_stdin;
|
|
||||||
} set_opts;
|
|
||||||
|
|
||||||
static void add_patterns_from_input(struct pattern_list *pl,
|
static void add_patterns_from_input(struct pattern_list *pl,
|
||||||
int argc, const char **argv)
|
int argc, const char **argv,
|
||||||
|
int use_stdin)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (core_sparse_checkout_cone) {
|
if (core_sparse_checkout_cone) {
|
||||||
|
|
@ -535,7 +548,7 @@ static void add_patterns_from_input(struct pattern_list *pl,
|
||||||
hashmap_init(&pl->parent_hashmap, pl_hashmap_cmp, NULL, 0);
|
hashmap_init(&pl->parent_hashmap, pl_hashmap_cmp, NULL, 0);
|
||||||
pl->use_cone_patterns = 1;
|
pl->use_cone_patterns = 1;
|
||||||
|
|
||||||
if (set_opts.use_stdin) {
|
if (use_stdin) {
|
||||||
struct strbuf unquoted = STRBUF_INIT;
|
struct strbuf unquoted = STRBUF_INIT;
|
||||||
while (!strbuf_getline(&line, stdin)) {
|
while (!strbuf_getline(&line, stdin)) {
|
||||||
if (line.buf[0] == '"') {
|
if (line.buf[0] == '"') {
|
||||||
|
|
@ -559,7 +572,7 @@ static void add_patterns_from_input(struct pattern_list *pl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (set_opts.use_stdin) {
|
if (use_stdin) {
|
||||||
struct strbuf line = STRBUF_INIT;
|
struct strbuf line = STRBUF_INIT;
|
||||||
|
|
||||||
while (!strbuf_getline(&line, stdin)) {
|
while (!strbuf_getline(&line, stdin)) {
|
||||||
|
|
@ -580,7 +593,8 @@ enum modify_type {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void add_patterns_cone_mode(int argc, const char **argv,
|
static void add_patterns_cone_mode(int argc, const char **argv,
|
||||||
struct pattern_list *pl)
|
struct pattern_list *pl,
|
||||||
|
int use_stdin)
|
||||||
{
|
{
|
||||||
struct strbuf buffer = STRBUF_INIT;
|
struct strbuf buffer = STRBUF_INIT;
|
||||||
struct pattern_entry *pe;
|
struct pattern_entry *pe;
|
||||||
|
|
@ -588,7 +602,7 @@ static void add_patterns_cone_mode(int argc, const char **argv,
|
||||||
struct pattern_list existing;
|
struct pattern_list existing;
|
||||||
char *sparse_filename = get_sparse_checkout_filename();
|
char *sparse_filename = get_sparse_checkout_filename();
|
||||||
|
|
||||||
add_patterns_from_input(pl, argc, argv);
|
add_patterns_from_input(pl, argc, argv, use_stdin);
|
||||||
|
|
||||||
memset(&existing, 0, sizeof(existing));
|
memset(&existing, 0, sizeof(existing));
|
||||||
existing.use_cone_patterns = core_sparse_checkout_cone;
|
existing.use_cone_patterns = core_sparse_checkout_cone;
|
||||||
|
|
@ -614,17 +628,19 @@ static void add_patterns_cone_mode(int argc, const char **argv,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_patterns_literal(int argc, const char **argv,
|
static void add_patterns_literal(int argc, const char **argv,
|
||||||
struct pattern_list *pl)
|
struct pattern_list *pl,
|
||||||
|
int use_stdin)
|
||||||
{
|
{
|
||||||
char *sparse_filename = get_sparse_checkout_filename();
|
char *sparse_filename = get_sparse_checkout_filename();
|
||||||
if (add_patterns_from_file_to_list(sparse_filename, "", 0,
|
if (add_patterns_from_file_to_list(sparse_filename, "", 0,
|
||||||
pl, NULL, 0))
|
pl, NULL, 0))
|
||||||
die(_("unable to load existing sparse-checkout patterns"));
|
die(_("unable to load existing sparse-checkout patterns"));
|
||||||
free(sparse_filename);
|
free(sparse_filename);
|
||||||
add_patterns_from_input(pl, argc, argv);
|
add_patterns_from_input(pl, argc, argv, use_stdin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int modify_pattern_list(int argc, const char **argv, enum modify_type m)
|
static int modify_pattern_list(int argc, const char **argv, int use_stdin,
|
||||||
|
enum modify_type m)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
int changed_config = 0;
|
int changed_config = 0;
|
||||||
|
|
@ -633,13 +649,13 @@ static int modify_pattern_list(int argc, const char **argv, enum modify_type m)
|
||||||
switch (m) {
|
switch (m) {
|
||||||
case ADD:
|
case ADD:
|
||||||
if (core_sparse_checkout_cone)
|
if (core_sparse_checkout_cone)
|
||||||
add_patterns_cone_mode(argc, argv, pl);
|
add_patterns_cone_mode(argc, argv, pl, use_stdin);
|
||||||
else
|
else
|
||||||
add_patterns_literal(argc, argv, pl);
|
add_patterns_literal(argc, argv, pl, use_stdin);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REPLACE:
|
case REPLACE:
|
||||||
add_patterns_from_input(pl, argc, argv);
|
add_patterns_from_input(pl, argc, argv, use_stdin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -659,41 +675,124 @@ static int modify_pattern_list(int argc, const char **argv, enum modify_type m)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sparse_checkout_set(int argc, const char **argv, const char *prefix,
|
static char const * const builtin_sparse_checkout_add_usage[] = {
|
||||||
enum modify_type m)
|
N_("git sparse-checkout add (--stdin | <patterns>)"),
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct sparse_checkout_add_opts {
|
||||||
|
int use_stdin;
|
||||||
|
} add_opts;
|
||||||
|
|
||||||
|
static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
static struct option builtin_sparse_checkout_set_options[] = {
|
static struct option builtin_sparse_checkout_add_options[] = {
|
||||||
OPT_BOOL(0, "stdin", &set_opts.use_stdin,
|
OPT_BOOL(0, "stdin", &add_opts.use_stdin,
|
||||||
N_("read patterns from standard in")),
|
N_("read patterns from standard in")),
|
||||||
OPT_END(),
|
OPT_END(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!core_apply_sparse_checkout)
|
||||||
|
die(_("no sparse-checkout to add to"));
|
||||||
|
|
||||||
repo_read_index(the_repository);
|
repo_read_index(the_repository);
|
||||||
|
|
||||||
|
argc = parse_options(argc, argv, prefix,
|
||||||
|
builtin_sparse_checkout_add_options,
|
||||||
|
builtin_sparse_checkout_add_usage,
|
||||||
|
PARSE_OPT_KEEP_UNKNOWN);
|
||||||
|
|
||||||
|
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>)"),
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct sparse_checkout_set_opts {
|
||||||
|
int cone_mode;
|
||||||
|
int sparse_index;
|
||||||
|
int use_stdin;
|
||||||
|
} set_opts;
|
||||||
|
|
||||||
|
static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
|
||||||
|
{
|
||||||
|
int default_patterns_nr = 2;
|
||||||
|
const char *default_patterns[] = {"/*", "!/*/", NULL};
|
||||||
|
|
||||||
|
static struct option builtin_sparse_checkout_set_options[] = {
|
||||||
|
OPT_BOOL(0, "cone", &set_opts.cone_mode,
|
||||||
|
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, "stdin", &set_opts.use_stdin,
|
||||||
|
N_("read patterns from standard in"),
|
||||||
|
PARSE_OPT_NONEG),
|
||||||
|
OPT_END(),
|
||||||
|
};
|
||||||
|
|
||||||
|
repo_read_index(the_repository);
|
||||||
|
|
||||||
|
set_opts.cone_mode = -1;
|
||||||
|
set_opts.sparse_index = -1;
|
||||||
|
|
||||||
argc = parse_options(argc, argv, prefix,
|
argc = parse_options(argc, argv, prefix,
|
||||||
builtin_sparse_checkout_set_options,
|
builtin_sparse_checkout_set_options,
|
||||||
builtin_sparse_checkout_set_usage,
|
builtin_sparse_checkout_set_usage,
|
||||||
PARSE_OPT_KEEP_UNKNOWN);
|
PARSE_OPT_KEEP_UNKNOWN);
|
||||||
|
|
||||||
return modify_pattern_list(argc, argv, m);
|
if (update_modes(&set_opts.cone_mode, &set_opts.sparse_index))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cone mode automatically specifies the toplevel directory. For
|
||||||
|
* non-cone mode, if nothing is specified, manually select just the
|
||||||
|
* top-level directory (much as 'init' would do).
|
||||||
|
*/
|
||||||
|
if (!core_sparse_checkout_cone && argc == 0) {
|
||||||
|
argv = default_patterns;
|
||||||
|
argc = default_patterns_nr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return modify_pattern_list(argc, argv, set_opts.use_stdin, REPLACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char const * const builtin_sparse_checkout_reapply_usage[] = {
|
static char const * const builtin_sparse_checkout_reapply_usage[] = {
|
||||||
N_("git sparse-checkout reapply"),
|
N_("git sparse-checkout reapply [--[no-]cone] [--[no-]sparse-index]"),
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct sparse_checkout_reapply_opts {
|
||||||
|
int cone_mode;
|
||||||
|
int sparse_index;
|
||||||
|
} reapply_opts;
|
||||||
|
|
||||||
static int sparse_checkout_reapply(int argc, const char **argv)
|
static int sparse_checkout_reapply(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
static struct option builtin_sparse_checkout_reapply_options[] = {
|
static struct option builtin_sparse_checkout_reapply_options[] = {
|
||||||
|
OPT_BOOL(0, "cone", &reapply_opts.cone_mode,
|
||||||
|
N_("initialize the sparse-checkout in cone mode")),
|
||||||
|
OPT_BOOL(0, "sparse-index", &reapply_opts.sparse_index,
|
||||||
|
N_("toggle the use of a sparse index")),
|
||||||
OPT_END(),
|
OPT_END(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!core_apply_sparse_checkout)
|
||||||
|
die(_("must be in a sparse-checkout to reapply sparsity patterns"));
|
||||||
|
|
||||||
argc = parse_options(argc, argv, NULL,
|
argc = parse_options(argc, argv, NULL,
|
||||||
builtin_sparse_checkout_reapply_options,
|
builtin_sparse_checkout_reapply_options,
|
||||||
builtin_sparse_checkout_reapply_usage, 0);
|
builtin_sparse_checkout_reapply_usage, 0);
|
||||||
|
|
||||||
repo_read_index(the_repository);
|
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;
|
||||||
|
|
||||||
return update_working_directory(NULL);
|
return update_working_directory(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -710,6 +809,17 @@ static int sparse_checkout_disable(int argc, const char **argv)
|
||||||
struct pattern_list pl;
|
struct pattern_list pl;
|
||||||
struct strbuf match_all = STRBUF_INIT;
|
struct strbuf match_all = STRBUF_INIT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We do not exit early if !core_apply_sparse_checkout; due to the
|
||||||
|
* ability for users to manually muck things up between
|
||||||
|
* direct editing of .git/info/sparse-checkout
|
||||||
|
* running read-tree -m u HEAD or update-index --skip-worktree
|
||||||
|
* direct toggling of config options
|
||||||
|
* users might end up with an index with SKIP_WORKTREE bit set on
|
||||||
|
* some files and not know how to undo it. So, here we just
|
||||||
|
* forcibly return to a dense checkout regardless of initial state.
|
||||||
|
*/
|
||||||
|
|
||||||
argc = parse_options(argc, argv, NULL,
|
argc = parse_options(argc, argv, NULL,
|
||||||
builtin_sparse_checkout_disable_options,
|
builtin_sparse_checkout_disable_options,
|
||||||
builtin_sparse_checkout_disable_usage, 0);
|
builtin_sparse_checkout_disable_usage, 0);
|
||||||
|
|
@ -758,9 +868,9 @@ int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)
|
||||||
if (!strcmp(argv[0], "init"))
|
if (!strcmp(argv[0], "init"))
|
||||||
return sparse_checkout_init(argc, argv);
|
return sparse_checkout_init(argc, argv);
|
||||||
if (!strcmp(argv[0], "set"))
|
if (!strcmp(argv[0], "set"))
|
||||||
return sparse_checkout_set(argc, argv, prefix, REPLACE);
|
return sparse_checkout_set(argc, argv, prefix);
|
||||||
if (!strcmp(argv[0], "add"))
|
if (!strcmp(argv[0], "add"))
|
||||||
return sparse_checkout_set(argc, argv, prefix, ADD);
|
return sparse_checkout_add(argc, argv, prefix);
|
||||||
if (!strcmp(argv[0], "reapply"))
|
if (!strcmp(argv[0], "reapply"))
|
||||||
return sparse_checkout_reapply(argc, argv);
|
return sparse_checkout_reapply(argc, argv);
|
||||||
if (!strcmp(argv[0], "disable"))
|
if (!strcmp(argv[0], "disable"))
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,15 @@ test_expect_success 'setup' '
|
||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'git sparse-checkout list (empty)' '
|
test_expect_success 'git sparse-checkout list (not sparse)' '
|
||||||
|
test_must_fail git -C repo sparse-checkout list >list 2>err &&
|
||||||
|
test_must_be_empty list &&
|
||||||
|
test_i18ngrep "this worktree is not sparse" err
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'git sparse-checkout list (not sparse)' '
|
||||||
|
git -C repo sparse-checkout set &&
|
||||||
|
rm repo/.git/info/sparse-checkout &&
|
||||||
git -C repo sparse-checkout list >list 2>err &&
|
git -C repo sparse-checkout list >list 2>err &&
|
||||||
test_must_be_empty list &&
|
test_must_be_empty list &&
|
||||||
test_i18ngrep "this worktree is not sparse (sparse-checkout file may not exist)" err
|
test_i18ngrep "this worktree is not sparse (sparse-checkout file may not exist)" err
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue