It's not fun to ask the user to set extensions.worktreeConfig manually. It's error-prone too. So we do it automatically whenever anybody sets a per-worktree config with "git config" (support for builtin commands is coming later). Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- Documentation/git-worktree.txt | 6 ++++++ builtin/config.c | 3 ++- worktree.c | 40 ++++++++++++++++++++++++++++++++++++++++ worktree.h | 6 ++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 329a673..f5aad0a 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -167,6 +167,12 @@ want to share to all working directories: you are sure you always use sparse checkout for all working directories. +When `git config --worktree` is used to set a configuration variable +in multiple working directory setup, `extensions.worktreeConfig` will +be automatically set. The two variables `core.worktree` and +`core.bare` if present will be moved to `config.worktree` of the main +working tree. + DETAILS ------- Each linked working tree has a private sub-directory in the repository's diff --git a/builtin/config.c b/builtin/config.c index 7d390af..9dafefd 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -533,7 +533,8 @@ int cmd_config(int argc, const char **argv, const char *prefix) if (repository_format_worktree_config) given_config_source.file = git_pathdup("config.worktree"); else if (worktrees[0] && worktrees[1]) { - die("BUG: migration is not supported yet"); + migrate_worktree_config(); + given_config_source.file = git_pathdup("config.worktree"); } else given_config_source.file = git_pathdup("config"); free_worktrees(worktrees); diff --git a/worktree.c b/worktree.c index eb61212..d8c9d85 100644 --- a/worktree.c +++ b/worktree.c @@ -380,3 +380,43 @@ const struct worktree *find_shared_symref(const char *symref, return existing; } + +void migrate_worktree_config(void) +{ + struct strbuf worktree_path = STRBUF_INIT; + struct strbuf main_path = STRBUF_INIT; + struct repository_format format; + + assert(repository_format_worktree_config == 0); + + strbuf_git_common_path(&worktree_path, "config.worktree"); + strbuf_git_path(&main_path, "config"); + + read_repository_format(&format, main_path.buf); + assert(format.worktree_config == 0); + + if (format.is_bare >= 0) { + git_config_set_in_file(worktree_path.buf, + "core.bare", "true"); + git_config_set_in_file(main_path.buf, + "core.bare", NULL); + } + if (format.work_tree) { + git_config_set_in_file(worktree_path.buf, + "core.worktree", + format.work_tree); + git_config_set_in_file(main_path.buf, + "core.worktree", NULL); + } + + git_config_set_in_file(main_path.buf, + "extensions.worktreeConfig", "true"); + if (format.version == 0) + git_config_set_in_file(main_path.buf, + "core.repositoryFormatVersion", "1"); + + repository_format_worktree_config = 1; + + strbuf_release(&main_path); + strbuf_release(&worktree_path); +} diff --git a/worktree.h b/worktree.h index d59ce1f..cf82676 100644 --- a/worktree.h +++ b/worktree.h @@ -76,4 +76,10 @@ extern const char *worktree_git_path(const struct worktree *wt, const char *fmt, ...) __attribute__((format (printf, 2, 3))); +/* + * Called to add extensions.worktreeConfig to $GIT_DIR/config and move + * main worktree specific config variables to $GIT_DIR/config.worktree. + */ +extern void migrate_worktree_config(void); + #endif -- 2.8.2.524.g6ff3d78