On Mon, Jan 31, 2022 at 10:01 AM Derrick Stolee via GitGitGadget <gitgitgadget@xxxxxxxxx> wrote: > [...] > Create a helper method, init_worktree_config(), that will be used in a > later change to fix this behavior within 'git sparse-checkout set'. The > method is carefully documented in worktree.h. > [...] > Signed-off-by: Derrick Stolee <dstolee@xxxxxxxxxxxxx> > --- > diff --git a/worktree.c b/worktree.c > @@ -826,3 +827,72 @@ int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath, > +int init_worktree_config(struct repository *r) > +{ > + int res = 0; > + int bare = 0; > + struct config_set cs = { { 0 } }; > + const char *core_worktree; > + char *common_config_file = xstrfmt("%s/config", r->commondir); > + char *main_worktree_file = xstrfmt("%s/config.worktree", r->commondir); > + > + /* > + * If the extension is already enabled, then we can skip the > + * upgrade process. > + */ > + if (repository_format_worktree_config) > + return 0; > + if ((res = git_config_set_gently("extensions.worktreeConfig", "true"))) > + return error(_("failed to set extensions.worktreeConfig setting")); These two early returns are leaking `common_config_file` and `main_worktree_file` which have already been allocated by xstrfmt(). > + > + git_configset_init(&cs); > + git_configset_add_file(&cs, common_config_file); > + > + /* > + * If core.bare is true in the common config file, then we need to > + * move it to the base worktree's config file or it will break all > + * worktrees. If it is false, then leave it in place because it > + * _could_ be negating a global core.bare=true. > + */ The terminology "base worktree", which is not otherwise in the project's lexicon, seems to be a leftover from earlier versions of this series. Perhaps it could say instead "the repository-specific configuration in $GIT_COMMON_DIR/worktree.config" or something? > + if (!git_configset_get_bool(&cs, "core.bare", &bare) && bare) { > + if ((res = move_config_setting("core.bare", "true", > + common_config_file, > + main_worktree_file))) > + goto cleanup; > + } > + /* > + * If core.worktree is set, then the base worktree is located > + * somewhere different than the parent of the common Git dir. > + * Relocate that value to avoid breaking all worktrees with this > + * upgrade to worktree config. > + */ s/base worktree/main worktree/ > + if (!git_configset_get_string_tmp(&cs, "core.worktree", &core_worktree)) { > + if ((res = move_config_setting("core.worktree", core_worktree, > + common_config_file, > + main_worktree_file))) > + goto cleanup; > + } > + > + /* > + * Ensure that we use worktree config for the remaining lifetime > + * of the current process. > + */ > + repository_format_worktree_config = 1; > + > +cleanup: > + git_configset_clear(&cs); > + free(common_config_file); > + free(main_worktree_file); > + return res; > +}