On Monday, 31 January 2022 16:00:59 CET Derrick Stolee via GitGitGadget wrote: > From: Derrick Stolee <dstolee@xxxxxxxxxxxxx> > > When adding a new worktree, it is reasonable to expect that we want to > use the current set of sparse-checkout settings for that new worktree. > This is particularly important for repositories where the worktree would > become too large to be useful. This is even more important when using > partial clone as well, since we want to avoid downloading the missing > blobs for files that should not be written to the new worktree. > > The only way to create such a worktree without this intermediate step of > expanding the full worktree is to copy the sparse-checkout patterns and > config settings during 'git worktree add'. Each worktree has its own > sparse-checkout patterns, and the default behavior when the > sparse-checkout file is missing is to include all paths at HEAD. Thus, > we need to have patterns from somewhere, they might as well be the > current worktree's patterns. These are then modified independently in > the future. > > In addition to the sparse-checkout file, copy the worktree config file > if worktree config is enabled and the file exists. This will copy over > any important settings to ensure the new worktree behaves the same as > the current one. The only exception we must continue to make is that > core.bare and core.worktree should become unset in the worktree's config > file. > > Signed-off-by: Derrick Stolee <dstolee@xxxxxxxxxxxxx> > --- > builtin/worktree.c | 60 ++++++++++++++++++++++++++++++ > t/t1091-sparse-checkout-builtin.sh | 31 +++++++++++---- > t/t2400-worktree-add.sh | 46 ++++++++++++++++++++++- > 3 files changed, 127 insertions(+), 10 deletions(-) > > diff --git a/builtin/worktree.c b/builtin/worktree.c > index 2838254f7f2..dc9cd6decc8 100644 > --- a/builtin/worktree.c > +++ b/builtin/worktree.c > @@ -335,6 +335,66 @@ static int add_worktree(const char *path, const char *refname, > strbuf_addf(&sb, "%s/commondir", sb_repo.buf); > write_file(sb.buf, "../.."); > > + /* > + * If the current worktree has sparse-checkout enabled, then copy > + * the sparse-checkout patterns from the current worktree. > + */ > + if (core_apply_sparse_checkout) { > + char *from_file = git_pathdup("info/sparse-checkout"); > + char *to_file = xstrfmt("%s/worktrees/%s/info/sparse-checkout", > + realpath.buf, name); > + > + if (file_exists(from_file)) { > + if (safe_create_leading_directories(to_file) || > + copy_file(to_file, from_file, 0666)) > + error(_("failed to copy '%s' to '%s'; sparse-checkout may not work correctly"), > + from_file, to_file); > + } > + > + free(from_file); > + free(to_file); > + } > + > + /* > + * If we are using worktree config, then copy all current config > + * values from the current worktree into the new one, that way the > + * new worktree behaves the same as this one. > + */ > + if (repository_format_worktree_config) { > + char *from_file = git_pathdup("config.worktree"); > + char *to_file = xstrfmt("%s/worktrees/%s/config.worktree", > + realpath.buf, name); > + > + if (file_exists(from_file)) { > + struct config_set cs = { { 0 }}; > + const char *str_value; > + int bool_value; > + > + if (safe_create_leading_directories(to_file) || > + copy_file(to_file, from_file, 0666)) > + die(_("failed to copy worktree config from '%s' to '%s'"), > + from_file, to_file); > + > + git_configset_init(&cs); > + git_configset_add_file(&cs, from_file); > + > + if (!git_configset_get_bool(&cs, "core.bare", &bool_value) && > + bool_value && > + git_config_set_multivar_in_file_gently( > + to_file, "core.bare", NULL, "true", 0)) > + error(_("failed to unset 'core.bare' in '%s'"), to_file); > + if (!git_configset_get_value(&cs, "core.worktree", &str_value) && > + git_config_set_in_file_gently(to_file, > + "core.worktree", NULL)) > + error(_("failed to unset 'core.worktree' in '%s'"), to_file); > + In the first patch of this series, you use _("unable to set '%s' in'%s'). Does it make sense to reuse this string here?