sparse-checkout: make set subsume init
cover sparse-checkout: make set subsume init
As described at [1], the split of init and set subcommands in sparse-checkout causes multiple issues:
* Poor performance (deleting all tracked files, then later restoring many and maybe even most of them)
* Poor UI (multiple progress bars in wrappers that hide both commands under 1 user-facing command)
* Loss of ignored files under directories the user wanted to keep
This series fixes this bug by providing a single command to switch to a
sparse-checkout: set. It does so by making set able to do the combined work of init and set. It keeps init as-is to give folks time to adapt, but marks it as deprecated.
A quick overview:
* Patches 1-2: small preparatory refactorings
* Patch 3: the crux of the series
* Patches 4-5: documentation modifications (Patch 4 is worth reviewing; it marks init as deprecated -- are others okay with that?)
* Patch 6: trivial modification of git clone --sparse to use git sparse-checkout set rather than git sparse-checkout init.
[1]
https://lore.kernel.org/git/CABPp-BE8TJ8QGAQWsSGT7S+9Xp-XmApcC9PSw3K=RQOP0rt+PQ@mail.gmail.com/
Elijah Newren (6):
sparse-checkout: pass use_stdin as a parameter instead of as a global
sparse-checkout: break apart functions for sparse_checkout_(set|add)
sparse-checkout: enable set to initialize sparse-checkout mode git-sparse-checkout.txt: update to document that set handles init
Documentation: clarify/correct a few sparsity related statements
clone: avoid using deprecated sparse-checkout init
Documentation/git-clone.txt | 8 +- Documentation/git-sparse-checkout.txt | 94 ++++++++++--------- builtin/clone.c | 2 +- builtin/sparse-checkout.c | 130 +++++++++++++++++++++----- 4 files changed, 160 insertions(+), 74 deletions(-)
base-commit: abe6bb3905392d5eb6b01fa6e54d7e784e0522aa
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1151%2Fnewren%2Fsparse-checkout-no-init-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1151/newren/sparse-checkout-no-init-v1
Pull-Request: https://github.com/git/git/pull/1151
Signature · 1 line
gitgitgadget
PATCH 1/6 sparse-checkout: pass use_stdin as a parameter instead of as a global
From: Elijah Newren <[email protected]>
add_patterns_from_input() has relied on a global variable, set_opts.use_stdin, which has been used by both the set and add subcommands of sparse-checkout. Once we introduce an add_opts.use_stdin, the hardcoding of set_opts.use_stdin will be incorrect. Pass the value as function parameter instead to allow us to make subsequent changes.
--- builtin/sparse-checkout.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
builtin/sparse-checkout.c +16 -12
@@ -525,7 +525,8 @@ static struct sparse_checkout_set_opts { } set_opts;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;if (core_sparse_checkout_cone) {
@@ -535,7 +536,7 @@ static void add_patterns_from_input(struct pattern_list *pl,hashmap_init (&pl->parent_hashmap, pl_hashmap_cmp,NULL ,0 ); pl->use_cone_patterns =1 ; -if (set_opts.use_stdin) { +if (use_stdin) {struct strbuf unquoted =STRBUF_INIT ;while (!strbuf_getline (&line, stdin)) {if (line.buf[0 ] =='"' ) {
@@ -559,7 +560,7 @@ static void add_patterns_from_input(struct pattern_list *pl, } } }else { -if (set_opts.use_stdin) { +if (use_stdin) {struct strbuf line =STRBUF_INIT ;while (!strbuf_getline (&line, stdin)) {
@@ -580,7 +581,8 @@ enum modify_type { };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 pattern_entry *pe;
@@ -588,7 +590,7 @@ static void add_patterns_cone_mode(int argc, const char **argv,struct pattern_list existing;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)); existing.use_cone_patterns = core_sparse_checkout_cone;
@@ -614,17 +616,19 @@ static void add_patterns_cone_mode(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 ();if (add_patterns_from_file_to_list (sparse_filename,"" ,0 , pl,NULL ,0 ))die (_ ("unable to load existing sparse-checkout patterns" ));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 changed_config =0 ;
@@ -633,13 +637,13 @@ static int modify_pattern_list(int argc, const char **argv, enum modify_type m)switch (m) {case ADD :if (core_sparse_checkout_cone) -add_patterns_cone_mode (argc, argv, pl); +add_patterns_cone_mode (argc, argv, pl, use_stdin);else -add_patterns_literal (argc, argv, pl); +add_patterns_literal (argc, argv, pl, use_stdin);break ;case REPLACE : -add_patterns_from_input (pl, argc, argv); +add_patterns_from_input (pl, argc, argv, use_stdin);break ; }
@@ -675,7 +679,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix, builtin_sparse_checkout_set_usage, PARSE_OPT_KEEP_UNKNOWN); -return modify_pattern_list (argc, argv, m); +return modify_pattern_list (argc, argv, set_opts.use_stdin, m); }static char const *const builtin_sparse_checkout_reapply_usage[] = {
Signature · 1 line
gitgitgadget
PATCH 2/6 sparse-checkout: break apart functions for sparse_checkout_(set|add)
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
sparse_checkout_set() was reused by sparse_checkout_add() with the only difference being a single parameter being passed to that function. However, we would like sparse_checkout_set() to do the same work that sparse_checkout_init() does if sparse checkouts are not already enabled. To facilitate this transition, give each mode their own copy of the function. This does not introduce any behavioral changes; that will come in a subsequent patch.
--- builtin/sparse-checkout.c | 54 +++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 14 deletions(-)
builtin/sparse-checkout.c +40 -14
@@ -515,15 +515,6 @@ static void strbuf_to_cone_pattern(struct strbuf *line, struct pattern_list *pl)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,int argc,const char **argv,int use_stdin)
@@ -663,8 +654,43 @@ static int modify_pattern_list(int argc, const char **argv, int use_stdin,return result; } -static int sparse_checkout_set(int argc, const char **argv, const char *prefix, - enum modify_type m) +static char const *const builtin_sparse_checkout_add_usage[] = { +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_add_options[] = { +OPT_BOOL (0 ,"stdin" , &add_opts.use_stdin, +N_ ("read patterns from standard in" )), +OPT_END (), + }; + +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 (--stdin | <patterns>)" ), +NULL +}; + +static struct sparse_checkout_set_opts { +int use_stdin; +} set_opts; + +static int sparse_checkout_set(int argc, const char **argv, const char *prefix) { static struct option builtin_sparse_checkout_set_options[] = { OPT_BOOL(0, "stdin", &set_opts.use_stdin,
@@ -679,7 +705,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix, builtin_sparse_checkout_set_usage, PARSE_OPT_KEEP_UNKNOWN); -return modify_pattern_list (argc, argv, set_opts.use_stdin, m); +return modify_pattern_list (argc, argv, set_opts.use_stdin,REPLACE ); }static char const *const builtin_sparse_checkout_reapply_usage[] = {
@@ -762,9 +788,9 @@ int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)if (!strcmp (argv[0 ],"init" ))return sparse_checkout_init (argc, argv);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" )) -return sparse_checkout_set (argc, argv, prefix,ADD ); +return sparse_checkout_add (argc, argv, prefix);if (!strcmp (argv[0 ],"reapply" ))return sparse_checkout_reapply (argc, argv);if (!strcmp (argv[0 ],"disable" ))
Signature · 1 line
gitgitgadget
PATCH 3/6 sparse-checkout: enable `set` to initialize sparse-checkout mode
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
The previously suggested workflow:
git sparse-checkout init ...
git sparse-checkout set ...
Suffered from three problems:
1) It would delete nearly all files in the first step, then restore them in the second. That was poor performance and forced unnecessary rebuilds.
2) The two-step process resulted in two progress bars, which was suboptimal from a UI point of view for wrappers that invoked both of these commands but only exposed a single command to their end users.
3) With cone mode, the first step would delete nearly all ignored files everywhere, because everything was considered to be outside of the specified sparsity paths. (The user was not allowed to specify any sparsity paths in the init step.)
Avoid these problems by teaching set to understand the extra parameters that init takes and performing any necessary initialization if not already in a sparse checkout.
--- builtin/sparse-checkout.c | 52 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-)
builtin/sparse-checkout.c +51 -1
@@ -682,17 +682,26 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) }static char const *const builtin_sparse_checkout_set_usage[] = { -N_ ("git sparse-checkout set (--stdin | <patterns>)" ), +N_ ("git sparse-checkout set [--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 mode, record_mode; +const char *default_patterns[] = {"/*" ,"!/*/" }; +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 (0 ,"stdin" , &set_opts.use_stdin,N_ ("read patterns from standard in" )),OPT_END (),
@@ -700,11 +709,52 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)repo_read_index (the_repository); + set_opts.cone_mode =-1 ; + set_opts.sparse_index =-1 ; + argc =parse_options (argc, argv, prefix, builtin_sparse_checkout_set_options, builtin_sparse_checkout_set_usage,PARSE_OPT_KEEP_UNKNOWN ); +/* Determine if we need to record the mode; ensure sparse checkout on */ + record_mode = (set_opts.cone_mode !=-1 ) || !core_apply_sparse_checkout; + core_apply_sparse_checkout =1 ; + +/* If not specified, use previous definition of cone mode */ +if (set_opts.cone_mode ==-1 && core_apply_sparse_checkout) + set_opts.cone_mode = core_sparse_checkout_cone; + +/* Set cone/non-cone mode appropriately */ +if (set_opts.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 (set_opts.sparse_index >=0 ) { +if (set_sparse_index_config (the_repository, set_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 ; + } + +/* +* 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 =2 ; + } +return modify_pattern_list (argc, argv, set_opts.use_stdin,REPLACE ); }
Signature · 1 line
gitgitgadget
Re: [PATCH 3/6] sparse-checkout: enable `set` to initialize sparse-checkout mode
Quoted 19 lines · Elijah Newren via GitGitGadget
From: Elijah Newren <[email protected]>
The previously suggested workflow:
git sparse-checkout init ...
git sparse-checkout set ...Suffered from three problems:
1) It would delete nearly all files in the first step, then restore them in the second. That was poor performance and forced unnecessary rebuilds.
2) The two-step process resulted in two progress bars, which was suboptimal from a UI point of view for wrappers that invoked both of these commands but only exposed a single command to their end users.
3) With cone mode, the first step would delete nearly all ignored files everywhere, because everything was considered to be outside of the specified sparsity paths. (The user was not allowed to specify any sparsity paths in theinitstep.)
Quoted 4 lines
Avoid these problems by teaching
setto understand the extra parameters thatinittakes and performing any necessary initialization if not already in a sparse checkout.
I really like this change! It always seemed weird that set would implicitly init, but without any of the options in init.
Quoted 10 lines
Signed-off-by Elijah Newren <[email protected]>--- builtin/sparse-checkout.c | 52 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-)builtin/sparse-checkout.c +0
-0
builtin/sparse-checkout.c static int sparse_checkout_add(int argc, const char **argv, const char *prefix) · line 685
Quoted 5 lines
builtin/sparse-checkout.c +1
-1@@ -682,17 +682,26 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) }static char const *const builtin_sparse_checkout_set_usage[] = { -N_ ("git sparse-checkout set (--stdin | <patterns>)" ), +N_ ("git sparse-checkout set [--cone] [--[no-]sparse-index] (--stdin | <patterns>)" ),
Since cone is an OPT_BOOL, shouldn't it appear in the usage string as --[no-]cone? Without a --no-cone option, it's not clear how a user would disable cone mode (since set preserves the existing cone mode setting if --cone isn't given).
Quoted 11 lines
builtin/sparse-checkout.c +2
-0NULL };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) {
builtin/sparse-checkout.c static int sparse_checkout_add(int argc, const char **argv, const char *prefix) · line 706
Quoted 10 lines
builtin/sparse-checkout.c +7
-0+int mode, record_mode; +const char *default_patterns[] = {"/*" ,"!/*/" }; +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 (0 ,"stdin" , &set_opts.use_stdin,N_ ("read patterns from standard in" )),
I know this isn't part of this patch, but is stdin really a bool (i.e. someone might specify --no-stdin)? If not, I think OPT_SET_INT might be more appropriate.
Quoted 9 lines
builtin/sparse-checkout.c +3
-0OPT_END(),@@ -700,11 +709,52 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)repo_read_index (the_repository); + set_opts.cone_mode =-1 ; + set_opts.sparse_index =-1 ; + argc = parse_options(argc, argv, prefix,
builtin/sparse-checkout.c static int sparse_checkout_set(int argc, const char **argv, const char *prefix) · line 725
Quoted 10 lines
builtin/sparse-checkout.c +6
-0builtin_sparse_checkout_set_options, builtin_sparse_checkout_set_usage, PARSE_OPT_KEEP_UNKNOWN); +/* Determine if we need to record the mode; ensure sparse checkout on */ + record_mode = (set_opts.cone_mode !=-1 ) || !core_apply_sparse_checkout; + core_apply_sparse_checkout =1 ; + +/* If not specified, use previous definition of cone mode */ +if (set_opts.cone_mode ==-1 && core_apply_sparse_checkout)
I *think* this is supposed go before the core_apply_sparse_checkout = 1; above it (if the intention is to only use the pre-existing cone mode setting when already in a sparse checkout). If not, the core_apply_sparse_checkout part of the condition is redundant and can be removed entirely.
Quoted 36 lines
builtin/sparse-checkout.c +32
-0+ set_opts.cone_mode = core_sparse_checkout_cone; + +/* Set cone/non-cone mode appropriately */ +if (set_opts.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 (set_opts.sparse_index >=0 ) { +if (set_sparse_index_config (the_repository, set_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 ; + } + +/* +* 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 =2 ; + } +return modify_pattern_list (argc, argv, set_opts.use_stdin,REPLACE ); }
Re: [PATCH 3/6] sparse-checkout: enable `set` to initialize sparse-checkout mode
Quoted 41 lines · Victoria Dye
Quoted 19 lines · Elijah Newren via GitGitGadget
From: Elijah Newren <[email protected]>
The previously suggested workflow:
git sparse-checkout init ...
git sparse-checkout set ...Suffered from three problems:
1) It would delete nearly all files in the first step, then restore them in the second. That was poor performance and forced unnecessary rebuilds.
2) The two-step process resulted in two progress bars, which was suboptimal from a UI point of view for wrappers that invoked both of these commands but only exposed a single command to their end users.
3) With cone mode, the first step would delete nearly all ignored files everywhere, because everything was considered to be outside of the specified sparsity paths. (The user was not allowed to specify any sparsity paths in theinitstep.)Quoted 4 lines
Avoid these problems by teaching
setto understand the extra parameters thatinittakes and performing any necessary initialization if not already in a sparse checkout.I really like this change! It always seemed weird that
setwould implicitlyinit, but without any of the options ininit.Quoted 12 lines
Signed-off-by Elijah Newren <[email protected]>--- builtin/sparse-checkout.c | 52 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-)builtin/sparse-checkout.c +0
-0@@ -682,17 +682,26 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) }
Quoted 8 lines
builtin/sparse-checkout.c static int sparse_checkout_add(int argc, const char **argv, const char *prefix) · line 685
Quoted 3 lines
builtin/sparse-checkout.c +1
-1static char const *const builtin_sparse_checkout_set_usage[] = { -N_ ("git sparse-checkout set (--stdin | <patterns>)" ), +N_ ("git sparse-checkout set [--cone] [--[no-]sparse-index] (--stdin | <patterns>)" ),Since
coneis anOPT_BOOL, shouldn't it appear in the usage string as--[no-]cone? Without a--no-coneoption, it's not clear how a user would disable cone mode (sincesetpreserves the existing cone mode setting if--coneisn't given).
Yeah, fair point. When copying from init I probably should have double checked.
Also, it makes me wonder if we should just make cone mode the default...
Quoted 22 lines
Quoted 11 lines
builtin/sparse-checkout.c +2
-0NULL };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) {builtin/sparse-checkout.c static int sparse_checkout_add(int argc, const char **argv, const char *prefix) · line 706
Quoted 10 lines
builtin/sparse-checkout.c +7
-0+int mode, record_mode; +const char *default_patterns[] = {"/*" ,"!/*/" }; +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 (0 ,"stdin" , &set_opts.use_stdin,N_ ("read patterns from standard in" )),
Quoted 3 lines
I know this isn't part of this patch, but is
stdinreally a bool (i.e. someone might specify--no-stdin)? If not, I thinkOPT_SET_INTmight be more appropriate.
Good point. OPT_SET_INT() wouldn't fix it, though; you need to use OPT_BOOL_F or OPT_SET_INT_F and pass PARSE_OPT_NONEG as a flag. I can include that.
Quoted 13 lines
Quoted 13 lines
builtin/sparse-checkout.c +3
-0OPT_END(),@@ -700,11 +709,52 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)repo_read_index (the_repository); + set_opts.cone_mode =-1 ; + set_opts.sparse_index =-1 ; + argc =parse_options (argc, argv, prefix, builtin_sparse_checkout_set_options, builtin_sparse_checkout_set_usage,PARSE_OPT_KEEP_UNKNOWN );
Quoted 11 lines
builtin/sparse-checkout.c static int sparse_checkout_set(int argc, const char **argv, const char *prefix) · line 725
Quoted 6 lines
builtin/sparse-checkout.c +6
-0+/* Determine if we need to record the mode; ensure sparse checkout on */ + record_mode = (set_opts.cone_mode !=-1 ) || !core_apply_sparse_checkout; + core_apply_sparse_checkout =1 ; + +/* If not specified, use previous definition of cone mode */ +if (set_opts.cone_mode ==-1 && core_apply_sparse_checkout)I *think* this is supposed go before the
core_apply_sparse_checkout = 1;above it (if the intention is to only use the pre-existing cone mode setting when already in a sparse checkout). If not, thecore_apply_sparse_checkoutpart of the condition is redundant and can be removed entirely.
Eek. I had it there originally, then moved it later while doing various changes. This definitely should be later; thanks for catching.
Quoted 34 lines
Quoted 34 lines
builtin/sparse-checkout.c +32
-0+ set_opts.cone_mode = core_sparse_checkout_cone; + +/* Set cone/non-cone mode appropriately */ +if (set_opts.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 (set_opts.sparse_index >=0 ) { +if (set_sparse_index_config (the_repository, set_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 ; + } + +/* +* 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 =2 ; + } +return modify_pattern_list (argc, argv, set_opts.use_stdin,REPLACE ); }
Re: [PATCH 3/6] sparse-checkout: enable `set` to initialize sparse-checkout mode
Quoted 51 lines · Elijah Newren
Quoted 41 lines · Victoria Dye
Quoted 19 lines · Elijah Newren via GitGitGadget
From: Elijah Newren <[email protected]>
The previously suggested workflow:
git sparse-checkout init ...
git sparse-checkout set ...Suffered from three problems:
1) It would delete nearly all files in the first step, then restore them in the second. That was poor performance and forced unnecessary rebuilds.
2) The two-step process resulted in two progress bars, which was suboptimal from a UI point of view for wrappers that invoked both of these commands but only exposed a single command to their end users.
3) With cone mode, the first step would delete nearly all ignored files everywhere, because everything was considered to be outside of the specified sparsity paths. (The user was not allowed to specify any sparsity paths in theinitstep.)Quoted 4 lines
Avoid these problems by teaching
setto understand the extra parameters thatinittakes and performing any necessary initialization if not already in a sparse checkout.I really like this change! It always seemed weird that
setwould implicitlyinit, but without any of the options ininit.Quoted 12 lines
Signed-off-by Elijah Newren <[email protected]>--- builtin/sparse-checkout.c | 52 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-)builtin/sparse-checkout.c +0
-0@@ -682,17 +682,26 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) }Quoted 8 lines
builtin/sparse-checkout.c static int sparse_checkout_add(int argc, const char **argv, const char *prefix) · line 685
Quoted 3 lines
builtin/sparse-checkout.c +1
-1static char const *const builtin_sparse_checkout_set_usage[] = { -N_ ("git sparse-checkout set (--stdin | <patterns>)" ), +N_ ("git sparse-checkout set [--cone] [--[no-]sparse-index] (--stdin | <patterns>)" ),Since
coneis anOPT_BOOL, shouldn't it appear in the usage string as--[no-]cone? Without a--no-coneoption, it's not clear how a user would disable cone mode (sincesetpreserves the existing cone mode setting if--coneisn't given).
Quoted 4 lines
Yeah, fair point. When copying from init I probably should have double checked.
Also, it makes me wonder if we should just make cone mode the default...
That was actually my first thought when reviewing this change! It feels like this would be a great moment to take the leap on that, but I can also see it warranting a separate series.
Quoted 93 lines
Quoted 22 lines
Quoted 11 lines
builtin/sparse-checkout.c +2
-0NULL };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) {builtin/sparse-checkout.c static int sparse_checkout_add(int argc, const char **argv, const char *prefix) · line 706
Quoted 10 lines
builtin/sparse-checkout.c +7
-0+int mode, record_mode; +const char *default_patterns[] = {"/*" ,"!/*/" }; +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 (0 ,"stdin" , &set_opts.use_stdin,N_ ("read patterns from standard in" )),Quoted 3 lines
I know this isn't part of this patch, but is
stdinreally a bool (i.e. someone might specify--no-stdin)? If not, I thinkOPT_SET_INTmight be more appropriate.Good point.
OPT_SET_INT()wouldn't fix it, though; you need to useOPT_BOOL_ForOPT_SET_INT_Fand passPARSE_OPT_NONEGas a flag. I can include that.Quoted 13 lines
Quoted 13 lines
builtin/sparse-checkout.c +3
-0OPT_END(),@@ -700,11 +709,52 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)repo_read_index (the_repository); + set_opts.cone_mode =-1 ; + set_opts.sparse_index =-1 ; + argc =parse_options (argc, argv, prefix, builtin_sparse_checkout_set_options, builtin_sparse_checkout_set_usage,PARSE_OPT_KEEP_UNKNOWN );Quoted 11 lines
builtin/sparse-checkout.c static int sparse_checkout_set(int argc, const char **argv, const char *prefix) · line 725
Quoted 6 lines
builtin/sparse-checkout.c +6
-0+/* Determine if we need to record the mode; ensure sparse checkout on */ + record_mode = (set_opts.cone_mode !=-1 ) || !core_apply_sparse_checkout; + core_apply_sparse_checkout =1 ; + +/* If not specified, use previous definition of cone mode */ +if (set_opts.cone_mode ==-1 && core_apply_sparse_checkout)I *think* this is supposed go before the
core_apply_sparse_checkout = 1;above it (if the intention is to only use the pre-existing cone mode setting when already in a sparse checkout). If not, thecore_apply_sparse_checkoutpart of the condition is redundant and can be removed entirely.Eek. I had it there originally, then moved it later while doing various changes. This definitely should be later; thanks for catching.
Quoted 34 lines
Quoted 34 lines
builtin/sparse-checkout.c +32
-0+ set_opts.cone_mode = core_sparse_checkout_cone; + +/* Set cone/non-cone mode appropriately */ +if (set_opts.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 (set_opts.sparse_index >=0 ) { +if (set_sparse_index_config (the_repository, set_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 ; + } + +/* +* 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 =2 ; + } +return modify_pattern_list (argc, argv, set_opts.use_stdin,REPLACE ); }
Re: [PATCH 3/6] sparse-checkout: enable `set` to initialize sparse-checkout mode
In reply to Elijah Newren via GitGitGadgetbuiltin/sparse-checkout.c static int sparse_checkout_add(int argc, const char **argv, const char *prefix) · line 698
Quoted 4 lines · Elijah Newren via GitGitGadget
static int
sparse_checkout_set(int argc, const char **argv, const char *prefix){builtin/sparse-checkout.c +2
-0+int mode, record_mode; +const char *default_patterns[] = {"/*" ,"!/*/" };
My gut reaction is that this array should be NULL terminated.
Quoted 28 lines
builtin/sparse-checkout.c +15
-0+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 (0 ,"stdin" , &set_opts.use_stdin,N_ ("read patterns from standard in" )),OPT_END (),@@ -700,11 +709,52 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)repo_read_index (the_repository); + set_opts.cone_mode =-1 ; + set_opts.sparse_index =-1 ; + argc =parse_options (argc, argv, prefix, builtin_sparse_checkout_set_options, builtin_sparse_checkout_set_usage,PARSE_OPT_KEEP_UNKNOWN ); +/* Determine if we need to record the mode; ensure sparse checkout on */ + record_mode = (set_opts.cone_mode !=-1 ) || !core_apply_sparse_checkout; + core_apply_sparse_checkout =1 ; + +/* If not specified, use previous definition of cone mode */ +if (set_opts.cone_mode ==-1 && core_apply_sparse_checkout) + set_opts.cone_mode = core_sparse_checkout_cone;
builtin/sparse-checkout.c static int sparse_checkout_set(int argc, const char **argv, const char *prefix) · line 736
Quoted 10 lines
builtin/sparse-checkout.c +10
-0+ +/* Set cone/non-cone mode appropriately */ +if (set_opts.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 ;
I think it is appropriate to still have the init steps before the modification of the worktree. I did have a brief pause to think about whether the set_config() should be delayed until modify_pattern_list() succeeds.
Quoted 8 lines
builtin/sparse-checkout.c +8
-0+/* Set sparse-index/non-sparse-index mode if specified */ +if (set_opts.sparse_index >=0 ) { +if (set_sparse_index_config (the_repository, set_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 ;
builtin/sparse-checkout.c static int sparse_checkout_set(int argc, const char **argv, const char *prefix) · line 755
Quoted 10 lines
builtin/sparse-checkout.c +10
-0+ } + +/* +* 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 =2 ;
Perhaps use 'default_patterns_nr' as a constant near the definition of 'default_patterns' so these numbers are not so far apart?
builtin/sparse-checkout.c static int sparse_checkout_set(int argc, const char **argv, const char *prefix) · line 759
Quoted 4 lines
builtin/sparse-checkout.c +2
-0+ } +return modify_pattern_list (argc, argv, set_opts.use_stdin,REPLACE ); }
Thanks,
-Stolee
Re: [PATCH 3/6] sparse-checkout: enable `set` to initialize sparse-checkout mode
Quoted 8 lines · Derrick Stolee
builtin/sparse-checkout.c static int sparse_checkout_add(int argc, const char **argv, const char *prefix) · line 698
Quoted 4 lines · Elijah Newren via GitGitGadget
static int
sparse_checkout_set(int argc, const char **argv, const char *prefix){builtin/sparse-checkout.c +2
-0+int mode, record_mode; +const char *default_patterns[] = {"/*" ,"!/*/" };My gut reaction is that this array should be NULL terminated.
Sure, I can make that change.
Quoted 56 lines
Quoted 28 lines
builtin/sparse-checkout.c +15
-0+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 (0 ,"stdin" , &set_opts.use_stdin,N_ ("read patterns from standard in" )),OPT_END (),@@ -700,11 +709,52 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)repo_read_index (the_repository); + set_opts.cone_mode =-1 ; + set_opts.sparse_index =-1 ; + argc =parse_options (argc, argv, prefix, builtin_sparse_checkout_set_options, builtin_sparse_checkout_set_usage,PARSE_OPT_KEEP_UNKNOWN ); +/* Determine if we need to record the mode; ensure sparse checkout on */ + record_mode = (set_opts.cone_mode !=-1 ) || !core_apply_sparse_checkout; + core_apply_sparse_checkout =1 ; + +/* If not specified, use previous definition of cone mode */ +if (set_opts.cone_mode ==-1 && core_apply_sparse_checkout) + set_opts.cone_mode = core_sparse_checkout_cone;builtin/sparse-checkout.c static int sparse_checkout_set(int argc, const char **argv, const char *prefix) · line 736
Quoted 10 lines
builtin/sparse-checkout.c +10
-0+ +/* Set cone/non-cone mode appropriately */ +if (set_opts.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 ;I think it is appropriate to still have the init steps before the modification of the worktree. I did have a brief pause to think about whether the
set_config()should be delayed untilmodify_pattern_list()succeeds.Quoted 13 lines
builtin/sparse-checkout.c +13
-0+/* Set sparse-index/non-sparse-index mode if specified */ +if (set_opts.sparse_index >=0 ) { +if (set_sparse_index_config (the_repository, set_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 ; + } + +/* +* Cone mode automatically specifies the toplevel directory. For +* non-cone mode, if nothing is specified, manually select just the
Quoted 8 lines
builtin/sparse-checkout.c static int sparse_checkout_set(int argc, const char **argv, const char *prefix) · line 755
Quoted 5 lines
builtin/sparse-checkout.c +5
-0+* top-level directory (much as 'init' would do). +*/ +if (!core_sparse_checkout_cone && argc ==0 ) { + argv = default_patterns; + argc =2 ;Perhaps use '
default_patterns_nr' as a constant near the definition of 'default_patterns' so these numbers are not so far apart?
Sounds like a good idea; will do.
Quoted 8 lines
builtin/sparse-checkout.c static int sparse_checkout_set(int argc, const char **argv, const char *prefix) · line 759
Quoted 5 lines
builtin/sparse-checkout.c +2
-0+ } +return modify_pattern_list (argc, argv, set_opts.use_stdin,REPLACE ); }Thanks,
-Stolee
PATCH 4/6 git-sparse-checkout.txt: update to document that set handles init
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
As noted in the previous commit, using separate init and set steps with sparse-checkout result in a number of issues. The previous commit made set able to handle the work of both commands. Update the documentation to reflect this, and mark init as deprecated.
--- Documentation/git-sparse-checkout.txt | 92 ++++++++++++++------------- 1 file changed, 49 insertions(+), 43 deletions(-)
Documentation/git-sparse-checkout.txt +49 -43
@@ -30,28 +30,35 @@ COMMANDS 'list':: Describe the patterns in the sparse-checkout file. -'init':: - Enable the `core.sparseCheckout` setting. If the - sparse-checkout file does not exist, then populate it with - patterns that match every file in the root directory and - no other directories, then will remove all directories tracked - by Git. Add patterns to the sparse-checkout file to - repopulate the working directory. +'set':: + Enable the necessary config settings + (extensions.worktreeConfig, core.sparseCheckout, + core.sparseCheckoutCone) if they are not already enabled, and + write a set of patterns to the sparse-checkout file from the + list of arguments following the 'set' subcommand. Update the + working directory to match the new patterns. + -To avoid interfering with other worktrees, it first enables the -`extensions.worktreeConfig` setting and makes sure to set the -`core.sparseCheckout` setting in the worktree-specific config file. +When the `--stdin` option is provided, the patterns are read from +standard in as a newline-delimited list instead of from the arguments. + -When `--cone` is provided, the `core.sparseCheckoutCone` setting is -also set, allowing for better performance with a limited set of -patterns (see 'CONE PATTERN SET' below). +When `--cone` is passed or `core.sparseCheckoutCone` is enabled, the +input list is considered a list of directories instead of +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. + -Use the `--[no-]sparse-index` option to toggle the use of the sparse -index format. This reduces the size of the index to be more closely -aligned with your sparse-checkout definition. This can have significant -performance advantages for commands such as `git status` or `git add`. -This feature is still experimental. Some commands might be slower with -a sparse index until they are properly integrated with the feature. +Use the `--[no-]sparse-index` option to use a sparse index (the +default is to not use it). A sparse index reduces the size of the +index to be more closely aligned with your sparse-checkout +definition. This can have significant performance advantages for +commands such as `git status` or `git add`. This feature is still +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 that is not completely understood by external tools. If you have trouble
@@ -60,23 +67,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 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':: Update the sparse-checkout file to include additional patterns. By default, these patterns are read from the command-line arguments,
@@ -96,9 +86,27 @@ C-style quoted strings. 'disable':: Disable the `core.sparseCheckout` config setting, and restore the - working directory to include all files. Leaves the sparse-checkout - file intact so a later 'git sparse-checkout init' command may - return the working directory to the same state. + working directory to include all files. + +'init':: + Deprecated command that behaves like `set` with no specified paths. + May be removed in the future. ++ +Historically, `set` did not used to 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 ---------------
@@ -117,10 +125,8 @@ directory, it updates the skip-worktree bits in the index based on this file. The files matching the patterns in the file will appear in the working directory, and the rest will not. -To enable the sparse-checkout feature, run `git sparse-checkout init` to -initialize a simple sparse-checkout file and enable the `core.sparseCheckout` -config setting. Then, run `git sparse-checkout set` to modify the patterns in -the sparse-checkout file. +To enable the sparse-checkout feature, run `git sparse-checkout set` to +set the patterns you want to use. To repopulate the working directory with all files, use the `git sparse-checkout disable` command.
Signature · 1 line
gitgitgadget
Re: [PATCH 4/6] git-sparse-checkout.txt: update to document that set handles init
Quoted 97 lines · Elijah Newren via GitGitGadget
From: Elijah Newren <[email protected]>
As noted in the previous commit, using separate
initandsetsteps with sparse-checkout result in a number of issues. The previous commit madesetable to handle the work of both commands. Update the documentation to reflect this, and markinitas deprecated.Signed-off-by Elijah Newren <[email protected]>--- Documentation/git-sparse-checkout.txt | 92 ++++++++++++++------------- 1 file changed, 49 insertions(+), 43 deletions(-)Documentation/git-sparse-checkout.txt +26
-36@@ -30,28 +30,35 @@ COMMANDS 'list':: Describe the patterns in the sparse-checkout file. -'init':: - Enable the `core.sparseCheckout` setting. If the - sparse-checkout file does not exist, then populate it with - patterns that match every file in the root directory and - no other directories, then will remove all directories tracked - by Git. Add patterns to the sparse-checkout file to - repopulate the working directory. +'set':: + Enable the necessary config settings + (extensions.worktreeConfig, core.sparseCheckout, + core.sparseCheckoutCone) if they are not already enabled, and + write a set of patterns to the sparse-checkout file from the + list of arguments following the 'set' subcommand. Update the + working directory to match the new patterns. + -To avoid interfering with other worktrees, it first enables the -`extensions.worktreeConfig` setting and makes sure to set the -`core.sparseCheckout` setting in the worktree-specific config file. +When the `--stdin` option is provided, the patterns are read from +standard in as a newline-delimited list instead of from the arguments. + -When `--cone` is provided, the `core.sparseCheckoutCone` setting is -also set, allowing for better performance with a limited set of -patterns (see 'CONE PATTERN SET' below). +When `--cone` is passed or `core.sparseCheckoutCone` is enabled, the +input list is considered a list of directories instead of +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. + -Use the `--[no-]sparse-index` option to toggle the use of the sparse -index format. This reduces the size of the index to be more closely -aligned with your sparse-checkout definition. This can have significant -performance advantages for commands such as `git status` or `git add`. -This feature is still experimental. Some commands might be slower with -a sparse index until they are properly integrated with the feature. +Use the `--[no-]sparse-index` option to use a sparse index (the +default is to not use it). A sparse index reduces the size of the +index to be more closely aligned with your sparse-checkout +definition. This can have significant performance advantages for +commands such as `git status` or `git add`. This feature is still +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 that is not completely understood by external tools. If you have trouble@@ -60,23 +67,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 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':: Update the sparse-checkout file to include additional patterns. By default, these patterns are read from the command-line arguments,@@ -96,9 +86,27 @@ C-style quoted strings.
Documentation/git-sparse-checkout.txt C-style quoted strings. · line 93
Quoted 10 lines
Documentation/git-sparse-checkout.txt +5
-3'disable':: Disable the `core.sparseCheckout` config setting, and restore the - working directory to include all files. Leaves the sparse-checkout - file intact so a later 'git sparse-checkout init' command may - return the working directory to the same state. + working directory to include all files. + +'init':: + Deprecated command that behaves like `set` with no specified paths. + May be removed in the future.
I'm on board with deprecating init, but one usage that's not covered by the updated set is toggling the sparse index *without* modifying the patterns. That likely won't matter to most users, but ones that assume git sparse-checkout set --[no-]sparse-index works the same way as git sparse-checkout init --[no-]sparse-index would find themselves losing their existing pattern set.
Maybe --[no-]sparse-index should be added to git sparse-checkout reapply? For changing settings without updating patterns, that probably makes more sense than init or set anyway. If adding that option is outside the scope of what you want to do in this series, though, I'd be happy with a note somewhere in this documentation explicitly noting that set (unlike init) will change your patterns, even when toggling index.sparse (or core.sparseCheckoutCone).
Quoted 33 lines
Documentation/git-sparse-checkout.txt +18
-4++ +Historically, `set` did not used to 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 ---------------@@ -117,10 +125,8 @@ directory, it updates the skip-worktree bits in the index based on this file. The files matching the patterns in the file will appear in the working directory, and the rest will not. -To enable the sparse-checkout feature, run `git sparse-checkout init` to -initialize a simple sparse-checkout file and enable the `core.sparseCheckout` -config setting. Then, run `git sparse-checkout set` to modify the patterns in -the sparse-checkout file. +To enable the sparse-checkout feature, run `git sparse-checkout set` to +set the patterns you want to use. To repopulate the working directory with all files, use the `git sparse-checkout disable` command.
Re: [PATCH 4/6] git-sparse-checkout.txt: update to document that set handles init
Quoted 13 lines · Victoria Dye
Documentation/git-sparse-checkout.txt C-style quoted strings. · line 93
Quoted 3 lines · Elijah Newren via GitGitGadget
+'init'::
Documentation/git-sparse-checkout.txt +2
-0+ Deprecated command that behaves like `set` with no specified paths. + May be removed in the future.I'm on board with deprecating
init, but one usage that's not covered by the updatedsetis toggling the sparse index *without* modifying the patterns. That likely won't matter to most users, but ones that assumegit sparse-checkout set --[no-]sparse-indexworks the same way asgit sparse-checkout init --[no-]sparse-indexwould find themselves losing their existing pattern set.
Quoted 7 lines
Maybe
--[no-]sparse-indexshould be added togit sparse-checkout reapply? For changing settings without updating patterns, that probably makes more sense thaninitorsetanyway. If adding that option is outside the scope of what you want to do in this series, though, I'd be happy with a note somewhere in this documentation explicitly noting thatset(unlikeinit) will change your patterns, even when togglingindex.sparse(orcore.sparseCheckoutCone).
I like 'reapply' as a good place for that functionality. Hopefully it won't be long before the sparse index is on by default, but it will still be good to have a user-facing way to toggle it, when necessary.
Thanks,
-Stolee
Re: [PATCH 4/6] git-sparse-checkout.txt: update to document that set handles init
In reply to Victoria DyeQuoted 117 lines · Victoria Dye
Quoted 97 lines · Elijah Newren via GitGitGadget
From: Elijah Newren <[email protected]>
As noted in the previous commit, using separate
initandsetsteps with sparse-checkout result in a number of issues. The previous commit madesetable to handle the work of both commands. Update the documentation to reflect this, and markinitas deprecated.Signed-off-by Elijah Newren <[email protected]>--- Documentation/git-sparse-checkout.txt | 92 ++++++++++++++------------- 1 file changed, 49 insertions(+), 43 deletions(-)Documentation/git-sparse-checkout.txt +26
-36@@ -30,28 +30,35 @@ COMMANDS 'list':: Describe the patterns in the sparse-checkout file. -'init':: - Enable the `core.sparseCheckout` setting. If the - sparse-checkout file does not exist, then populate it with - patterns that match every file in the root directory and - no other directories, then will remove all directories tracked - by Git. Add patterns to the sparse-checkout file to - repopulate the working directory. +'set':: + Enable the necessary config settings + (extensions.worktreeConfig, core.sparseCheckout, + core.sparseCheckoutCone) if they are not already enabled, and + write a set of patterns to the sparse-checkout file from the + list of arguments following the 'set' subcommand. Update the + working directory to match the new patterns. + -To avoid interfering with other worktrees, it first enables the -`extensions.worktreeConfig` setting and makes sure to set the -`core.sparseCheckout` setting in the worktree-specific config file. +When the `--stdin` option is provided, the patterns are read from +standard in as a newline-delimited list instead of from the arguments. + -When `--cone` is provided, the `core.sparseCheckoutCone` setting is -also set, allowing for better performance with a limited set of -patterns (see 'CONE PATTERN SET' below). +When `--cone` is passed or `core.sparseCheckoutCone` is enabled, the +input list is considered a list of directories instead of +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. + -Use the `--[no-]sparse-index` option to toggle the use of the sparse -index format. This reduces the size of the index to be more closely -aligned with your sparse-checkout definition. This can have significant -performance advantages for commands such as `git status` or `git add`. -This feature is still experimental. Some commands might be slower with -a sparse index until they are properly integrated with the feature. +Use the `--[no-]sparse-index` option to use a sparse index (the +default is to not use it). A sparse index reduces the size of the +index to be more closely aligned with your sparse-checkout +definition. This can have significant performance advantages for +commands such as `git status` or `git add`. This feature is still +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 that is not completely understood by external tools. If you have trouble@@ -60,23 +67,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 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':: Update the sparse-checkout file to include additional patterns. By default, these patterns are read from the command-line arguments,@@ -96,9 +86,27 @@ C-style quoted strings.Documentation/git-sparse-checkout.txt C-style quoted strings. · line 93
Quoted 10 lines
Documentation/git-sparse-checkout.txt +5
-3'disable':: Disable the `core.sparseCheckout` config setting, and restore the - working directory to include all files. Leaves the sparse-checkout - file intact so a later 'git sparse-checkout init' command may - return the working directory to the same state. + working directory to include all files. + +'init':: + Deprecated command that behaves like `set` with no specified paths. + May be removed in the future.I'm on board with deprecating
init, but one usage that's not covered by the updatedsetis toggling the sparse index *without* modifying the patterns. That likely won't matter to most users, but ones that assumegit sparse-checkout set --[no-]sparse-indexworks the same way asgit sparse-checkout init --[no-]sparse-indexwould find themselves losing their existing pattern set.
Quoted 7 lines
Maybe
--[no-]sparse-indexshould be added togit sparse-checkout reapply? For changing settings without updating patterns, that probably makes more sense thaninitorsetanyway. If adding that option is outside the scope of what you want to do in this series, though, I'd be happy with a note somewhere in this documentation explicitly noting thatset(unlikeinit) will change your patterns, even when togglingindex.sparse(orcore.sparseCheckoutCone).
I like that idea; reapply seems like the right place to allow folks to toggle options without updating sparsity paths. I'll add it.
Quoted 34 lines
Quoted 33 lines
Documentation/git-sparse-checkout.txt +18
-4++ +Historically, `set` did not used to 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 ---------------@@ -117,10 +125,8 @@ directory, it updates the skip-worktree bits in the index based on this file. The files matching the patterns in the file will appear in the working directory, and the rest will not. -To enable the sparse-checkout feature, run `git sparse-checkout init` to -initialize a simple sparse-checkout file and enable the `core.sparseCheckout` -config setting. Then, run `git sparse-checkout set` to modify the patterns in -the sparse-checkout file. +To enable the sparse-checkout feature, run `git sparse-checkout set` to +set the patterns you want to use. To repopulate the working directory with all files, use the `git sparse-checkout disable` command.
Re: [PATCH 4/6] git-sparse-checkout.txt: update to document that set handles init
In reply to Elijah Newren via GitGitGadgetQuoted 106 lines · Elijah Newren via GitGitGadget
From: Elijah Newren <[email protected]>
As noted in the previous commit, using separate
initandsetsteps with sparse-checkout result in a number of issues. The previous commit madesetable to handle the work of both commands. Update the documentation to reflect this, and markinitas deprecated.Signed-off-by Elijah Newren <[email protected]>--- Documentation/git-sparse-checkout.txt | 92 ++++++++++++++------------- 1 file changed, 49 insertions(+), 43 deletions(-)Documentation/git-sparse-checkout.txt +30
-39@@ -30,28 +30,35 @@ COMMANDS 'list':: Describe the patterns in the sparse-checkout file. -'init':: - Enable the `core.sparseCheckout` setting. If the - sparse-checkout file does not exist, then populate it with - patterns that match every file in the root directory and - no other directories, then will remove all directories tracked - by Git. Add patterns to the sparse-checkout file to - repopulate the working directory. +'set':: + Enable the necessary config settings + (extensions.worktreeConfig, core.sparseCheckout, + core.sparseCheckoutCone) if they are not already enabled, and + write a set of patterns to the sparse-checkout file from the + list of arguments following the 'set' subcommand. Update the + working directory to match the new patterns. + -To avoid interfering with other worktrees, it first enables the -`extensions.worktreeConfig` setting and makes sure to set the -`core.sparseCheckout` setting in the worktree-specific config file. +When the `--stdin` option is provided, the patterns are read from +standard in as a newline-delimited list instead of from the arguments. + -When `--cone` is provided, the `core.sparseCheckoutCone` setting is -also set, allowing for better performance with a limited set of -patterns (see 'CONE PATTERN SET' below). +When `--cone` is passed or `core.sparseCheckoutCone` is enabled, the +input list is considered a list of directories instead of +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. + -Use the `--[no-]sparse-index` option to toggle the use of the sparse -index format. This reduces the size of the index to be more closely -aligned with your sparse-checkout definition. This can have significant -performance advantages for commands such as `git status` or `git add`. -This feature is still experimental. Some commands might be slower with -a sparse index until they are properly integrated with the feature. +Use the `--[no-]sparse-index` option to use a sparse index (the +default is to not use it). A sparse index reduces the size of the +index to be more closely aligned with your sparse-checkout +definition. This can have significant performance advantages for +commands such as `git status` or `git add`. This feature is still +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 that is not completely understood by external tools. If you have trouble@@ -60,23 +67,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 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':: Update the sparse-checkout file to include additional patterns. By default, these patterns are read from the command-line arguments,@@ -96,9 +86,27 @@ C-style quoted strings. 'disable':: Disable the `core.sparseCheckout` config setting, and restore the - working directory to include all files. Leaves the sparse-checkout - file intact so a later 'git sparse-checkout init' command may - return the working directory to the same state. + working directory to include all files. + +'init':: + Deprecated command that behaves like `set` with no specified paths.
Documentation/git-sparse-checkout.txt C-style quoted strings. · line 102
Quoted 10 lines
Documentation/git-sparse-checkout.txt +10
-0+ May be removed in the future. ++ +Historically, `set` did not used to 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. ++
Super nit: Perhaps update 'set did not used to handle' to 'set did not handle'.
Quoted 24 lines
Documentation/git-sparse-checkout.txt +9
-4+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 ---------------@@ -117,10 +125,8 @@ directory, it updates the skip-worktree bits in the index based on this file. The files matching the patterns in the file will appear in the working directory, and the rest will not. -To enable the sparse-checkout feature, run `git sparse-checkout init` to -initialize a simple sparse-checkout file and enable the `core.sparseCheckout` -config setting. Then, run `git sparse-checkout set` to modify the patterns in -the sparse-checkout file. +To enable the sparse-checkout feature, run `git sparse-checkout set` to +set the patterns you want to use. To repopulate the working directory with all files, use the `git sparse-checkout disable` command.
Re: [PATCH 4/6] git-sparse-checkout.txt: update to document that set handles init
Quoted 4 lines · Lessley Dennington
Quoted 2 lines · Elijah Newren via GitGitGadget
From: Elijah Newren <[email protected]>
...
Quoted 11 lines
Documentation/git-sparse-checkout.txt C-style quoted strings. · line 102
Quoted 9 lines
++
Documentation/git-sparse-checkout.txt +8
-0+Historically, `set` did not used to 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. ++Super nit: Perhaps update '
setdid not used to handle' to 'setdid not handle'.
Yeah, that sounds better. I'll wait a bit longer for other comments, then send a fix for this along with any other needed fixes (even if just included Acks & Reviewed-bys I get). Thanks!
Re: [PATCH 4/6] git-sparse-checkout.txt: update to document that set handles init
Quoted 19 lines · Elijah Newren
Quoted 4 lines · Lessley Dennington
Quoted 2 lines · Elijah Newren via GitGitGadget
From: Elijah Newren <[email protected]>
...
Quoted 11 lines
Documentation/git-sparse-checkout.txt C-style quoted strings. · line 102
Quoted 9 lines
++
Documentation/git-sparse-checkout.txt +8
-0+Historically, `set` did not used to 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. ++Super nit: Perhaps update '
setdid not used to handle' to 'setdid not handle'.
Quoted 4 lines
Yeah, that sounds better. I'll wait a bit longer for other comments, then send a fix for this along with any other needed fixes (even if just included Acks & Reviewed-bys I get). Thanks!
Sounds good. Also apologies that I didn't add this to v2 - my Thunderbird client hadn't loaded those messages at the time I sent my feedback.
PATCH 5/6 Documentation: clarify/correct a few sparsity related statements
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
--- Documentation/git-clone.txt | 8 ++++---- Documentation/git-sparse-checkout.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
Documentation/git-clone.txt +4 -4
@@ -167,10 +167,10 @@ objects from the source repository into a pack in the cloned repository. configuration variables are created. --sparse:: - Initialize the sparse-checkout file so the working - directory starts with only the files in the root - of the repository. The sparse-checkout file can be - modified to grow the working directory as needed. + Employ a sparse-checkout, with only files in the toplevel + directory initially being present. The + linkgit:git-sparse-checkout[1] command can be used to grow the + working directory as needed. --filter=<filter-spec>:: Use the partial clone feature and request that the server sends
Documentation/git-sparse-checkout.txt +1 -1
@@ -115,7 +115,7 @@ SPARSE CHECKOUT 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 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 files, but only a few are important to the current user.
Signature · 1 line
gitgitgadget
PATCH 6/6 clone: avoid using deprecated `sparse-checkout init`
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
The previous commits marked sparse-checkout init as deprecated; we can just use set instead here and pass it no paths.
--- builtin/clone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
builtin/clone.c +1 -1
@@ -633,7 +633,7 @@ static int git_sparse_checkout_init(const char *repo) {struct strvec argv =STRVEC_INIT ;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
Signature · 1 line
gitgitgadget
Quoted 9 lines · Elijah Newren via GitGitGadget
As described at [1], the split of init and set subcommands in sparse-checkout causes multiple issues:
* Poor performance (deleting all tracked files, then later restoring many and maybe even most of them)
* Poor UI (multiple progress bars in wrappers that hide both commands under 1 user-facing command)
* Loss of ignored files under directories the user wanted to keep
Quoted 8 lines
This series fixes this bug by providing a single command to switch to a
sparse-checkout: set. It does so by making set able to do the combined work of init and set. It keeps init as-is to give folks time to adapt, but marks it as deprecated.A quick overview:
* Patches 1-2: small preparatory refactorings
These were easy to read and obviously improvements. They make the later work easier, too.
Quoted 1 line
* Patch 3: the crux of the series
Victoria and I had some thoughts that might improve this patch, but it is high quality without them.
Quoted 4 lines
* Patches 4-5: documentation modifications (Patch 4 is worth reviewing; it marks init as deprecated -- are others okay with that?)
* Patch 6: trivial modification of git clone --sparse to use git sparse-checkout set rather than git sparse-checkout init.
These are good immediate follow-ups. I notice you left out the "--sparse implies --cone" change, and I think that is wise to leave for an independent series.
Thanks,
-Stolee
v2 cover sparse-checkout: make set subsume init
In reply to Elijah Newren via GitGitGadgetAs described at [1], the split of init and set subcommands in sparse-checkout causes multiple issues:
* Poor performance (deleting all tracked files, then later restoring many and maybe even most of them)
* Poor UI (multiple progress bars in wrappers that hide both commands under 1 user-facing command)
* Loss of ignored files under directories the user wanted to keep
This series fixes this bug by providing a single command to switch to a
sparse-checkout: set. It does so by making set able to do the combined work of init and set. It keeps init as-is to give folks time to adapt, but marks it as deprecated. It also makes reapply able to toggle cone/non-cone mode and sparse-index/non-sparse-index mode.
Changes since v1:
* Inserted new patches 3 & 4 as additional preparatory cleanups
* Took the new mode-toggling work code in sparse_checkout_set from the previous series and moved it into a new function, as a preparatory patch, and made it usable by init/set/reapply
* Also updated reapply to allow mode-toggling
* Updated the documentation as per above
* Various other small items from review comments
A quick overview:
* Patches 1-4: small preparatory refactorings
* Patch 5: patch adding new function for toggling {cone,sparse-checkout} modes
* Patch 6: the crux of the series; make set able to handle both init and set options
* Patch 7: make reapply also able to do mode toggling
* Patches 8-9: documentation modifications (Patch 4 is worth reviewing; it marks init as deprecated -- are others okay with that?)
* Patch 10: trivial modification of git clone --sparse to use git sparse-checkout set rather than git sparse-checkout init.
[1]
https://lore.kernel.org/git/CABPp-BE8TJ8QGAQWsSGT7S+9Xp-XmApcC9PSw3K=RQOP0rt+PQ@mail.gmail.com/
Elijah Newren (10):
sparse-checkout: pass use_stdin as a parameter instead of as a global
sparse-checkout: break apart functions for sparse_checkout_(set|add)
sparse-checkout: add sanity-checks on initial sparsity state
sparse-checkout: disallow --no-stdin as an argument to set
sparse-checkout: split out code for tweaking settings config
sparse-checkout: enable set to initialize sparse-checkout mode
sparse-checkout: enable reapply to take --[no-]{cone,sparse-index} git-sparse-checkout.txt: update to document init/set/reapply changes
Documentation: clarify/correct a few sparsity related statements
clone: avoid using deprecated sparse-checkout init
Documentation/git-clone.txt | 8 +- Documentation/git-sparse-checkout.txt | 100 +++++++------ builtin/clone.c | 2 +- builtin/sparse-checkout.c | 196 ++++++++++++++++++++------ t/t1091-sparse-checkout-builtin.sh | 10 +- 5 files changed, 219 insertions(+), 97 deletions(-)
base-commit: abe6bb3905392d5eb6b01fa6e54d7e784e0522aa
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1151%2Fnewren%2Fsparse-checkout-no-init-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1151/newren/sparse-checkout-no-init-v2
Pull-Request: https://github.com/git/git/pull/1151
Range-diff vs v1:
1: e41cfe3c1bb = 1: e41cfe3c1bb sparse-checkout: pass use_stdin as a parameter instead of as a global
2: 6f7de8f5412 = 2: 6f7de8f5412 sparse-checkout: break apart functions for sparse_checkout_(set|add)
-: ----------- > 3: bade5e52390 sparse-checkout: add sanity-checks on initial sparsity state
-: ----------- > 4: 0180bfc4a93 sparse-checkout: disallow --no-stdin as an argument to set
-: ----------- > 5: 3f5255eeef9 sparse-checkout: split out code for tweaking settings config
3: a90687eb4c1 ! 6: 3c640f5bcef sparse-checkout: enable `set` to initialize sparse-checkout mode
@@ builtin/sparse-checkout.c: static int sparse_checkout_add(int argc, const char *
static char const * const builtin_sparse_checkout_set_usage[] = {
- N_("git sparse-checkout set (--stdin | <patterns>)"),
-+ N_("git sparse-checkout set [--cone] [--[no-]sparse-index] (--stdin | <patterns>)"),
++ N_("git sparse-checkout set [--[no-]cone] [--[no-]sparse-index] (--stdin | <patterns>)"),
NULL
};
@@ builtin/sparse-checkout.c: static int sparse_checkout_add(int argc, const char *
static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
{
-+ int mode, record_mode;
-+ const char *default_patterns[] = {"/*", "!/*/"};
++ 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(0, "stdin", &set_opts.use_stdin,
- N_("read patterns from standard in")),
- OPT_END(),
+ OPT_BOOL_F(0, "stdin", &set_opts.use_stdin,
+ N_("read patterns from standard in"),
+ PARSE_OPT_NONEG),
@@ builtin/sparse-checkout.c: static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
repo_read_index(the_repository);
@@ builtin/sparse-checkout.c: static int sparse_checkout_set(int argc, const char *
builtin_sparse_checkout_set_usage,
PARSE_OPT_KEEP_UNKNOWN);
-+ /* Determine if we need to record the mode; ensure sparse checkout on */
-+ record_mode = (set_opts.cone_mode != -1) || !core_apply_sparse_checkout;
-+ core_apply_sparse_checkout = 1;
-+
-+ /* If not specified, use previous definition of cone mode */
-+ if (set_opts.cone_mode == -1 && core_apply_sparse_checkout)
-+ set_opts.cone_mode = core_sparse_checkout_cone;
-+
-+ /* Set cone/non-cone mode appropriately */
-+ if (set_opts.cone_mode == 1) {
-+ mode = MODE_CONE_PATTERNS;
-+ core_sparse_checkout_cone = 1;
-+ } else {
-+ mode = MODE_ALL_PATTERNS;
-+ }
-+ if (record_mode && set_config(mode))
++ if (update_modes(&set_opts.cone_mode, &set_opts.sparse_index))
+ return 1;
+
-+ /* Set sparse-index/non-sparse-index mode if specified */
-+ if (set_opts.sparse_index >= 0) {
-+ if (set_sparse_index_config(the_repository, set_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;
-+ }
-+
+ /*
+ * Cone mode automatically specifies the toplevel directory. For
+ * non-cone mode, if nothing is specified, manually select just the
@@ builtin/sparse-checkout.c: static int sparse_checkout_set(int argc, const char *
+ */
+ if (!core_sparse_checkout_cone && argc == 0) {
+ argv = default_patterns;
-+ argc = 2;
++ argc = default_patterns_nr;
+ }
+
return modify_pattern_list(argc, argv, set_opts.use_stdin, REPLACE);
-: ----------- > 7: acb10889a1f sparse-checkout: enable reapply to take --[no-]{cone,sparse-index}
4: 95d3df78b2f ! 8: 17b033caf4b git-sparse-checkout.txt: update to document that set handles init @@ Metadata
Author: Elijah Newren <[email protected]>
## Commit message ##
- git-sparse-checkout.txt: update to document that set handles init
+ git-sparse-checkout.txt: update to document init/set/reapply changes
As noted in the previous commit, using separate init and set steps
- with sparse-checkout result in a number of issues. The previous commit
- made set able to handle the work of both commands. Update the
- documentation to reflect this, and mark init as deprecated.
+ with sparse-checkout result in a number of issues. The previous commits
+ made set able to handle the work of both commands, and enabled reapply
+ to tweak the {cone,sparse-index} settings. Update the documentation to
+ reflect this, and mark init as deprecated.
@@ Documentation/git-sparse-checkout.txt: COMMANDS
+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.
++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 -index format. This reduces the size of the index to be more closely
@@ Documentation/git-sparse-checkout.txt: to rewrite your index to not be sparse. O
Update the sparse-checkout file to include additional patterns.
By default, these patterns are read from the command-line arguments,
@@ Documentation/git-sparse-checkout.txt: C-style quoted strings.
+ cases, it can make sense to run git sparse-checkout reapply later
+ after cleaning up affected paths (e.g. resolving conflicts, undoing
+ 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 the core.sparseCheckout config setting, and restore the
5: 9d455f1fb51 = 9: 922a65b4019 Documentation: clarify/correct a few sparsity related statements 6: 2ad404874ee = 10: d47b2c88242 clone: avoid using deprecated `sparse-checkout init`
Signature · 1 line
gitgitgadget
PATCH v2 1/10 sparse-checkout: pass use_stdin as a parameter instead of as a global
From: Elijah Newren <[email protected]>
add_patterns_from_input() has relied on a global variable, set_opts.use_stdin, which has been used by both the set and add subcommands of sparse-checkout. Once we introduce an add_opts.use_stdin, the hardcoding of set_opts.use_stdin will be incorrect. Pass the value as function parameter instead to allow us to make subsequent changes.
--- builtin/sparse-checkout.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
builtin/sparse-checkout.c +16 -12
@@ -525,7 +525,8 @@ static struct sparse_checkout_set_opts { } set_opts;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;if (core_sparse_checkout_cone) {
@@ -535,7 +536,7 @@ static void add_patterns_from_input(struct pattern_list *pl,hashmap_init (&pl->parent_hashmap, pl_hashmap_cmp,NULL ,0 ); pl->use_cone_patterns =1 ; -if (set_opts.use_stdin) { +if (use_stdin) {struct strbuf unquoted =STRBUF_INIT ;while (!strbuf_getline (&line, stdin)) {if (line.buf[0 ] =='"' ) {
@@ -559,7 +560,7 @@ static void add_patterns_from_input(struct pattern_list *pl, } } }else { -if (set_opts.use_stdin) { +if (use_stdin) {struct strbuf line =STRBUF_INIT ;while (!strbuf_getline (&line, stdin)) {
@@ -580,7 +581,8 @@ enum modify_type { };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 pattern_entry *pe;
@@ -588,7 +590,7 @@ static void add_patterns_cone_mode(int argc, const char **argv,struct pattern_list existing;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)); existing.use_cone_patterns = core_sparse_checkout_cone;
@@ -614,17 +616,19 @@ static void add_patterns_cone_mode(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 ();if (add_patterns_from_file_to_list (sparse_filename,"" ,0 , pl,NULL ,0 ))die (_ ("unable to load existing sparse-checkout patterns" ));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 changed_config =0 ;
@@ -633,13 +637,13 @@ static int modify_pattern_list(int argc, const char **argv, enum modify_type m)switch (m) {case ADD :if (core_sparse_checkout_cone) -add_patterns_cone_mode (argc, argv, pl); +add_patterns_cone_mode (argc, argv, pl, use_stdin);else -add_patterns_literal (argc, argv, pl); +add_patterns_literal (argc, argv, pl, use_stdin);break ;case REPLACE : -add_patterns_from_input (pl, argc, argv); +add_patterns_from_input (pl, argc, argv, use_stdin);break ; }
@@ -675,7 +679,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix, builtin_sparse_checkout_set_usage, PARSE_OPT_KEEP_UNKNOWN); -return modify_pattern_list (argc, argv, m); +return modify_pattern_list (argc, argv, set_opts.use_stdin, m); }static char const *const builtin_sparse_checkout_reapply_usage[] = {
Signature · 1 line
gitgitgadget
PATCH v2 2/10 sparse-checkout: break apart functions for sparse_checkout_(set|add)
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
sparse_checkout_set() was reused by sparse_checkout_add() with the only difference being a single parameter being passed to that function. However, we would like sparse_checkout_set() to do the same work that sparse_checkout_init() does if sparse checkouts are not already enabled. To facilitate this transition, give each mode their own copy of the function. This does not introduce any behavioral changes; that will come in a subsequent patch.
--- builtin/sparse-checkout.c | 54 +++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 14 deletions(-)
builtin/sparse-checkout.c +40 -14
@@ -515,15 +515,6 @@ static void strbuf_to_cone_pattern(struct strbuf *line, struct pattern_list *pl)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,int argc,const char **argv,int use_stdin)
@@ -663,8 +654,43 @@ static int modify_pattern_list(int argc, const char **argv, int use_stdin,return result; } -static int sparse_checkout_set(int argc, const char **argv, const char *prefix, - enum modify_type m) +static char const *const builtin_sparse_checkout_add_usage[] = { +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_add_options[] = { +OPT_BOOL (0 ,"stdin" , &add_opts.use_stdin, +N_ ("read patterns from standard in" )), +OPT_END (), + }; + +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 (--stdin | <patterns>)" ), +NULL +}; + +static struct sparse_checkout_set_opts { +int use_stdin; +} set_opts; + +static int sparse_checkout_set(int argc, const char **argv, const char *prefix) { static struct option builtin_sparse_checkout_set_options[] = { OPT_BOOL(0, "stdin", &set_opts.use_stdin,
@@ -679,7 +705,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix, builtin_sparse_checkout_set_usage, PARSE_OPT_KEEP_UNKNOWN); -return modify_pattern_list (argc, argv, set_opts.use_stdin, m); +return modify_pattern_list (argc, argv, set_opts.use_stdin,REPLACE ); }static char const *const builtin_sparse_checkout_reapply_usage[] = {
@@ -762,9 +788,9 @@ int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)if (!strcmp (argv[0 ],"init" ))return sparse_checkout_init (argc, argv);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" )) -return sparse_checkout_set (argc, argv, prefix,ADD ); +return sparse_checkout_add (argc, argv, prefix);if (!strcmp (argv[0 ],"reapply" ))return sparse_checkout_reapply (argc, argv);if (!strcmp (argv[0 ],"disable" ))
Signature · 1 line
gitgitgadget
PATCH v2 3/10 sparse-checkout: add sanity-checks on initial sparsity state
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
Most sparse-checkout subcommands (list, add, reapply, disable) only make sense when already in a sparse state. Add a quick check that will error out early if this is not the case.
--- builtin/sparse-checkout.c | 12 ++++++++++++ t/t1091-sparse-checkout-builtin.sh | 10 +++++++++- 2 files changed, 21 insertions(+), 1 deletion(-)
builtin/sparse-checkout.c +12 -0
@@ -56,6 +56,9 @@ static int sparse_checkout_list(int argc, const char **argv)char *sparse_filename;int res; +if (!core_apply_sparse_checkout) +die (_ ("this worktree is not sparse" )); + argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_list_options, builtin_sparse_checkout_list_usage,0 );
@@ -671,6 +674,9 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) OPT_END(), }; +if (!core_apply_sparse_checkout) +die (_ ("no sparse-checkout to add to" )); +repo_read_index (the_repository); argc = parse_options(argc, argv, prefix,
@@ -719,6 +725,9 @@ static int sparse_checkout_reapply(int argc, const char **argv) OPT_END(), }; +if (!core_apply_sparse_checkout) +die (_ ("must be in a sparse-checkout to reapply sparsity patterns" )); + argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_reapply_options, builtin_sparse_checkout_reapply_usage,0 );
@@ -740,6 +749,9 @@ static int sparse_checkout_disable(int argc, const char **argv)struct pattern_list pl;struct strbuf match_all =STRBUF_INIT ; +if (!core_apply_sparse_checkout) +die (_ ("no active sparse-checkout to disable" )); + argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_disable_options, builtin_sparse_checkout_disable_usage,0 );
t/t1091-sparse-checkout-builtin.sh +9 -1
@@ -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 && test_must_be_empty list && test_i18ngrep "this worktree is not sparse (sparse-checkout file may not exist)" err
Signature · 1 line
gitgitgadget
PATCH v2 4/10 sparse-checkout: disallow --no-stdin as an argument to set
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
We intentionally added --stdin as an option to sparse-checkout set, but didn't intend for --no-stdin to be permitted as well.
--- builtin/sparse-checkout.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
builtin/sparse-checkout.c +3 -2
@@ -699,8 +699,9 @@ static struct sparse_checkout_set_opts {static int sparse_checkout_set (int argc,const char **argv,const char *prefix) {static struct option builtin_sparse_checkout_set_options[] = { -OPT_BOOL (0 ,"stdin" , &set_opts.use_stdin, -N_ ("read patterns from standard in" )), +OPT_BOOL_F (0 ,"stdin" , &set_opts.use_stdin, +N_ ("read patterns from standard in" ), +PARSE_OPT_NONEG ),OPT_END (), };
Signature · 1 line
gitgitgadget
PATCH v2 5/10 sparse-checkout: split out code for tweaking settings config
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
init has some code for handling updates to either cone mode or the sparse-index setting. We would like to be able to reuse this elsewhere, namely in set and reapply. Split this function out, and make it slightly more general so it can handle being called from the new callers.
--- builtin/sparse-checkout.c | 56 ++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 19 deletions(-)
builtin/sparse-checkout.c +37 -19
@@ -383,6 +383,41 @@ static int set_config(enum sparse_checkout_mode mode)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[] = {N_ ("git sparse-checkout init [--cone] [--[no-]sparse-index]" ),NULL
@@ -399,7 +434,6 @@ static int sparse_checkout_init(int argc, const char **argv)char *sparse_filename;int res;struct object_id oid; -int mode;struct strbuf pattern =STRBUF_INIT ;static struct option builtin_sparse_checkout_init_options[] = {
@@ -412,19 +446,14 @@ static int sparse_checkout_init(int argc, const char **argv)repo_read_index (the_repository); + init_opts.cone_mode =-1 ; init_opts.sparse_index =-1 ; argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_init_options, builtin_sparse_checkout_init_usage,0 ); -if (init_opts.cone_mode) { - mode =MODE_CONE_PATTERNS ; - core_sparse_checkout_cone =1 ; - }else - mode =MODE_ALL_PATTERNS ; - -if (set_config (mode)) +if (update_modes (&init_opts.cone_mode, &init_opts.sparse_index))return 1 ;memset (&pl,0 ,sizeof (pl));
@@ -432,17 +461,6 @@ static int sparse_checkout_init(int argc, const char **argv) sparse_filename =get_sparse_checkout_filename (); 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 (res >=0 ) {free (sparse_filename);
Signature · 1 line
gitgitgadget
PATCH v2 6/10 sparse-checkout: enable `set` to initialize sparse-checkout mode
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
The previously suggested workflow:
git sparse-checkout init ...
git sparse-checkout set ...
Suffered from three problems:
1) It would delete nearly all files in the first step, then restore them in the second. That was poor performance and forced unnecessary rebuilds.
2) The two-step process resulted in two progress bars, which was suboptimal from a UI point of view for wrappers that invoked both of these commands but only exposed a single command to their end users.
3) With cone mode, the first step would delete nearly all ignored files everywhere, because everything was considered to be outside of the specified sparsity paths. (The user was not allowed to specify any sparsity paths in the init step.)
Avoid these problems by teaching set to understand the extra parameters that init takes and performing any necessary initialization if not already in a sparse checkout.
--- builtin/sparse-checkout.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
builtin/sparse-checkout.c +26 -1
@@ -706,17 +706,26 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) }static char const *const builtin_sparse_checkout_set_usage[] = { -N_ ("git sparse-checkout set (--stdin | <patterns>)" ), +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 ),
@@ -725,11 +734,27 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)repo_read_index (the_repository); + set_opts.cone_mode =-1 ; + set_opts.sparse_index =-1 ; + argc =parse_options (argc, argv, prefix, builtin_sparse_checkout_set_options, builtin_sparse_checkout_set_usage,PARSE_OPT_KEEP_UNKNOWN ); +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 ); }
Signature · 1 line
gitgitgadget
PATCH v2 7/10 sparse-checkout: enable reapply to take --[no-]{cone,sparse-index}
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
Folks may want to switch to or from cone mode, or to or from a sparse-index without changing their sparsity paths. Allow them to do so using the reapply command.
--- builtin/sparse-checkout.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
builtin/sparse-checkout.c +17 -1
@@ -759,13 +759,22 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix) }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 }; +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 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 (), };
@@ -777,6 +786,13 @@ static int sparse_checkout_reapply(int argc, const char **argv) 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 ; +return update_working_directory (NULL ); }
Signature · 1 line
gitgitgadget
PATCH v2 8/10 git-sparse-checkout.txt: update to document init/set/reapply changes
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
As noted in the previous commit, using separate init and set steps with sparse-checkout result in a number of issues. The previous commits made set able to handle the work of both commands, and enabled reapply to tweak the {cone,sparse-index} settings. Update the documentation to reflect this, and mark init as deprecated.
--- Documentation/git-sparse-checkout.txt | 98 +++++++++++++++------------ 1 file changed, 55 insertions(+), 43 deletions(-)
Documentation/git-sparse-checkout.txt +55 -43
@@ -30,28 +30,36 @@ COMMANDS 'list':: Describe the patterns in the sparse-checkout file. -'init':: - Enable the `core.sparseCheckout` setting. If the - sparse-checkout file does not exist, then populate it with - patterns that match every file in the root directory and - no other directories, then will remove all directories tracked - by Git. Add patterns to the sparse-checkout file to - repopulate the working directory. +'set':: + Enable the necessary config settings + (extensions.worktreeConfig, core.sparseCheckout, + core.sparseCheckoutCone) if they are not already enabled, and + write a set of patterns to the sparse-checkout file from the + list of arguments following the 'set' subcommand. Update the + working directory to match the new patterns. + -To avoid interfering with other worktrees, it first enables the -`extensions.worktreeConfig` setting and makes sure to set the -`core.sparseCheckout` setting in the worktree-specific config file. +When the `--stdin` option is provided, the patterns are read from +standard in as a newline-delimited list instead of from the arguments. + -When `--cone` is provided, the `core.sparseCheckoutCone` setting is -also set, allowing for better performance with a limited set of -patterns (see 'CONE PATTERN SET' below). +When `--cone` is passed or `core.sparseCheckoutCone` is enabled, the +input list is considered a list of directories instead of +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 -index format. This reduces the size of the index to be more closely -aligned with your sparse-checkout definition. This can have significant -performance advantages for commands such as `git status` or `git add`. -This feature is still experimental. Some commands might be slower with -a sparse index until they are properly integrated with the feature. +Use the `--[no-]sparse-index` option to use a sparse index (the +default is to not use it). A sparse index reduces the size of the +index to be more closely aligned with your sparse-checkout +definition. This can have significant performance advantages for +commands such as `git status` or `git add`. This feature is still +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 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 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':: Update the sparse-checkout file to include additional patterns. 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 after cleaning up affected paths (e.g. resolving conflicts, undoing 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 the `core.sparseCheckout` config setting, and restore the - working directory to include all files. Leaves the sparse-checkout - file intact so a later 'git sparse-checkout init' command may - return the working directory to the same state. + working directory to include all files. + +'init':: + Deprecated command that behaves like `set` with no specified paths. + May be removed in the future. ++ +Historically, `set` did not used to 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 ---------------
@@ -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 appear in the working directory, and the rest will not. -To enable the sparse-checkout feature, run `git sparse-checkout init` to -initialize a simple sparse-checkout file and enable the `core.sparseCheckout` -config setting. Then, run `git sparse-checkout set` to modify the patterns in -the sparse-checkout file. +To enable the sparse-checkout feature, run `git sparse-checkout set` to +set the patterns you want to use. To repopulate the working directory with all files, use the `git sparse-checkout disable` command.
Signature · 1 line
gitgitgadget
PATCH v2 9/10 Documentation: clarify/correct a few sparsity related statements
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
--- Documentation/git-clone.txt | 8 ++++---- Documentation/git-sparse-checkout.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
Documentation/git-clone.txt +4 -4
@@ -167,10 +167,10 @@ objects from the source repository into a pack in the cloned repository. configuration variables are created. --sparse:: - Initialize the sparse-checkout file so the working - directory starts with only the files in the root - of the repository. The sparse-checkout file can be - modified to grow the working directory as needed. + Employ a sparse-checkout, with only files in the toplevel + directory initially being present. The + linkgit:git-sparse-checkout[1] command can be used to grow the + working directory as needed. --filter=<filter-spec>:: Use the partial clone feature and request that the server sends
Documentation/git-sparse-checkout.txt +1 -1
@@ -121,7 +121,7 @@ SPARSE CHECKOUT 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 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 files, but only a few are important to the current user.
Signature · 1 line
gitgitgadget
PATCH v2 10/10 clone: avoid using deprecated `sparse-checkout init`
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
The previous commits marked sparse-checkout init as deprecated; we can just use set instead here and pass it no paths.
--- builtin/clone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
builtin/clone.c +1 -1
@@ -633,7 +633,7 @@ static int git_sparse_checkout_init(const char *repo) {struct strvec argv =STRVEC_INIT ;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
Signature · 1 line
gitgitgadget
Quoted 17 lines · Elijah Newren via GitGitGadget
As described at [1], the split of init and set subcommands in sparse-checkout causes multiple issues:
* Poor performance (deleting all tracked files, then later restoring many and maybe even most of them)
* Poor UI (multiple progress bars in wrappers that hide both commands under 1 user-facing command)
* Loss of ignored files under directories the user wanted to keepThis series fixes this bug by providing a single command to switch to a
sparse-checkout: set. It does so by making set able to do the combined work of init and set. It keeps init as-is to give folks time to adapt, but marks it as deprecated. It also makes reapply able to toggle cone/non-cone mode and sparse-index/non-sparse-index mode.Changes since v1:
Quoted 7 lines
* Inserted new patches 3 & 4 as additional preparatory cleanups
* Took the new mode-toggling work code insparse_checkout_setfrom the previous series and moved it into a new function, as a preparatory patch, and made it usable byinit/set/reapply
* Also updated reapply to allow mode-toggling
* Updated the documentation as per above
* Various other small items from review comments
I reread this series and the new patch organization is an improvement! I found this to be an easy read and have no suggestions for changes.
Thanks,
-Stolee
Quoted 194 lines · Elijah Newren via GitGitGadget
As described at [1], the split of init and set subcommands in sparse-checkout causes multiple issues:
* Poor performance (deleting all tracked files, then later restoring many and maybe even most of them)
* Poor UI (multiple progress bars in wrappers that hide both commands under 1 user-facing command)
* Loss of ignored files under directories the user wanted to keepThis series fixes this bug by providing a single command to switch to a
sparse-checkout: set. It does so by making set able to do the combined work of init and set. It keeps init as-is to give folks time to adapt, but marks it as deprecated. It also makes reapply able to toggle cone/non-cone mode and sparse-index/non-sparse-index mode.Changes since v1:
* Inserted new patches 3 & 4 as additional preparatory cleanups
* Took the new mode-toggling work code insparse_checkout_setfrom the previous series and moved it into a new function, as a preparatory patch, and made it usable byinit/set/reapply
* Also updated reapply to allow mode-toggling
* Updated the documentation as per above
* Various other small items from review commentsA quick overview:
* Patches 1-4: small preparatory refactorings
* Patch 5: patch adding new function for toggling {cone,sparse-checkout} modes
* Patch 6: the crux of the series; make set able to handle both init and set options
* Patch 7: make reapply also able to do mode toggling
* Patches 8-9: documentation modifications (Patch 4 is worth reviewing; it marks init as deprecated -- are others okay with that?)
* Patch 10: trivial modification of git clone --sparse to use git sparse-checkout set rather than git sparse-checkout init.[1]
https://lore.kernel.org/git/CABPp-BE8TJ8QGAQWsSGT7S+9Xp-XmApcC9PSw3K=RQOP0rt+PQ@mail.gmail.com/Elijah Newren (10):
sparse-checkout: passuse_stdinas a parameter instead of as a global
sparse-checkout: break apart functions forsparse_checkout_(set|add)
sparse-checkout: add sanity-checks on initial sparsity state
sparse-checkout: disallow --no-stdin as an argument to set
sparse-checkout: split out code for tweaking settings config
sparse-checkout: enablesetto initialize sparse-checkout mode
sparse-checkout: enable reapply to take --[no-]{cone,sparse-index} git-sparse-checkout.txt: update to documentinit/set/reapplychanges
Documentation: clarify/correct a few sparsity related statements
clone: avoid using deprecatedsparse-checkout initDocumentation/git-clone.txt | 8 +- Documentation/git-sparse-checkout.txt | 100 +++++++------ builtin/clone.c | 2 +- builtin/sparse-checkout.c | 196 ++++++++++++++++++++------ t/t1091-sparse-checkout-builtin.sh | 10 +- 5 files changed, 219 insertions(+), 97 deletions(-)base-commit:
abe6bb3905392d5eb6b01fa6e54d7e784e0522aa
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1151%2Fnewren%2Fsparse-checkout-no-init-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1151/newren/sparse-checkout-no-init-v2
Pull-Request: https://github.com/git/git/pull/1151Range-diff vs v1:
1: e41cfe3c1bb = 1: e41cfe3c1bb sparse-checkout: pass use_stdin as a parameter instead of as a global 2: 6f7de8f5412 = 2: 6f7de8f5412 sparse-checkout: break apart functions for sparse_checkout_(set|add) -: ----------- > 3: bade5e52390 sparse-checkout: add sanity-checks on initial sparsity state -: ----------- > 4: 0180bfc4a93 sparse-checkout: disallow --no-stdin as an argument to set -: ----------- > 5: 3f5255eeef9 sparse-checkout: split out code for tweaking settings config 3: a90687eb4c1 ! 6: 3c640f5bcef sparse-checkout: enable `set` to initialize sparse-checkout mode @@ builtin/sparse-checkout.c: static int sparse_checkout_add(int argc, const char * static char const * const builtin_sparse_checkout_set_usage[] = { - N_("git sparse-checkout set (--stdin | <patterns>)"), -+ N_("git sparse-checkout set [--cone] [--[no-]sparse-index] (--stdin | <patterns>)"), ++ N_("git sparse-checkout set [--[no-]cone] [--[no-]sparse-index] (--stdin | <patterns>)"), NULL }; @@ builtin/sparse-checkout.c: static int sparse_checkout_add(int argc, const char * static int sparse_checkout_set(int argc, const char **argv, const char *prefix) { -+ int mode, record_mode; -+ const char *default_patterns[] = {"/*", "!/*/"}; ++ 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(0, "stdin", &set_opts.use_stdin, - N_("read patterns from standard in")), - OPT_END(), + OPT_BOOL_F(0, "stdin", &set_opts.use_stdin, + N_("read patterns from standard in"), + PARSE_OPT_NONEG), @@ builtin/sparse-checkout.c: static int sparse_checkout_set(int argc, const char **argv, const char *prefix) repo_read_index(the_repository); @@ builtin/sparse-checkout.c: static int sparse_checkout_set(int argc, const char * builtin_sparse_checkout_set_usage, PARSE_OPT_KEEP_UNKNOWN); -+ /* Determine if we need to record the mode; ensure sparse checkout on */ -+ record_mode = (set_opts.cone_mode != -1) || !core_apply_sparse_checkout; -+ core_apply_sparse_checkout = 1; -+ -+ /* If not specified, use previous definition of cone mode */ -+ if (set_opts.cone_mode == -1 && core_apply_sparse_checkout) -+ set_opts.cone_mode = core_sparse_checkout_cone; -+ -+ /* Set cone/non-cone mode appropriately */ -+ if (set_opts.cone_mode == 1) { -+ mode = MODE_CONE_PATTERNS; -+ core_sparse_checkout_cone = 1; -+ } else { -+ mode = MODE_ALL_PATTERNS; -+ } -+ if (record_mode && set_config(mode)) ++ if (update_modes(&set_opts.cone_mode, &set_opts.sparse_index)) + return 1; + -+ /* Set sparse-index/non-sparse-index mode if specified */ -+ if (set_opts.sparse_index >= 0) { -+ if (set_sparse_index_config(the_repository, set_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; -+ } -+ + /* + * Cone mode automatically specifies the toplevel directory. For + * non-cone mode, if nothing is specified, manually select just the @@ builtin/sparse-checkout.c: static int sparse_checkout_set(int argc, const char * + */ + if (!core_sparse_checkout_cone && argc == 0) { + argv = default_patterns; -+ argc = 2; ++ argc = default_patterns_nr; + } + return modify_pattern_list(argc, argv, set_opts.use_stdin, REPLACE); -: ----------- > 7: acb10889a1f sparse-checkout: enable reapply to take --[no-]{cone,sparse-index} 4: 95d3df78b2f ! 8: 17b033caf4b git-sparse-checkout.txt: update to document that set handles init@@ Metadata
Author: Elijah Newren <[email protected]>## Commit message ##
- git-sparse-checkout.txt: update to document that set handles init
+ git-sparse-checkout.txt: update to documentinit/set/reapplychangesAs noted in the previous commit, using separate
initandsetsteps
- with sparse-checkout result in a number of issues. The previous commit
- madesetable to handle the work of both commands. Update the
- documentation to reflect this, and markinitas deprecated.
+ with sparse-checkout result in a number of issues. The previous commits
+ madesetable to handle the work of both commands, and enabled reapply
+ to tweak the {cone,sparse-index} settings. Update the documentation to
+ reflect this, and markinitas deprecated.Signed-off-by Elijah Newren <[email protected]>@@
Documentation/git-sparse-checkout.txt: COMMANDS
+files that are siblings of ancestor directories. The input format +matches the output ofgit ls-tree --name-only. This includes +interpreting pathnames that begin with a double quote (") as C-style
-+quoted strings.
++quoted strings. This may become the default in the future; --no-cone ++can be passed to request non-cone mode.
+
-Use the--[no-]sparse-indexoption to toggle the use of the sparse -index format. This reduces the size of the index to be more closely
@@Documentation/git-sparse-checkout.txt: to rewrite your index to not be sparse. O
Update the sparse-checkout file to include additional patterns.
By default, these patterns are read from the command-line arguments,
@@Documentation/git-sparse-checkout.txt: C-style quoted strings.
+ cases, it can make sense to rungit sparse-checkout reapplylater
+ after cleaning up affected paths (e.g. resolving conflicts, undoing
+ or committing changes, etc.).
+++
++Thereapplycommand can also take--[no-]coneand--[no-]sparse-index++flags, with the same meaning as the flags from thesetcommand, in order ++to change which sparsity mode you are using without needing to also respecify ++all sparsity paths.
Quoted 5 lines
'disable'::
Disable thecore.sparseCheckoutconfig setting, and restore the5: 9d455f1fb51 = 9: 922a65b4019 Documentation: clarify/correct a few sparsity related statements 6: 2ad404874ee = 10: d47b2c88242 clone: avoid using deprecated `sparse-checkout init`
These updates all look good to me, and the series as a whole represents a huge improvement in the robustness & usability of git sparse-checkout.
Thanks!
v3 cover sparse-checkout: make set subsume init
In reply to Elijah Newren via GitGitGadgetAs described at [1], the split of init and set subcommands in sparse-checkout causes multiple issues:
* Poor performance (deleting all tracked files, then later restoring many and maybe even most of them)
* Poor UI (multiple progress bars in wrappers that hide both commands under 1 user-facing command)
* Loss of ignored files under directories the user wanted to keep
This series fixes this bug by providing a single command to switch to a
sparse-checkout: set. It does so by making set able to do the combined work of init and set. It keeps init as-is to give folks time to adapt, but marks it as deprecated. It also makes reapply able to toggle cone/non-cone mode and sparse-index/non-sparse-index mode.
Changes since v2:
* Small documentation wording improvement
* Added Reviewed-by's from Stolee and Victoria
Changes since v1:
* Inserted new patches 3 & 4 as additional preparatory cleanups
* Took the new mode-toggling work code in sparse_checkout_set from the previous series and moved it into a new function, as a preparatory patch, and made it usable by init/set/reapply
* Also updated reapply to allow mode-toggling
* Updated the documentation as per above
* Various other small items from review comments
A quick overview:
* Patches 1-4: small preparatory refactorings
* Patch 5: patch adding new function for toggling {cone,sparse-checkout} modes
* Patch 6: the crux of the series; make set able to handle both init and set options
* Patch 7: make reapply also able to do mode toggling
* Patches 8-9: documentation modifications (Patch 4 is worth reviewing; it marks init as deprecated -- are others okay with that?)
* Patch 10: trivial modification of git clone --sparse to use git sparse-checkout set rather than git sparse-checkout init.
[1]
https://lore.kernel.org/git/CABPp-BE8TJ8QGAQWsSGT7S+9Xp-XmApcC9PSw3K=RQOP0rt+PQ@mail.gmail.com/
Elijah Newren (10):
sparse-checkout: pass use_stdin as a parameter instead of as a global
sparse-checkout: break apart functions for sparse_checkout_(set|add)
sparse-checkout: add sanity-checks on initial sparsity state
sparse-checkout: disallow --no-stdin as an argument to set
sparse-checkout: split out code for tweaking settings config
sparse-checkout: enable set to initialize sparse-checkout mode
sparse-checkout: enable reapply to take --[no-]{cone,sparse-index} git-sparse-checkout.txt: update to document init/set/reapply changes
Documentation: clarify/correct a few sparsity related statements
clone: avoid using deprecated sparse-checkout init
Documentation/git-clone.txt | 8 +- Documentation/git-sparse-checkout.txt | 100 +++++++------ builtin/clone.c | 2 +- builtin/sparse-checkout.c | 196 ++++++++++++++++++++------ t/t1091-sparse-checkout-builtin.sh | 10 +- 5 files changed, 219 insertions(+), 97 deletions(-)
base-commit: abe6bb3905392d5eb6b01fa6e54d7e784e0522aa
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1151%2Fnewren%2Fsparse-checkout-no-init-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1151/newren/sparse-checkout-no-init-v3
Pull-Request: https://github.com/git/git/pull/1151
Range-diff vs v2:
1: e41cfe3c1bb ! 1: 814aed2d125 sparse-checkout: pass use_stdin as a parameter instead of as a global
@@ Commit message
incorrect. Pass the value as function parameter instead to allow us to
make subsequent changes.
+ Reviewed-by: Derrick Stolee <[email protected]>
+ Reviewed-by: Victoria Dye <[email protected]>
## builtin/sparse-checkout.c ##
2: 6f7de8f5412 ! 2: 04cd57592e9 sparse-checkout: break apart functions for sparse_checkout_(set|add)
@@ Commit message
function. This does not introduce any behavioral changes; that will
come in a subsequent patch.
+ Reviewed-by: Derrick Stolee <[email protected]>
+ Reviewed-by: Victoria Dye <[email protected]>
## builtin/sparse-checkout.c ##
3: bade5e52390 ! 3: f3af5edb25d sparse-checkout: add sanity-checks on initial sparsity state
@@ Commit message
only make sense when already in a sparse state. Add a quick check
that will error out early if this is not the case.
+ Reviewed-by: Derrick Stolee <[email protected]>
+ Reviewed-by: Victoria Dye <[email protected]>
## builtin/sparse-checkout.c ##
4: 0180bfc4a93 ! 4: 82a13cc0197 sparse-checkout: disallow --no-stdin as an argument to set
@@ Commit message
but didn't intend for --no-stdin to be permitted as well.
+ Reviewed-by: Derrick Stolee <[email protected]>
+ Reviewed-by: Victoria Dye <[email protected]>
## builtin/sparse-checkout.c ##
5: 3f5255eeef9 ! 5: 7a812e0222c sparse-checkout: split out code for tweaking settings config
@@ Commit message
and make it slightly more general so it can handle being called from the new callers.
+ Reviewed-by: Derrick Stolee <[email protected]>
+ Reviewed-by: Victoria Dye <[email protected]>
## builtin/sparse-checkout.c ##
6: 3c640f5bcef ! 6: 7167a4b3118 sparse-checkout: enable set to initialize sparse-checkout mode
@@ Commit message
parameters that init takes and performing any necessary initialization
if not already in a sparse checkout.
+ Reviewed-by: Derrick Stolee <[email protected]>
+ Reviewed-by: Victoria Dye <[email protected]>
## builtin/sparse-checkout.c ##
7: acb10889a1f ! 7: 3687637915f sparse-checkout: enable reapply to take --[no-]{cone,sparse-index}
@@ Commit message
sparse-index without changing their sparsity paths. Allow them to do so using the reapply command.
+ Reviewed-by: Derrick Stolee <[email protected]>
+ Reviewed-by: Victoria Dye <[email protected]>
## builtin/sparse-checkout.c ##
8: 17b033caf4b ! 8: 7483d1363e5 git-sparse-checkout.txt: update to document init/set/reapply changes
@@ Commit message
to tweak the {cone,sparse-index} settings. Update the documentation to reflect this, and mark init as deprecated.
+ Reviewed-by: Derrick Stolee <[email protected]>
+ Reviewed-by: Victoria Dye <[email protected]>
## Documentation/git-sparse-checkout.txt ##
@@ Documentation/git-sparse-checkout.txt: C-style quoted strings.
+ Deprecated command that behaves like set with no specified paths.
+ May be removed in the future.
++
-+Historically, set did not used to 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.
++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
9: 922a65b4019 ! 9: 11a45920602 Documentation: clarify/correct a few sparsity related statements
@@ Metadata
## Commit message ##
Documentation: clarify/correct a few sparsity related statements
+ Reviewed-by: Derrick Stolee <[email protected]>
+ Reviewed-by: Victoria Dye <[email protected]>
## Documentation/git-clone.txt ##
10: d47b2c88242 ! 10: 395d9b194d3 clone: avoid using deprecated sparse-checkout init
@@ Commit message
The previous commits marked sparse-checkout init as deprecated; we can just use set instead here and pass it no paths.
+ Reviewed-by: Derrick Stolee <[email protected]>
+ Reviewed-by: Victoria Dye <[email protected]>
## builtin/clone.c ##
Signature · 1 line
gitgitgadget
PATCH v3 1/10 sparse-checkout: pass use_stdin as a parameter instead of as a global
From: Elijah Newren <[email protected]>
add_patterns_from_input() has relied on a global variable, set_opts.use_stdin, which has been used by both the set and add subcommands of sparse-checkout. Once we introduce an add_opts.use_stdin, the hardcoding of set_opts.use_stdin will be incorrect. Pass the value as function parameter instead to allow us to make subsequent changes.
--- builtin/sparse-checkout.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
builtin/sparse-checkout.c +16 -12
@@ -525,7 +525,8 @@ static struct sparse_checkout_set_opts { } set_opts;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;if (core_sparse_checkout_cone) {
@@ -535,7 +536,7 @@ static void add_patterns_from_input(struct pattern_list *pl,hashmap_init (&pl->parent_hashmap, pl_hashmap_cmp,NULL ,0 ); pl->use_cone_patterns =1 ; -if (set_opts.use_stdin) { +if (use_stdin) {struct strbuf unquoted =STRBUF_INIT ;while (!strbuf_getline (&line, stdin)) {if (line.buf[0 ] =='"' ) {
@@ -559,7 +560,7 @@ static void add_patterns_from_input(struct pattern_list *pl, } } }else { -if (set_opts.use_stdin) { +if (use_stdin) {struct strbuf line =STRBUF_INIT ;while (!strbuf_getline (&line, stdin)) {
@@ -580,7 +581,8 @@ enum modify_type { };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 pattern_entry *pe;
@@ -588,7 +590,7 @@ static void add_patterns_cone_mode(int argc, const char **argv,struct pattern_list existing;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)); existing.use_cone_patterns = core_sparse_checkout_cone;
@@ -614,17 +616,19 @@ static void add_patterns_cone_mode(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 ();if (add_patterns_from_file_to_list (sparse_filename,"" ,0 , pl,NULL ,0 ))die (_ ("unable to load existing sparse-checkout patterns" ));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 changed_config =0 ;
@@ -633,13 +637,13 @@ static int modify_pattern_list(int argc, const char **argv, enum modify_type m)switch (m) {case ADD :if (core_sparse_checkout_cone) -add_patterns_cone_mode (argc, argv, pl); +add_patterns_cone_mode (argc, argv, pl, use_stdin);else -add_patterns_literal (argc, argv, pl); +add_patterns_literal (argc, argv, pl, use_stdin);break ;case REPLACE : -add_patterns_from_input (pl, argc, argv); +add_patterns_from_input (pl, argc, argv, use_stdin);break ; }
@@ -675,7 +679,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix, builtin_sparse_checkout_set_usage, PARSE_OPT_KEEP_UNKNOWN); -return modify_pattern_list (argc, argv, m); +return modify_pattern_list (argc, argv, set_opts.use_stdin, m); }static char const *const builtin_sparse_checkout_reapply_usage[] = {
Signature · 1 line
gitgitgadget
PATCH v3 2/10 sparse-checkout: break apart functions for sparse_checkout_(set|add)
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
sparse_checkout_set() was reused by sparse_checkout_add() with the only difference being a single parameter being passed to that function. However, we would like sparse_checkout_set() to do the same work that sparse_checkout_init() does if sparse checkouts are not already enabled. To facilitate this transition, give each mode their own copy of the function. This does not introduce any behavioral changes; that will come in a subsequent patch.
--- builtin/sparse-checkout.c | 54 +++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 14 deletions(-)
builtin/sparse-checkout.c +40 -14
@@ -515,15 +515,6 @@ static void strbuf_to_cone_pattern(struct strbuf *line, struct pattern_list *pl)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,int argc,const char **argv,int use_stdin)
@@ -663,8 +654,43 @@ static int modify_pattern_list(int argc, const char **argv, int use_stdin,return result; } -static int sparse_checkout_set(int argc, const char **argv, const char *prefix, - enum modify_type m) +static char const *const builtin_sparse_checkout_add_usage[] = { +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_add_options[] = { +OPT_BOOL (0 ,"stdin" , &add_opts.use_stdin, +N_ ("read patterns from standard in" )), +OPT_END (), + }; + +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 (--stdin | <patterns>)" ), +NULL +}; + +static struct sparse_checkout_set_opts { +int use_stdin; +} set_opts; + +static int sparse_checkout_set(int argc, const char **argv, const char *prefix) { static struct option builtin_sparse_checkout_set_options[] = { OPT_BOOL(0, "stdin", &set_opts.use_stdin,
@@ -679,7 +705,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix, builtin_sparse_checkout_set_usage, PARSE_OPT_KEEP_UNKNOWN); -return modify_pattern_list (argc, argv, set_opts.use_stdin, m); +return modify_pattern_list (argc, argv, set_opts.use_stdin,REPLACE ); }static char const *const builtin_sparse_checkout_reapply_usage[] = {
@@ -762,9 +788,9 @@ int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)if (!strcmp (argv[0 ],"init" ))return sparse_checkout_init (argc, argv);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" )) -return sparse_checkout_set (argc, argv, prefix,ADD ); +return sparse_checkout_add (argc, argv, prefix);if (!strcmp (argv[0 ],"reapply" ))return sparse_checkout_reapply (argc, argv);if (!strcmp (argv[0 ],"disable" ))
Signature · 1 line
gitgitgadget
PATCH v3 3/10 sparse-checkout: add sanity-checks on initial sparsity state
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
Most sparse-checkout subcommands (list, add, reapply, disable) only make sense when already in a sparse state. Add a quick check that will error out early if this is not the case.
--- builtin/sparse-checkout.c | 12 ++++++++++++ t/t1091-sparse-checkout-builtin.sh | 10 +++++++++- 2 files changed, 21 insertions(+), 1 deletion(-)
builtin/sparse-checkout.c +12 -0
@@ -56,6 +56,9 @@ static int sparse_checkout_list(int argc, const char **argv)char *sparse_filename;int res; +if (!core_apply_sparse_checkout) +die (_ ("this worktree is not sparse" )); + argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_list_options, builtin_sparse_checkout_list_usage,0 );
@@ -671,6 +674,9 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) OPT_END(), }; +if (!core_apply_sparse_checkout) +die (_ ("no sparse-checkout to add to" )); +repo_read_index (the_repository); argc = parse_options(argc, argv, prefix,
@@ -719,6 +725,9 @@ static int sparse_checkout_reapply(int argc, const char **argv) OPT_END(), }; +if (!core_apply_sparse_checkout) +die (_ ("must be in a sparse-checkout to reapply sparsity patterns" )); + argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_reapply_options, builtin_sparse_checkout_reapply_usage,0 );
@@ -740,6 +749,9 @@ static int sparse_checkout_disable(int argc, const char **argv)struct pattern_list pl;struct strbuf match_all =STRBUF_INIT ; +if (!core_apply_sparse_checkout) +die (_ ("no active sparse-checkout to disable" )); + argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_disable_options, builtin_sparse_checkout_disable_usage,0 );
t/t1091-sparse-checkout-builtin.sh +9 -1
@@ -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 && test_must_be_empty list && test_i18ngrep "this worktree is not sparse (sparse-checkout file may not exist)" err
Signature · 1 line
gitgitgadget
Re: [PATCH v3 03/10] sparse-checkout: add sanity-checks on initial sparsity state
Quoted 6 lines · Elijah Newren via GitGitGadget
From: Elijah Newren <[email protected]>
Most sparse-checkout subcommands (list, add, reapply, disable) only make sense when already in a sparse state. Add a quick check that will error out early if this is not the case.
Quoted 7 lines
Reviewed-by Derrick Stolee <[email protected]>Reviewed-by Victoria Dye <[email protected]>Signed-off-by Elijah Newren <[email protected]>--- builtin/sparse-checkout.c | 12 ++++++++++++ t/t1091-sparse-checkout-builtin.sh | 10 +++++++++- 2 files changed, 21 insertions(+), 1 deletion(-)
I won't complain too much but some looks a bit questionable to die on. For example, when asked to "please disable" something that is already disabled, I do not think the user's intention includes "if already disabled, please die"; rather it is "I want the end result to be in the disabled state", isn't it?
I think what is common among the ones that I find questionable to die is that they do not use end-user input from argv. "Please add X to sparsity patterns" may not make much sense when we are not already sparse", unlike "Please disable", for example.
Side note. I suspect that it can be argued that we might just auto-enable sparse state upon the first request to add something, but I personally feel that is dwimming too much, as behaviours of git in normal mode and sparse mode are so different.
So, for the same reason, I think "list" that shows "there is nothing" without an error, when sparse-checkout is not active, would also be perfectly defensible, and some people may find that dying a bit too much in such a situation.
Or does the system work differently between
(A) core_apply_sparse_checkout is true and the sparsity pattern list is empty, and
(B) sparse-checkout is not in effect at all.
If that is the case, please ignore all of the above.
Quoted 65 lines
builtin/sparse-checkout.c +12
-0@@ -56,6 +56,9 @@ static int sparse_checkout_list(int argc, const char **argv)char *sparse_filename;int res; +if (!core_apply_sparse_checkout) +die (_ ("this worktree is not sparse" )); + argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_list_options, builtin_sparse_checkout_list_usage,0 );@@ -671,6 +674,9 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) OPT_END(), }; +if (!core_apply_sparse_checkout) +die (_ ("no sparse-checkout to add to" )); +repo_read_index (the_repository); argc = parse_options(argc, argv, prefix,@@ -719,6 +725,9 @@ static int sparse_checkout_reapply(int argc, const char **argv) OPT_END(), }; +if (!core_apply_sparse_checkout) +die (_ ("must be in a sparse-checkout to reapply sparsity patterns" )); + argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_reapply_options, builtin_sparse_checkout_reapply_usage,0 );@@ -740,6 +749,9 @@ static int sparse_checkout_disable(int argc, const char **argv)struct pattern_list pl;struct strbuf match_all =STRBUF_INIT ; +if (!core_apply_sparse_checkout) +die (_ ("no active sparse-checkout to disable" )); + argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_disable_options, builtin_sparse_checkout_disable_usage,0 );t/t1091-sparse-checkout-builtin.sh +9
-1@@ -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 && test_must_be_empty list && test_i18ngrep "this worktree is not sparse (sparse-checkout file may not exist)" err
Re: [PATCH v3 03/10] sparse-checkout: add sanity-checks on initial sparsity state
Quoted 17 lines · Junio C Hamano
Quoted 6 lines · Elijah Newren via GitGitGadget
From: Elijah Newren <[email protected]>
Most sparse-checkout subcommands (list, add, reapply, disable) only make sense when already in a sparse state. Add a quick check that will error out early if this is not the case.
Quoted 7 lines
Reviewed-by Derrick Stolee <[email protected]>Reviewed-by Victoria Dye <[email protected]>Signed-off-by Elijah Newren <[email protected]>--- builtin/sparse-checkout.c | 12 ++++++++++++ t/t1091-sparse-checkout-builtin.sh | 10 +++++++++- 2 files changed, 21 insertions(+), 1 deletion(-)
Quoted 5 lines
I won't complain too much but some looks a bit questionable to die on. For example, when asked to "please disable" something that is already disabled, I do not think the user's intention includes "if already disabled, please die"; rather it is "I want the end result to be in the disabled state", isn't it?
Yeah, fair enough, I can change it to just print that it's already disabled.
However, I think add, list, and reapply should all die still.
Quoted 16 lines
I think what is common among the ones that I find questionable to die is that they do not use end-user input from argv. "Please add X to sparsity patterns" may not make much sense when we are not already sparse", unlike "Please disable", for example.
Side note. I suspect that it can be argued that we might just auto-enable sparse state upon the first request to add something, but I personally feel that is dwimming too much, as behaviours of git in normal mode and sparse mode are so different.
So, for the same reason, I think "list" that shows "there is nothing" without an error, when sparse-checkout is not active, would also be perfectly defensible, and some people may find that dying a bit too much in such a situation.
Quoted 4 lines
Or does the system work differently between
(A)
core_apply_sparse_checkoutis true and the sparsity pattern list is empty, and
You can get empty output from
git sparse-checkout list
after running
git sparse-checkout --cone
(cone mode, no paths specified)
In this state, only files immediately in the toplevel directory will be present; all subdirectories will be sparsified away.
(Granted, that's because cone mode by default gives you some pattern lists behind the scenes. If you actually delete all entries in .git/info/sparse-checkout and do a git sparse-checkout reapply, then you will have NO (tracked) files in your checkout; everything will be SKIP_WORKTREE.)
Quoted 1 line
(B) sparse-checkout is not in effect at all.
In this state, the tree is dense; all files are present.
Quoted 1 line
If that is the case, please ignore all of the above.
I think your comment about disable makes sense, though.
PATCH v3 4/10 sparse-checkout: disallow --no-stdin as an argument to set
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
We intentionally added --stdin as an option to sparse-checkout set, but didn't intend for --no-stdin to be permitted as well.
--- builtin/sparse-checkout.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
builtin/sparse-checkout.c +3 -2
@@ -699,8 +699,9 @@ static struct sparse_checkout_set_opts {static int sparse_checkout_set (int argc,const char **argv,const char *prefix) {static struct option builtin_sparse_checkout_set_options[] = { -OPT_BOOL (0 ,"stdin" , &set_opts.use_stdin, -N_ ("read patterns from standard in" )), +OPT_BOOL_F (0 ,"stdin" , &set_opts.use_stdin, +N_ ("read patterns from standard in" ), +PARSE_OPT_NONEG ),OPT_END (), };
Signature · 1 line
gitgitgadget
PATCH v3 5/10 sparse-checkout: split out code for tweaking settings config
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
init has some code for handling updates to either cone mode or the sparse-index setting. We would like to be able to reuse this elsewhere, namely in set and reapply. Split this function out, and make it slightly more general so it can handle being called from the new callers.
--- builtin/sparse-checkout.c | 56 ++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 19 deletions(-)
builtin/sparse-checkout.c +37 -19
@@ -383,6 +383,41 @@ static int set_config(enum sparse_checkout_mode mode)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[] = {N_ ("git sparse-checkout init [--cone] [--[no-]sparse-index]" ),NULL
@@ -399,7 +434,6 @@ static int sparse_checkout_init(int argc, const char **argv)char *sparse_filename;int res;struct object_id oid; -int mode;struct strbuf pattern =STRBUF_INIT ;static struct option builtin_sparse_checkout_init_options[] = {
@@ -412,19 +446,14 @@ static int sparse_checkout_init(int argc, const char **argv)repo_read_index (the_repository); + init_opts.cone_mode =-1 ; init_opts.sparse_index =-1 ; argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_init_options, builtin_sparse_checkout_init_usage,0 ); -if (init_opts.cone_mode) { - mode =MODE_CONE_PATTERNS ; - core_sparse_checkout_cone =1 ; - }else - mode =MODE_ALL_PATTERNS ; - -if (set_config (mode)) +if (update_modes (&init_opts.cone_mode, &init_opts.sparse_index))return 1 ;memset (&pl,0 ,sizeof (pl));
@@ -432,17 +461,6 @@ static int sparse_checkout_init(int argc, const char **argv) sparse_filename =get_sparse_checkout_filename (); 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 (res >=0 ) {free (sparse_filename);
Signature · 1 line
gitgitgadget
PATCH v3 6/10 sparse-checkout: enable `set` to initialize sparse-checkout mode
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
The previously suggested workflow:
git sparse-checkout init ...
git sparse-checkout set ...
Suffered from three problems:
1) It would delete nearly all files in the first step, then restore them in the second. That was poor performance and forced unnecessary rebuilds.
2) The two-step process resulted in two progress bars, which was suboptimal from a UI point of view for wrappers that invoked both of these commands but only exposed a single command to their end users.
3) With cone mode, the first step would delete nearly all ignored files everywhere, because everything was considered to be outside of the specified sparsity paths. (The user was not allowed to specify any sparsity paths in the init step.)
Avoid these problems by teaching set to understand the extra parameters that init takes and performing any necessary initialization if not already in a sparse checkout.
--- builtin/sparse-checkout.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
builtin/sparse-checkout.c +26 -1
@@ -706,17 +706,26 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) }static char const *const builtin_sparse_checkout_set_usage[] = { -N_ ("git sparse-checkout set (--stdin | <patterns>)" ), +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 ),
@@ -725,11 +734,27 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)repo_read_index (the_repository); + set_opts.cone_mode =-1 ; + set_opts.sparse_index =-1 ; + argc =parse_options (argc, argv, prefix, builtin_sparse_checkout_set_options, builtin_sparse_checkout_set_usage,PARSE_OPT_KEEP_UNKNOWN ); +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 ); }
Signature · 1 line
gitgitgadget
PATCH v3 7/10 sparse-checkout: enable reapply to take --[no-]{cone,sparse-index}
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
Folks may want to switch to or from cone mode, or to or from a sparse-index without changing their sparsity paths. Allow them to do so using the reapply command.
--- builtin/sparse-checkout.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
builtin/sparse-checkout.c +17 -1
@@ -759,13 +759,22 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix) }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 }; +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 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 (), };
@@ -777,6 +786,13 @@ static int sparse_checkout_reapply(int argc, const char **argv) 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 ; +return update_working_directory (NULL ); }
Signature · 1 line
gitgitgadget
Re: [PATCH v3 07/10] sparse-checkout: enable reapply to take --[no-]{cone,sparse-index}
Quoted 5 lines · Elijah Newren via GitGitGadget
From: Elijah Newren <[email protected]>
Folks may want to switch to or from cone mode, or to or from a sparse-index without changing their sparsity paths. Allow them to do so using the reapply command.
Interesting.
Are there certain pattern that would make sense only in one of the modes but not the other? If there isn't any such pattern, this feature perfectly makes sense, I would think.
If an existing pattern changes its meaning between the old mode and the new mode, that is very much fine---that is what the user wanted to achieve by switching between the modes with "reapply".
Thanks.
Quoted 48 lines
Reviewed-by Derrick Stolee <[email protected]>Reviewed-by Victoria Dye <[email protected]>Signed-off-by Elijah Newren <[email protected]>--- builtin/sparse-checkout.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)builtin/sparse-checkout.c +17
-1@@ -759,13 +759,22 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix) }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 }; +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 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 (), };@@ -777,6 +786,13 @@ static int sparse_checkout_reapply(int argc, const char **argv) 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 ; +return update_working_directory (NULL ); }
Re: [PATCH v3 07/10] sparse-checkout: enable reapply to take --[no-]{cone,sparse-index}
Quoted 9 lines · Junio C Hamano
Quoted 5 lines · Elijah Newren via GitGitGadget
From: Elijah Newren <[email protected]>
Folks may want to switch to or from cone mode, or to or from a sparse-index without changing their sparsity paths. Allow them to do so using the reapply command.
Quoted 5 lines
Interesting.
Are there certain pattern that would make sense only in one of the modes but not the other? If there isn't any such pattern, this feature perfectly makes sense, I would think.
Good question.
Valid cone mode patterns are a strict subset of the possible sparsity patterns. So, switching from cone to non-cone mode trivially makes sense. Understanding why switching in the other direction is okay takes a bit more understanding...
Stolee designed cone mode such that when it's active, and someone edits .git/info/sparse-checkout and adds patterns of their own (which users might do because that had been suggested for several years in the read-tree docs -- and still is), then the code will print a warning ("disabling cone pattern matching") and operate in non-cone mode. As such, the sparsity does not "break" when they switch modes if they have non-cone patterns; they'll just get warnings.
Further, we're making reapply consistent with init here. Stolee made init usable for switching modes in an active sparse-checkout (though it wasn't well documented, and it's slightly confusing to users who might worry that they'll lose their sparsity patterns by using init). We're just copying that ability from init over in reapply, and recommending using the latter rather than the former.
Quoted 5 lines
If an existing pattern changes its meaning between the old mode and the new mode, that is very much fine---that is what the user wanted to achieve by switching between the modes with "reapply".
Thanks.
PATCH v3 8/10 git-sparse-checkout.txt: update to document init/set/reapply changes
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
As noted in the previous commit, using separate init and set steps with sparse-checkout result in a number of issues. The previous commits made set able to handle the work of both commands, and enabled reapply to tweak the {cone,sparse-index} settings. Update the documentation to reflect this, and mark init as deprecated.
--- Documentation/git-sparse-checkout.txt | 98 +++++++++++++++------------ 1 file changed, 55 insertions(+), 43 deletions(-)
Documentation/git-sparse-checkout.txt +55 -43
@@ -30,28 +30,36 @@ COMMANDS 'list':: Describe the patterns in the sparse-checkout file. -'init':: - Enable the `core.sparseCheckout` setting. If the - sparse-checkout file does not exist, then populate it with - patterns that match every file in the root directory and - no other directories, then will remove all directories tracked - by Git. Add patterns to the sparse-checkout file to - repopulate the working directory. +'set':: + Enable the necessary config settings + (extensions.worktreeConfig, core.sparseCheckout, + core.sparseCheckoutCone) if they are not already enabled, and + write a set of patterns to the sparse-checkout file from the + list of arguments following the 'set' subcommand. Update the + working directory to match the new patterns. + -To avoid interfering with other worktrees, it first enables the -`extensions.worktreeConfig` setting and makes sure to set the -`core.sparseCheckout` setting in the worktree-specific config file. +When the `--stdin` option is provided, the patterns are read from +standard in as a newline-delimited list instead of from the arguments. + -When `--cone` is provided, the `core.sparseCheckoutCone` setting is -also set, allowing for better performance with a limited set of -patterns (see 'CONE PATTERN SET' below). +When `--cone` is passed or `core.sparseCheckoutCone` is enabled, the +input list is considered a list of directories instead of +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 -index format. This reduces the size of the index to be more closely -aligned with your sparse-checkout definition. This can have significant -performance advantages for commands such as `git status` or `git add`. -This feature is still experimental. Some commands might be slower with -a sparse index until they are properly integrated with the feature. +Use the `--[no-]sparse-index` option to use a sparse index (the +default is to not use it). A sparse index reduces the size of the +index to be more closely aligned with your sparse-checkout +definition. This can have significant performance advantages for +commands such as `git status` or `git add`. This feature is still +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 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 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':: Update the sparse-checkout file to include additional patterns. 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 after cleaning up affected paths (e.g. resolving conflicts, undoing 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 the `core.sparseCheckout` config setting, and restore the - working directory to include all files. Leaves the sparse-checkout - file intact so a later 'git sparse-checkout init' command may - return the working directory to the same state. + working directory to include all files. + +'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 ---------------
@@ -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 appear in the working directory, and the rest will not. -To enable the sparse-checkout feature, run `git sparse-checkout init` to -initialize a simple sparse-checkout file and enable the `core.sparseCheckout` -config setting. Then, run `git sparse-checkout set` to modify the patterns in -the sparse-checkout file. +To enable the sparse-checkout feature, run `git sparse-checkout set` to +set the patterns you want to use. To repopulate the working directory with all files, use the `git sparse-checkout disable` command.
Signature · 1 line
gitgitgadget
PATCH v3 9/10 Documentation: clarify/correct a few sparsity related statements
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
--- Documentation/git-clone.txt | 8 ++++---- Documentation/git-sparse-checkout.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
Documentation/git-clone.txt +4 -4
@@ -167,10 +167,10 @@ objects from the source repository into a pack in the cloned repository. configuration variables are created. --sparse:: - Initialize the sparse-checkout file so the working - directory starts with only the files in the root - of the repository. The sparse-checkout file can be - modified to grow the working directory as needed. + Employ a sparse-checkout, with only files in the toplevel + directory initially being present. The + linkgit:git-sparse-checkout[1] command can be used to grow the + working directory as needed. --filter=<filter-spec>:: Use the partial clone feature and request that the server sends
Documentation/git-sparse-checkout.txt +1 -1
@@ -121,7 +121,7 @@ SPARSE CHECKOUT 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 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 files, but only a few are important to the current user.
Signature · 1 line
gitgitgadget
PATCH v3 10/10 clone: avoid using deprecated `sparse-checkout init`
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
The previous commits marked sparse-checkout init as deprecated; we can just use set instead here and pass it no paths.
--- builtin/clone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
builtin/clone.c +1 -1
@@ -633,7 +633,7 @@ static int git_sparse_checkout_init(const char *repo) {struct strvec argv =STRVEC_INIT ;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
Signature · 1 line
gitgitgadget
v4 cover sparse-checkout: make set subsume init
In reply to Elijah Newren via GitGitGadgetAs described at [1], the split of init and set subcommands in sparse-checkout causes multiple issues:
* Poor performance (deleting all tracked files, then later restoring many and maybe even most of them)
* Poor UI (multiple progress bars in wrappers that hide both commands under 1 user-facing command)
* Loss of ignored files under directories the user wanted to keep
This series fixes this bug by providing a single command to switch to a
sparse-checkout: set. It does so by making set able to do the combined work of init and set. It keeps init as-is to give folks time to adapt, but marks it as deprecated. It also makes reapply able to toggle cone/non-cone mode and sparse-index/non-sparse-index mode.
Changes since v3:
* Do not make git sparse-checkout disable throw an error when not in a sparse-checkout -- and document why we don't exit early either.
Changes since v2:
* Small documentation wording improvement
* Added Reviewed-by's from Stolee and Victoria
Changes since v1:
* Inserted new patches 3 & 4 as additional preparatory cleanups
* Took the new mode-toggling work code in sparse_checkout_set from the previous series and moved it into a new function, as a preparatory patch, and made it usable by init/set/reapply
* Also updated reapply to allow mode-toggling
* Updated the documentation as per above
* Various other small items from review comments
A quick overview:
* Patches 1-4: small preparatory refactorings
* Patch 5: patch adding new function for toggling {cone,sparse-checkout} modes
* Patch 6: the crux of the series; make set able to handle both init and set options
* Patch 7: make reapply also able to do mode toggling
* Patches 8-9: documentation modifications (Patch 4 is worth reviewing; it marks init as deprecated -- are others okay with that?)
* Patch 10: trivial modification of git clone --sparse to use git sparse-checkout set rather than git sparse-checkout init.
[1]
https://lore.kernel.org/git/CABPp-BE8TJ8QGAQWsSGT7S+9Xp-XmApcC9PSw3K=RQOP0rt+PQ@mail.gmail.com/
Elijah Newren (10):
sparse-checkout: pass use_stdin as a parameter instead of as a global
sparse-checkout: break apart functions for sparse_checkout_(set|add)
sparse-checkout: add sanity-checks on initial sparsity state
sparse-checkout: disallow --no-stdin as an argument to set
sparse-checkout: split out code for tweaking settings config
sparse-checkout: enable set to initialize sparse-checkout mode
sparse-checkout: enable reapply to take --[no-]{cone,sparse-index} git-sparse-checkout.txt: update to document init/set/reapply changes
Documentation: clarify/correct a few sparsity related statements
clone: avoid using deprecated sparse-checkout init
Documentation/git-clone.txt | 8 +- Documentation/git-sparse-checkout.txt | 100 +++++++------ builtin/clone.c | 2 +- builtin/sparse-checkout.c | 204 ++++++++++++++++++++------ t/t1091-sparse-checkout-builtin.sh | 10 +- 5 files changed, 227 insertions(+), 97 deletions(-)
base-commit: abe6bb3905392d5eb6b01fa6e54d7e784e0522aa
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1151%2Fnewren%2Fsparse-checkout-no-init-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1151/newren/sparse-checkout-no-init-v4
Pull-Request: https://github.com/git/git/pull/1151
Range-diff vs v3:
1: 814aed2d125 = 1: 814aed2d125 sparse-checkout: pass use_stdin as a parameter instead of as a global 2: 04cd57592e9 = 2: 04cd57592e9 sparse-checkout: break apart functions for sparse_checkout_(set|add) 3: f3af5edb25d ! 3: a8fdda35b91 sparse-checkout: add sanity-checks on initial sparsity state
@@ Metadata
## Commit message ##
sparse-checkout: add sanity-checks on initial sparsity state
- Most sparse-checkout subcommands (list, add, reapply, disable)
- only make sense when already in a sparse state. Add a quick check
- that will error out early if this is not the case.
+ Most sparse-checkout subcommands (list, add, reapply) only make sense
+ when already in a sparse state. Add a quick check that will error out
+ early if this is not the case.
+
+ Also document with a comment why we do not exit early in disable even
+ when core.sparseCheckout starts as false.
@@ builtin/sparse-checkout.c: static int sparse_checkout_disable(int argc, const ch
struct pattern_list pl;
struct strbuf match_all = STRBUF_INIT;
-+ if (!core_apply_sparse_checkout)
-+ die(_("no active sparse-checkout to disable"));
++ /*
++ * 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,
builtin_sparse_checkout_disable_options,
4: 82a13cc0197 = 4: 5882332b97f sparse-checkout: disallow --no-stdin as an argument to set
5: 7a812e0222c = 5: 3e9e28c8dd2 sparse-checkout: split out code for tweaking settings config
6: 7167a4b3118 = 6: 595ba138603 sparse-checkout: enable `set` to initialize sparse-checkout mode
7: 3687637915f = 7: 09b13280c26 sparse-checkout: enable reapply to take --[no-]{cone,sparse-index}
8: 7483d1363e5 = 8: 9d96da855ea git-sparse-checkout.txt: update to document init/set/reapply changes
9: 11a45920602 = 9: f669829a98b Documentation: clarify/correct a few sparsity related statements
10: 395d9b194d3 = 10: ae671aa615a clone: avoid using deprecated `sparse-checkout init`Signature · 1 line
gitgitgadget
PATCH v4 1/10 sparse-checkout: pass use_stdin as a parameter instead of as a global
From: Elijah Newren <[email protected]>
add_patterns_from_input() has relied on a global variable, set_opts.use_stdin, which has been used by both the set and add subcommands of sparse-checkout. Once we introduce an add_opts.use_stdin, the hardcoding of set_opts.use_stdin will be incorrect. Pass the value as function parameter instead to allow us to make subsequent changes.
--- builtin/sparse-checkout.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
builtin/sparse-checkout.c +16 -12
@@ -525,7 +525,8 @@ static struct sparse_checkout_set_opts { } set_opts;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;if (core_sparse_checkout_cone) {
@@ -535,7 +536,7 @@ static void add_patterns_from_input(struct pattern_list *pl,hashmap_init (&pl->parent_hashmap, pl_hashmap_cmp,NULL ,0 ); pl->use_cone_patterns =1 ; -if (set_opts.use_stdin) { +if (use_stdin) {struct strbuf unquoted =STRBUF_INIT ;while (!strbuf_getline (&line, stdin)) {if (line.buf[0 ] =='"' ) {
@@ -559,7 +560,7 @@ static void add_patterns_from_input(struct pattern_list *pl, } } }else { -if (set_opts.use_stdin) { +if (use_stdin) {struct strbuf line =STRBUF_INIT ;while (!strbuf_getline (&line, stdin)) {
@@ -580,7 +581,8 @@ enum modify_type { };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 pattern_entry *pe;
@@ -588,7 +590,7 @@ static void add_patterns_cone_mode(int argc, const char **argv,struct pattern_list existing;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)); existing.use_cone_patterns = core_sparse_checkout_cone;
@@ -614,17 +616,19 @@ static void add_patterns_cone_mode(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 ();if (add_patterns_from_file_to_list (sparse_filename,"" ,0 , pl,NULL ,0 ))die (_ ("unable to load existing sparse-checkout patterns" ));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 changed_config =0 ;
@@ -633,13 +637,13 @@ static int modify_pattern_list(int argc, const char **argv, enum modify_type m)switch (m) {case ADD :if (core_sparse_checkout_cone) -add_patterns_cone_mode (argc, argv, pl); +add_patterns_cone_mode (argc, argv, pl, use_stdin);else -add_patterns_literal (argc, argv, pl); +add_patterns_literal (argc, argv, pl, use_stdin);break ;case REPLACE : -add_patterns_from_input (pl, argc, argv); +add_patterns_from_input (pl, argc, argv, use_stdin);break ; }
@@ -675,7 +679,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix, builtin_sparse_checkout_set_usage, PARSE_OPT_KEEP_UNKNOWN); -return modify_pattern_list (argc, argv, m); +return modify_pattern_list (argc, argv, set_opts.use_stdin, m); }static char const *const builtin_sparse_checkout_reapply_usage[] = {
Signature · 1 line
gitgitgadget
PATCH v4 2/10 sparse-checkout: break apart functions for sparse_checkout_(set|add)
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
sparse_checkout_set() was reused by sparse_checkout_add() with the only difference being a single parameter being passed to that function. However, we would like sparse_checkout_set() to do the same work that sparse_checkout_init() does if sparse checkouts are not already enabled. To facilitate this transition, give each mode their own copy of the function. This does not introduce any behavioral changes; that will come in a subsequent patch.
--- builtin/sparse-checkout.c | 54 +++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 14 deletions(-)
builtin/sparse-checkout.c +40 -14
@@ -515,15 +515,6 @@ static void strbuf_to_cone_pattern(struct strbuf *line, struct pattern_list *pl)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,int argc,const char **argv,int use_stdin)
@@ -663,8 +654,43 @@ static int modify_pattern_list(int argc, const char **argv, int use_stdin,return result; } -static int sparse_checkout_set(int argc, const char **argv, const char *prefix, - enum modify_type m) +static char const *const builtin_sparse_checkout_add_usage[] = { +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_add_options[] = { +OPT_BOOL (0 ,"stdin" , &add_opts.use_stdin, +N_ ("read patterns from standard in" )), +OPT_END (), + }; + +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 (--stdin | <patterns>)" ), +NULL +}; + +static struct sparse_checkout_set_opts { +int use_stdin; +} set_opts; + +static int sparse_checkout_set(int argc, const char **argv, const char *prefix) { static struct option builtin_sparse_checkout_set_options[] = { OPT_BOOL(0, "stdin", &set_opts.use_stdin,
@@ -679,7 +705,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix, builtin_sparse_checkout_set_usage, PARSE_OPT_KEEP_UNKNOWN); -return modify_pattern_list (argc, argv, set_opts.use_stdin, m); +return modify_pattern_list (argc, argv, set_opts.use_stdin,REPLACE ); }static char const *const builtin_sparse_checkout_reapply_usage[] = {
@@ -762,9 +788,9 @@ int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)if (!strcmp (argv[0 ],"init" ))return sparse_checkout_init (argc, argv);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" )) -return sparse_checkout_set (argc, argv, prefix,ADD ); +return sparse_checkout_add (argc, argv, prefix);if (!strcmp (argv[0 ],"reapply" ))return sparse_checkout_reapply (argc, argv);if (!strcmp (argv[0 ],"disable" ))
Signature · 1 line
gitgitgadget
PATCH v4 3/10 sparse-checkout: add sanity-checks on initial sparsity state
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
Most sparse-checkout subcommands (list, add, reapply) only make sense when already in a sparse state. Add a quick check that will error out early if this is not the case.
Also document with a comment why we do not exit early in disable even when core.sparseCheckout starts as false.
--- builtin/sparse-checkout.c | 20 ++++++++++++++++++++ t/t1091-sparse-checkout-builtin.sh | 10 +++++++++- 2 files changed, 29 insertions(+), 1 deletion(-)
builtin/sparse-checkout.c +20 -0
@@ -56,6 +56,9 @@ static int sparse_checkout_list(int argc, const char **argv)char *sparse_filename;int res; +if (!core_apply_sparse_checkout) +die (_ ("this worktree is not sparse" )); + argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_list_options, builtin_sparse_checkout_list_usage,0 );
@@ -671,6 +674,9 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) OPT_END(), }; +if (!core_apply_sparse_checkout) +die (_ ("no sparse-checkout to add to" )); +repo_read_index (the_repository); argc = parse_options(argc, argv, prefix,
@@ -719,6 +725,9 @@ static int sparse_checkout_reapply(int argc, const char **argv) OPT_END(), }; +if (!core_apply_sparse_checkout) +die (_ ("must be in a sparse-checkout to reapply sparsity patterns" )); + argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_reapply_options, builtin_sparse_checkout_reapply_usage,0 );
@@ -740,6 +749,17 @@ static int sparse_checkout_disable(int argc, const char **argv)struct pattern_list pl;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 , builtin_sparse_checkout_disable_options, builtin_sparse_checkout_disable_usage,0 );
t/t1091-sparse-checkout-builtin.sh +9 -1
@@ -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 && test_must_be_empty list && test_i18ngrep "this worktree is not sparse (sparse-checkout file may not exist)" err
Signature · 1 line
gitgitgadget
PATCH v4 4/10 sparse-checkout: disallow --no-stdin as an argument to set
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
We intentionally added --stdin as an option to sparse-checkout set, but didn't intend for --no-stdin to be permitted as well.
--- builtin/sparse-checkout.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
builtin/sparse-checkout.c +3 -2
@@ -699,8 +699,9 @@ static struct sparse_checkout_set_opts {static int sparse_checkout_set (int argc,const char **argv,const char *prefix) {static struct option builtin_sparse_checkout_set_options[] = { -OPT_BOOL (0 ,"stdin" , &set_opts.use_stdin, -N_ ("read patterns from standard in" )), +OPT_BOOL_F (0 ,"stdin" , &set_opts.use_stdin, +N_ ("read patterns from standard in" ), +PARSE_OPT_NONEG ),OPT_END (), };
Signature · 1 line
gitgitgadget
PATCH v4 5/10 sparse-checkout: split out code for tweaking settings config
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
init has some code for handling updates to either cone mode or the sparse-index setting. We would like to be able to reuse this elsewhere, namely in set and reapply. Split this function out, and make it slightly more general so it can handle being called from the new callers.
--- builtin/sparse-checkout.c | 56 ++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 19 deletions(-)
builtin/sparse-checkout.c +37 -19
@@ -383,6 +383,41 @@ static int set_config(enum sparse_checkout_mode mode)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[] = {N_ ("git sparse-checkout init [--cone] [--[no-]sparse-index]" ),NULL
@@ -399,7 +434,6 @@ static int sparse_checkout_init(int argc, const char **argv)char *sparse_filename;int res;struct object_id oid; -int mode;struct strbuf pattern =STRBUF_INIT ;static struct option builtin_sparse_checkout_init_options[] = {
@@ -412,19 +446,14 @@ static int sparse_checkout_init(int argc, const char **argv)repo_read_index (the_repository); + init_opts.cone_mode =-1 ; init_opts.sparse_index =-1 ; argc =parse_options (argc, argv,NULL , builtin_sparse_checkout_init_options, builtin_sparse_checkout_init_usage,0 ); -if (init_opts.cone_mode) { - mode =MODE_CONE_PATTERNS ; - core_sparse_checkout_cone =1 ; - }else - mode =MODE_ALL_PATTERNS ; - -if (set_config (mode)) +if (update_modes (&init_opts.cone_mode, &init_opts.sparse_index))return 1 ;memset (&pl,0 ,sizeof (pl));
@@ -432,17 +461,6 @@ static int sparse_checkout_init(int argc, const char **argv) sparse_filename =get_sparse_checkout_filename (); 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 (res >=0 ) {free (sparse_filename);
Signature · 1 line
gitgitgadget
PATCH v4 6/10 sparse-checkout: enable `set` to initialize sparse-checkout mode
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
The previously suggested workflow:
git sparse-checkout init ...
git sparse-checkout set ...
Suffered from three problems:
1) It would delete nearly all files in the first step, then restore them in the second. That was poor performance and forced unnecessary rebuilds.
2) The two-step process resulted in two progress bars, which was suboptimal from a UI point of view for wrappers that invoked both of these commands but only exposed a single command to their end users.
3) With cone mode, the first step would delete nearly all ignored files everywhere, because everything was considered to be outside of the specified sparsity paths. (The user was not allowed to specify any sparsity paths in the init step.)
Avoid these problems by teaching set to understand the extra parameters that init takes and performing any necessary initialization if not already in a sparse checkout.
--- builtin/sparse-checkout.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
builtin/sparse-checkout.c +26 -1
@@ -706,17 +706,26 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) }static char const *const builtin_sparse_checkout_set_usage[] = { -N_ ("git sparse-checkout set (--stdin | <patterns>)" ), +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 ),
@@ -725,11 +734,27 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)repo_read_index (the_repository); + set_opts.cone_mode =-1 ; + set_opts.sparse_index =-1 ; + argc =parse_options (argc, argv, prefix, builtin_sparse_checkout_set_options, builtin_sparse_checkout_set_usage,PARSE_OPT_KEEP_UNKNOWN ); +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 ); }
Signature · 1 line
gitgitgadget
PATCH v4 7/10 sparse-checkout: enable reapply to take --[no-]{cone,sparse-index}
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
Folks may want to switch to or from cone mode, or to or from a sparse-index without changing their sparsity paths. Allow them to do so using the reapply command.
--- builtin/sparse-checkout.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
builtin/sparse-checkout.c +17 -1
@@ -759,13 +759,22 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix) }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 }; +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 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 (), };
@@ -777,6 +786,13 @@ static int sparse_checkout_reapply(int argc, const char **argv) 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 ; +return update_working_directory (NULL ); }
Signature · 1 line
gitgitgadget
Re: [PATCH v4 07/10] sparse-checkout: enable reapply to take --[no-]{cone,sparse-index}
Quoted 19 lines · Elijah Newren via GitGitGadget
From: Elijah Newren <[email protected]>
Folks may want to switch to or from cone mode, or to or from a sparse-index without changing their sparsity paths. Allow them to do so using the reapply command.
Reviewed-by Derrick Stolee <[email protected]>Reviewed-by Victoria Dye <[email protected]>Signed-off-by Elijah Newren <[email protected]>--- builtin/sparse-checkout.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)builtin/sparse-checkout.c +0
-0
builtin/sparse-checkout.c static int sparse_checkout_set(int argc, const char **argv, const char *prefix) · line 762
Quoted 5 lines
builtin/sparse-checkout.c +1
-1@@ -759,13 +759,22 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix) }static char const *const builtin_sparse_checkout_reapply_usage[] = { -N_ ("git sparse-checkout reapply" ), +N_ ("git sparse-checkout reapply [--[no-]cone] [--[no-]sparse-index] " ),
Found a trailing space in [1], which came from this commit.
[1]: https://github.com/git-l10n/git-po/blob/pot/next/2021-12-22.diff#L19
--
Jiang Xin
Re: [PATCH v4 07/10] sparse-checkout: enable reapply to take --[no-]{cone,sparse-index}
Quoted 4 lines · Jiang Xin
Quoted 1 line · Elijah Newren via GitGitGadget
...
Quoted 7 lines
builtin/sparse-checkout.c static int sparse_checkout_set(int argc, const char **argv, const char *prefix) · line 762
Quoted 3 lines
static char const * const builtin_sparse_checkout_reapply_usage[] = {
builtin/sparse-checkout.c +1
-1- N_("git sparse-checkout reapply"), + N_("git sparse-checkout reapply [--[no-]cone] [--[no-]sparse-index] "),Found a trailing space in [1], which came from this commit.
[1]: https://github.com/git-l10n/git-po/blob/pot/next/2021-12-22.diff#L19
Sorry about that. This series has already hit next, so I submitted a new patch to correct this
(https://lore.kernel.org/git/[email protected]/).
Re: [PATCH v4 07/10] sparse-checkout: enable reapply to take --[no-]{cone,sparse-index}
Quoted 10 lines · Elijah Newren
Quoted 4 lines · Jiang Xin
Quoted 1 line · Elijah Newren via GitGitGadget
...
Quoted 4 lines
Quoted 3 lines
static char const * const builtin_sparse_checkout_reapply_usage[] = {
builtin/sparse-checkout.c +1
-1- N_("git sparse-checkout reapply"), + N_("git sparse-checkout reapply [--[no-]cone] [--[no-]sparse-index] "),
Quoted 7 lines
Quoted 3 lines
Found a trailing space in [1], which came from this commit.
[1]: https://github.com/git-l10n/git-po/blob/pot/next/2021-12-22.diff#L19
Sorry about that. This series has already hit next, so I submitted a new patch to correct this
(https://lore.kernel.org/git/[email protected]/).
Thanks, both. Will take a look.
PATCH v4 8/10 git-sparse-checkout.txt: update to document init/set/reapply changes
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
As noted in the previous commit, using separate init and set steps with sparse-checkout result in a number of issues. The previous commits made set able to handle the work of both commands, and enabled reapply to tweak the {cone,sparse-index} settings. Update the documentation to reflect this, and mark init as deprecated.
--- Documentation/git-sparse-checkout.txt | 98 +++++++++++++++------------ 1 file changed, 55 insertions(+), 43 deletions(-)
Documentation/git-sparse-checkout.txt +55 -43
@@ -30,28 +30,36 @@ COMMANDS 'list':: Describe the patterns in the sparse-checkout file. -'init':: - Enable the `core.sparseCheckout` setting. If the - sparse-checkout file does not exist, then populate it with - patterns that match every file in the root directory and - no other directories, then will remove all directories tracked - by Git. Add patterns to the sparse-checkout file to - repopulate the working directory. +'set':: + Enable the necessary config settings + (extensions.worktreeConfig, core.sparseCheckout, + core.sparseCheckoutCone) if they are not already enabled, and + write a set of patterns to the sparse-checkout file from the + list of arguments following the 'set' subcommand. Update the + working directory to match the new patterns. + -To avoid interfering with other worktrees, it first enables the -`extensions.worktreeConfig` setting and makes sure to set the -`core.sparseCheckout` setting in the worktree-specific config file. +When the `--stdin` option is provided, the patterns are read from +standard in as a newline-delimited list instead of from the arguments. + -When `--cone` is provided, the `core.sparseCheckoutCone` setting is -also set, allowing for better performance with a limited set of -patterns (see 'CONE PATTERN SET' below). +When `--cone` is passed or `core.sparseCheckoutCone` is enabled, the +input list is considered a list of directories instead of +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 -index format. This reduces the size of the index to be more closely -aligned with your sparse-checkout definition. This can have significant -performance advantages for commands such as `git status` or `git add`. -This feature is still experimental. Some commands might be slower with -a sparse index until they are properly integrated with the feature. +Use the `--[no-]sparse-index` option to use a sparse index (the +default is to not use it). A sparse index reduces the size of the +index to be more closely aligned with your sparse-checkout +definition. This can have significant performance advantages for +commands such as `git status` or `git add`. This feature is still +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 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 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':: Update the sparse-checkout file to include additional patterns. 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 after cleaning up affected paths (e.g. resolving conflicts, undoing 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 the `core.sparseCheckout` config setting, and restore the - working directory to include all files. Leaves the sparse-checkout - file intact so a later 'git sparse-checkout init' command may - return the working directory to the same state. + working directory to include all files. + +'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 ---------------
@@ -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 appear in the working directory, and the rest will not. -To enable the sparse-checkout feature, run `git sparse-checkout init` to -initialize a simple sparse-checkout file and enable the `core.sparseCheckout` -config setting. Then, run `git sparse-checkout set` to modify the patterns in -the sparse-checkout file. +To enable the sparse-checkout feature, run `git sparse-checkout set` to +set the patterns you want to use. To repopulate the working directory with all files, use the `git sparse-checkout disable` command.
Signature · 1 line
gitgitgadget
PATCH v4 9/10 Documentation: clarify/correct a few sparsity related statements
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
--- Documentation/git-clone.txt | 8 ++++---- Documentation/git-sparse-checkout.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
Documentation/git-clone.txt +4 -4
@@ -167,10 +167,10 @@ objects from the source repository into a pack in the cloned repository. configuration variables are created. --sparse:: - Initialize the sparse-checkout file so the working - directory starts with only the files in the root - of the repository. The sparse-checkout file can be - modified to grow the working directory as needed. + Employ a sparse-checkout, with only files in the toplevel + directory initially being present. The + linkgit:git-sparse-checkout[1] command can be used to grow the + working directory as needed. --filter=<filter-spec>:: Use the partial clone feature and request that the server sends
Documentation/git-sparse-checkout.txt +1 -1
@@ -121,7 +121,7 @@ SPARSE CHECKOUT 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 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 files, but only a few are important to the current user.
Signature · 1 line
gitgitgadget
Re: [PATCH v4 09/10] Documentation: clarify/correct a few sparsity related statements
Documentation/git-clone.txt objects from the source repository into a pack in the cloned repository. · line 173
Quoted 10 lines · Elijah Newren via GitGitGadget
--sparse::
Documentation/git-clone.txt +4
-4- Initialize the sparse-checkout file so the working - directory starts with only the files in the root - of the repository. The sparse-checkout file can be - modified to grow the working directory as needed. + Employ a sparse-checkout, with only files in the toplevel + directory initially being present. The + linkgit:git-sparse-checkout[1] command can be used to grow the + working directory as needed.
s/toplevel/top-level/
Documentation/git-sparse-checkout.txt SPARSE CHECKOUT · line 126
Quoted 8 lines
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 the skip-worktree bit is set, then the file is ignored in the working
Documentation/git-sparse-checkout.txt +1
-1-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 files, but only a few are important to the current user.
Looks OK.
Signature · 1 line
An old man doll... just what I always wanted! - Clara
Re: [PATCH v4 09/10] Documentation: clarify/correct a few sparsity related statements
Quoted 13 lines · Bagas Sanjaya
Documentation/git-clone.txt objects from the source repository into a pack in the cloned repository. · line 173
Quoted 10 lines · Elijah Newren via GitGitGadget
--sparse::
Documentation/git-clone.txt +4
-4- Initialize the sparse-checkout file so the working - directory starts with only the files in the root - of the repository. The sparse-checkout file can be - modified to grow the working directory as needed. + Employ a sparse-checkout, with only files in the toplevel + directory initially being present. The + linkgit:git-sparse-checkout[1] command can be used to grow the + working directory as needed.
Quoted 1 line
s/toplevel/top-level/
No, the only occurrence of either term in Documentation/glossary.txt (though used incidentally) is 'toplevel' rather than 'top-level', git rev-parse has a --show-toplevel flag with no hyphen between top and level, and the occurrences of 'toplevel' in the codebase from a quick grep outnumber top-level 2 to 1. I'll keep 'toplevel'.
Quoted 10 lines
Documentation/git-sparse-checkout.txt SPARSE CHECKOUT · line 126
Quoted 8 lines
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 the skip-worktree bit is set, then the file is ignored in the working
Documentation/git-sparse-checkout.txt +1
-1-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 files, but only a few are important to the current user.Looks OK.
PATCH v4 10/10 clone: avoid using deprecated `sparse-checkout init`
In reply to Elijah Newren via GitGitGadgetFrom: Elijah Newren <[email protected]>
The previous commits marked sparse-checkout init as deprecated; we can just use set instead here and pass it no paths.
--- builtin/clone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
builtin/clone.c +1 -1
@@ -633,7 +633,7 @@ static int git_sparse_checkout_init(const char *repo) {struct strvec argv =STRVEC_INIT ;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
Signature · 1 line
gitgitgadget