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 <pclo...@gmail.com>
---
 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

Reply via email to