{"thread":{"id":"44846","subject":"[PATCH v5 0/4] Per-worktree config file support","startedAt":"2017-01-10T11:27:39Z","lastAt":"2017-01-19T20:03:24Z","messageCount":13,"participants":["Nguyễn Thái Ngọc Duy","Duy Nguyen","Stefan Beller","Junio C Hamano"],"isPatch":true,"patchVersion":5,"patchTotal":4},"messages":[{"id":"309135","messageId":"20170110112524.12870-1-pclouds@gmail.com","threadId":"44846","inReplyTo":null,"subject":"[PATCH v5 0/4] Per-worktree config file support","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2017-01-10T11:25:20Z","receivedAt":"2017-01-10T11:27:39Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Let's get this rolling again. To refresh your memory because it's half\na year since v4 [1], this is about letting each worktree in multi\nworktree setup has their own config settings. The most prominent ones\nare core.worktree, used by submodules, and core.sparseCheckout.\n\nThis time I'm not touching submodules at all. I'm leaving it in the\ngood hands of \"submodule people\". All I'm providing is mechanism. How\nyou use it is up to you. So the series benefits sparse checkout users\nonly.\n\nNot much has changed from v4, except that the migration to new config\nlayout is done automatically _update_ a config variable with \"git\nconfig --worktree\".\n\nI think this one is more or less ready. I have an RFC follow-up patch\nabout core.bare, but that could be handled separately.\n\n[1] http://public-inbox.org/git/20160720172419.25473-1-pclouds@gmail.com/\n\nNguyễn Thái Ngọc Duy (4):\n  config: read per-worktree config files\n  config: --worktree for manipulating per-worktree config file\n  config: automatically migrate to new config layout when --worktree is used\n  t2029: add tests for per-worktree config\n\n Documentation/config.txt               | 11 ++++-\n Documentation/git-config.txt           | 26 ++++++++---\n Documentation/git-worktree.txt         | 37 +++++++++++++++\n Documentation/gitrepository-layout.txt |  8 ++++\n builtin/config.c                       | 16 ++++++-\n cache.h                                |  2 +\n config.c                               |  7 +++\n environment.c                          |  1 +\n setup.c                                |  5 ++-\n t/t2029-worktree-config.sh (new +x)    | 82 ++++++++++++++++++++++++++++++++++\n worktree.c                             | 40 +++++++++++++++++\n worktree.h                             |  6 +++\n 12 files changed, 230 insertions(+), 11 deletions(-)\n create mode 100755 t/t2029-worktree-config.sh\n\n-- \n2.8.2.524.g6ff3d78\n\n"},{"id":"309136","messageId":"20170110112524.12870-2-pclouds@gmail.com","threadId":"44846","inReplyTo":"20170110112524.12870-1-pclouds@gmail.com","subject":"[PATCH v5 1/4] config: read per-worktree config files","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2017-01-10T11:25:21Z","receivedAt":"2017-01-10T11:27:46Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"A new repo extension is added, worktreeConfig. When it is present:\n\n - Repository config reading by default includes $GIT_DIR/config _and_\n   $GIT_DIR/config.worktree. \"config\" file remains shared in multiple\n   worktree setup.\n\n - The special treatment for core.bare and core.worktree, to stay\n   effective only in main worktree, is gone. These config files are\n   supposed to be in config.worktree.\n\nThis extension is most useful in multiple worktree setup because you\nnow have an option to store per-worktree config (which is either\n.git/config.worktree for main worktree, or\n.git/worktrees/xx/config.worktree for linked ones).\n\nThis extension can be used in single worktree mode, even though it's\npretty much useless (but this can happen after you remove all linked\nworktrees and move back to single worktree).\n\n\"git config\" reads from both \"config\" and \"config.worktree\" by default\n(i.e. without either --user, --file...) when this extension is\npresent. Default writes (not implemented in this patch) still go to\n\"config\", not \"config.worktree\". A new option --worktree is added for\nthat (*).\n\nSince a new repo extension is introduced, existing git binaries should\nrefuse to access to the repo (both from main and linked worktrees). So\nthey will not misread the config file (i.e. skip the config.worktree\npart). They may still accidentally write to the config file anyway if\nthey use with \"git config --file <path>\".\n\nThis design places a bet on the assumption that the majority of config\nvariables are shared so it is the default mode. A safer move would be\ndefault writes go to per-worktree file, so that accidental changes are\nisolated.\n\n(*) \"git config --worktree\" points back to \"config\" file when this\n    extension is not present so that it works in any setup.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Documentation/config.txt               | 11 +++++++++--\n Documentation/git-config.txt           |  4 ++++\n Documentation/git-worktree.txt         | 31 +++++++++++++++++++++++++++++++\n Documentation/gitrepository-layout.txt |  8 ++++++++\n cache.h                                |  2 ++\n config.c                               |  7 +++++++\n environment.c                          |  1 +\n setup.c                                |  5 ++++-\n 8 files changed, 66 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 30cb946..c508386 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -2,8 +2,9 @@ CONFIGURATION FILE\n ------------------\n \n The Git configuration file contains a number of variables that affect\n-the Git commands' behavior. The `.git/config` file in each repository\n-is used to store the configuration for that repository, and\n+the Git commands' behavior. The files `.git/config` and optionally\n+`config.worktree` (see `extensions.worktreeConfig` below) are each\n+repository is used to store the configuration for that repository, and\n `$HOME/.gitconfig` is used to store a per-user configuration as\n fallback values for the `.git/config` file. The file `/etc/gitconfig`\n can be used to store a system-wide default configuration.\n@@ -264,6 +265,12 @@ advice.*::\n \t\tshow directions on how to proceed from the current state.\n --\n \n+extensions.worktreeConfig::\n+\tIf set, by default \"git config\" reads from both \"config\" and\n+\t\"config.worktree\" file in that order. In multiple working\n+\tdirectory mode, \"config\" file is shared while\n+\t\"config.worktree\" is per-working directory.\n+\n core.fileMode::\n \tTells Git if the executable bit of files in the working tree\n \tis to be honored.\ndiff --git a/Documentation/git-config.txt b/Documentation/git-config.txt\nindex 83f86b9..806873c 100644\n--- a/Documentation/git-config.txt\n+++ b/Documentation/git-config.txt\n@@ -253,6 +253,10 @@ $XDG_CONFIG_HOME/git/config::\n $GIT_DIR/config::\n \tRepository specific configuration file.\n \n+$GIT_DIR/config.worktree::\n+\tThis is optional and is only searched when\n+\t`extensions.worktreeConfig` is present in $GIT_DIR/config.\n+\n If no further options are given, all reading options will read all of these\n files that are available. If the global or the system-wide configuration\n file are not available they will be ignored. If the repository configuration\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex e257c19..329a673 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -136,6 +136,37 @@ working trees, it can be used to identify worktrees. For example if\n you only have two working trees, at \"/abc/def/ghi\" and \"/abc/def/ggg\",\n then \"ghi\" or \"def/ghi\" is enough to point to the former working tree.\n \n+CONFIGURATION FILE\n+------------------\n+By default, the repository \"config\" file is shared across all working\n+directories. If the config variables `core.bare` or `core.worktree`\n+are already present in the config file, they will be applied to the\n+main working directory only.\n+\n+In order to have configuration specific to working directories, you\n+can turn on \"worktreeConfig\" extension, e.g.:\n+\n+------------\n+$ git config extensions.worktreeConfig true\n+------------\n+\n+In this mode, specific configuration stays in the path pointed by `git\n+rev-parse --git-path config.worktree`. You can add or update\n+configuration in this file with `git config --worktree`. Git before\n+version 2.13 will refuse to access repositories with this extension.\n+\n+Note that in this file, the exception for `core.bare` and\n+`core.worktree` is gone. If you have them before, you need to move\n+them to the `config.worktree` of the main working directory. You may\n+also take this opportunity to move other configuration that you do not\n+want to share to all working directories:\n+\n+ - `core.worktree` and `core.bare` should never be shared\n+\n+ - `core.sparseCheckout` is recommended per working directory, unless\n+   you are sure you always use sparse checkout for all working\n+   directories.\n+\n DETAILS\n -------\n Each linked working tree has a private sub-directory in the repository's\ndiff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt\nindex a5f99cb..fee2557 100644\n--- a/Documentation/gitrepository-layout.txt\n+++ b/Documentation/gitrepository-layout.txt\n@@ -143,6 +143,11 @@ config::\n \tif $GIT_COMMON_DIR is set and \"$GIT_COMMON_DIR/config\" will be\n \tused instead.\n \n+config.worktree::\n+\tWorking directory specific configuration file for the main\n+\tworking directory in multiple working directory setup (see\n+\tlinkgit:git-worktree[1]).\n+\n branches::\n \tA slightly deprecated way to store shorthands to be used\n \tto specify a URL to 'git fetch', 'git pull' and 'git push'.\n@@ -276,6 +281,9 @@ worktrees/<id>/link::\n \tfile. It is used to detect if the linked repository is\n \tmanually removed.\n \n+worktrees/<id>/config.worktree::\n+\tWorking directory specific configuration file.\n+\n SEE ALSO\n --------\n linkgit:git-init[1],\ndiff --git a/cache.h b/cache.h\nindex a50a61a..c621a35 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -777,10 +777,12 @@ extern int grafts_replace_parents;\n #define GIT_REPO_VERSION 0\n #define GIT_REPO_VERSION_READ 1\n extern int repository_format_precious_objects;\n+extern int repository_format_worktree_config;\n \n struct repository_format {\n \tint version;\n \tint precious_objects;\n+\tint worktree_config;\n \tint is_bare;\n \tchar *work_tree;\n \tstruct string_list unknown_extensions;\ndiff --git a/config.c b/config.c\nindex 83fdecb..a461e68 100644\n--- a/config.c\n+++ b/config.c\n@@ -1307,6 +1307,13 @@ static int do_git_config_sequence(config_fn_t fn, void *data)\n \tif (repo_config && !access_or_die(repo_config, R_OK, 0))\n \t\tret += git_config_from_file(fn, repo_config, data);\n \n+\tif (repository_format_worktree_config) {\n+\t\tchar *path = git_pathdup(\"config.worktree\");\n+\t\tif (!access_or_die(path, R_OK, 0))\n+\t\t\tret += git_config_from_file(fn, path, data);\n+\t\tfree(path);\n+\t}\n+\n \tcurrent_parsing_scope = CONFIG_SCOPE_CMDLINE;\n \tif (git_config_from_parameters(fn, data) < 0)\n \t\tdie(_(\"unable to parse command-line config\"));\ndiff --git a/environment.c b/environment.c\nindex 0935ec6..df1be15 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -26,6 +26,7 @@ int warn_ambiguous_refs = 1;\n int warn_on_object_refname_ambiguity = 1;\n int ref_paranoia = -1;\n int repository_format_precious_objects;\n+int repository_format_worktree_config;\n const char *git_commit_encoding;\n const char *git_log_output_encoding;\n const char *apply_default_whitespace;\ndiff --git a/setup.c b/setup.c\nindex fe572b8..69efe45 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -389,6 +389,8 @@ static int check_repo_format(const char *var, const char *value, void *vdata)\n \t\t\t;\n \t\telse if (!strcmp(ext, \"preciousobjects\"))\n \t\t\tdata->precious_objects = git_config_bool(var, value);\n+\t\telse if (!strcmp(ext, \"worktreeconfig\"))\n+\t\t\tdata->worktree_config = git_config_bool(var, value);\n \t\telse\n \t\t\tstring_list_append(&data->unknown_extensions, ext);\n \t} else if (strcmp(var, \"core.bare\") == 0) {\n@@ -432,8 +434,9 @@ static int check_repository_format_gently(const char *gitdir, int *nongit_ok)\n \t}\n \n \trepository_format_precious_objects = candidate.precious_objects;\n+\trepository_format_worktree_config = candidate.worktree_config;\n \tstring_list_clear(&candidate.unknown_extensions, 0);\n-\tif (!has_common) {\n+\tif (!has_common || repository_format_worktree_config) {\n \t\tif (candidate.is_bare != -1) {\n \t\t\tis_bare_repository_cfg = candidate.is_bare;\n \t\t\tif (is_bare_repository_cfg == 1)\n-- \n2.8.2.524.g6ff3d78\n\n"},{"id":"309137","messageId":"20170110112524.12870-3-pclouds@gmail.com","threadId":"44846","inReplyTo":"20170110112524.12870-1-pclouds@gmail.com","subject":"[PATCH v5 2/4] config: --worktree for manipulating per-worktree config file","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2017-01-10T11:25:22Z","receivedAt":"2017-01-10T11:27:52Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"As noted in the previous commit, \"git config\" without options will read\nboth per-worktree and per-repo by default. --worktree is needed to read\njust per-worktree config. Writing goes to per-repo by default though,\nunless --worktree is given.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Documentation/git-config.txt | 22 +++++++++++++++-------\n builtin/config.c             | 15 ++++++++++++++-\n 2 files changed, 29 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/git-config.txt b/Documentation/git-config.txt\nindex 806873c..ead33a8 100644\n--- a/Documentation/git-config.txt\n+++ b/Documentation/git-config.txt\n@@ -47,13 +47,15 @@ checks or transformations are performed on the value.\n \n When reading, the values are read from the system, global and\n repository local configuration files by default, and options\n-`--system`, `--global`, `--local` and `--file <filename>` can be\n-used to tell the command to read from only that location (see <<FILES>>).\n+`--system`, `--global`, `--local`, `--worktree` and\n+`--file <filename>` can be used to tell the command to read from only\n+that location (see <<FILES>>).\n \n When writing, the new value is written to the repository local\n configuration file by default, and options `--system`, `--global`,\n-`--file <filename>` can be used to tell the command to write to\n-that location (you can say `--local` but that is the default).\n+`--worktree`, `--file <filename>` can be used to tell the command to\n+write to that location (you can say `--local` but that is the\n+default).\n \n This command will fail with non-zero status upon error.  Some exit\n codes are:\n@@ -133,6 +135,11 @@ from all available files.\n +\n See also <<FILES>>.\n \n+--worktree::\n+\tSimilar to `--local` except that `.git/config.worktree` is\n+\tread from or written to if `extensions.worktreeConfig` is\n+\tpresent. If not it's the same as `--local`.\n+\n -f config-file::\n --file config-file::\n \tUse the given config file instead of the one specified by GIT_CONFIG.\n@@ -275,9 +282,10 @@ configuration file. Note that this also affects options like `--replace-all`\n and `--unset`. *'git config' will only ever change one file at a time*.\n \n You can override these rules either by command-line options or by environment\n-variables. The `--global` and the `--system` options will limit the file used\n-to the global or system-wide file respectively. The `GIT_CONFIG` environment\n-variable has a similar effect, but you can specify any filename you want.\n+variables. The `--global`, `--system` and `--worktree` options will limit\n+the file used to the global, system-wide or per-worktree file respectively.\n+The `GIT_CONFIG` environment variable has a similar effect, but you\n+can specify any filename you want.\n \n \n ENVIRONMENT\ndiff --git a/builtin/config.c b/builtin/config.c\nindex 05843a0..7d390af 100644\n--- a/builtin/config.c\n+++ b/builtin/config.c\n@@ -4,6 +4,7 @@\n #include \"parse-options.h\"\n #include \"urlmatch.h\"\n #include \"quote.h\"\n+#include \"worktree.h\"\n \n static const char *const builtin_config_usage[] = {\n \tN_(\"git config [<options>]\"),\n@@ -23,6 +24,7 @@ static char key_delim = ' ';\n static char term = '\\n';\n \n static int use_global_config, use_system_config, use_local_config;\n+static int use_worktree_config;\n static struct git_config_source given_config_source;\n static int actions, types;\n static int end_null;\n@@ -56,6 +58,7 @@ static struct option builtin_config_options[] = {\n \tOPT_BOOL(0, \"global\", &use_global_config, N_(\"use global config file\")),\n \tOPT_BOOL(0, \"system\", &use_system_config, N_(\"use system config file\")),\n \tOPT_BOOL(0, \"local\", &use_local_config, N_(\"use repository config file\")),\n+\tOPT_BOOL(0, \"worktree\", &use_worktree_config, N_(\"use per-worktree config file\")),\n \tOPT_STRING('f', \"file\", &given_config_source.file, N_(\"file\"), N_(\"use given config file\")),\n \tOPT_STRING(0, \"blob\", &given_config_source.blob, N_(\"blob-id\"), N_(\"read config from given blob object\")),\n \tOPT_GROUP(N_(\"Action\")),\n@@ -490,6 +493,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)\n \t\t\t     PARSE_OPT_STOP_AT_NON_OPTION);\n \n \tif (use_global_config + use_system_config + use_local_config +\n+\t    use_worktree_config +\n \t    !!given_config_source.file + !!given_config_source.blob > 1) {\n \t\terror(\"only one config file at a time.\");\n \t\tusage_with_options(builtin_config_usage, builtin_config_options);\n@@ -524,7 +528,16 @@ int cmd_config(int argc, const char **argv, const char *prefix)\n \t\tgiven_config_source.file = git_etc_gitconfig();\n \telse if (use_local_config)\n \t\tgiven_config_source.file = git_pathdup(\"config\");\n-\telse if (given_config_source.file) {\n+\telse if (use_worktree_config) {\n+\t\tstruct worktree **worktrees = get_worktrees(0);\n+\t\tif (repository_format_worktree_config)\n+\t\t\tgiven_config_source.file = git_pathdup(\"config.worktree\");\n+\t\telse if (worktrees[0] && worktrees[1]) {\n+\t\t\tdie(\"BUG: migration is not supported yet\");\n+\t\t} else\n+\t\t\tgiven_config_source.file = git_pathdup(\"config\");\n+\t\tfree_worktrees(worktrees);\n+\t} else if (given_config_source.file) {\n \t\tif (!is_absolute_path(given_config_source.file) && prefix)\n \t\t\tgiven_config_source.file =\n \t\t\t\txstrdup(prefix_filename(prefix,\n-- \n2.8.2.524.g6ff3d78\n\n"},{"id":"309138","messageId":"20170110112524.12870-4-pclouds@gmail.com","threadId":"44846","inReplyTo":"20170110112524.12870-1-pclouds@gmail.com","subject":"[PATCH v5 3/4] config: automatically migrate to new config layout when --worktree is used","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2017-01-10T11:25:23Z","receivedAt":"2017-01-10T11:27:58Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"It's not fun to ask the user to set extensions.worktreeConfig manually.\nIt's error-prone too. So we do it automatically whenever anybody sets a\nper-worktree config with \"git config\" (support for builtin commands is\ncoming later).\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Documentation/git-worktree.txt |  6 ++++++\n builtin/config.c               |  3 ++-\n worktree.c                     | 40 ++++++++++++++++++++++++++++++++++++++++\n worktree.h                     |  6 ++++++\n 4 files changed, 54 insertions(+), 1 deletion(-)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 329a673..f5aad0a 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -167,6 +167,12 @@ want to share to all working directories:\n    you are sure you always use sparse checkout for all working\n    directories.\n \n+When `git config --worktree` is used to set a configuration variable\n+in multiple working directory setup, `extensions.worktreeConfig` will\n+be automatically set. The two variables `core.worktree` and\n+`core.bare` if present will be moved to `config.worktree` of the main\n+working tree.\n+\n DETAILS\n -------\n Each linked working tree has a private sub-directory in the repository's\ndiff --git a/builtin/config.c b/builtin/config.c\nindex 7d390af..9dafefd 100644\n--- a/builtin/config.c\n+++ b/builtin/config.c\n@@ -533,7 +533,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)\n \t\tif (repository_format_worktree_config)\n \t\t\tgiven_config_source.file = git_pathdup(\"config.worktree\");\n \t\telse if (worktrees[0] && worktrees[1]) {\n-\t\t\tdie(\"BUG: migration is not supported yet\");\n+\t\t\tmigrate_worktree_config();\n+\t\t\tgiven_config_source.file = git_pathdup(\"config.worktree\");\n \t\t} else\n \t\t\tgiven_config_source.file = git_pathdup(\"config\");\n \t\tfree_worktrees(worktrees);\ndiff --git a/worktree.c b/worktree.c\nindex eb61212..d8c9d85 100644\n--- a/worktree.c\n+++ b/worktree.c\n@@ -380,3 +380,43 @@ const struct worktree *find_shared_symref(const char *symref,\n \n \treturn existing;\n }\n+\n+void migrate_worktree_config(void)\n+{\n+\tstruct strbuf worktree_path = STRBUF_INIT;\n+\tstruct strbuf main_path = STRBUF_INIT;\n+\tstruct repository_format format;\n+\n+\tassert(repository_format_worktree_config == 0);\n+\n+\tstrbuf_git_common_path(&worktree_path, \"config.worktree\");\n+\tstrbuf_git_path(&main_path, \"config\");\n+\n+\tread_repository_format(&format, main_path.buf);\n+\tassert(format.worktree_config == 0);\n+\n+\tif (format.is_bare >= 0) {\n+\t\tgit_config_set_in_file(worktree_path.buf,\n+\t\t\t\t       \"core.bare\", \"true\");\n+\t\tgit_config_set_in_file(main_path.buf,\n+\t\t\t\t       \"core.bare\", NULL);\n+\t}\n+\tif (format.work_tree) {\n+\t\tgit_config_set_in_file(worktree_path.buf,\n+\t\t\t\t       \"core.worktree\",\n+\t\t\t\t       format.work_tree);\n+\t\tgit_config_set_in_file(main_path.buf,\n+\t\t\t\t       \"core.worktree\", NULL);\n+\t}\n+\n+\tgit_config_set_in_file(main_path.buf,\n+\t\t\t       \"extensions.worktreeConfig\", \"true\");\n+\tif (format.version == 0)\n+\t\tgit_config_set_in_file(main_path.buf,\n+\t\t\t\t       \"core.repositoryFormatVersion\", \"1\");\n+\n+\trepository_format_worktree_config = 1;\n+\n+\tstrbuf_release(&main_path);\n+\tstrbuf_release(&worktree_path);\n+}\ndiff --git a/worktree.h b/worktree.h\nindex d59ce1f..cf82676 100644\n--- a/worktree.h\n+++ b/worktree.h\n@@ -76,4 +76,10 @@ extern const char *worktree_git_path(const struct worktree *wt,\n \t\t\t\t     const char *fmt, ...)\n \t__attribute__((format (printf, 2, 3)));\n \n+/*\n+ * Called to add extensions.worktreeConfig to $GIT_DIR/config and move\n+ * main worktree specific config variables to $GIT_DIR/config.worktree.\n+ */\n+extern void migrate_worktree_config(void);\n+\n #endif\n-- \n2.8.2.524.g6ff3d78\n\n"},{"id":"309139","messageId":"20170110112524.12870-5-pclouds@gmail.com","threadId":"44846","inReplyTo":"20170110112524.12870-1-pclouds@gmail.com","subject":"[PATCH v5 4/4] t2029: add tests for per-worktree config","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2017-01-10T11:25:24Z","receivedAt":"2017-01-10T11:28:04Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n t/t2029-worktree-config.sh (new +x) | 82 +++++++++++++++++++++++++++++++++++++\n 1 file changed, 82 insertions(+)\n create mode 100755 t/t2029-worktree-config.sh\n\ndiff --git a/t/t2029-worktree-config.sh b/t/t2029-worktree-config.sh\nnew file mode 100755\nindex 0000000..4ebdf13\n--- /dev/null\n+++ b/t/t2029-worktree-config.sh\n@@ -0,0 +1,82 @@\n+#!/bin/sh\n+\n+test_description=\"config file in multi worktree\"\n+\n+. ./test-lib.sh\n+\n+cmp_config() {\n+\tif [ \"$1\" = \"-C\" ]; then\n+\t\tshift &&\n+\t\tGD=\"-C $1\" &&\n+\t\tshift\n+\telse\n+\t\tGD=\n+\tfi &&\n+\techo \"$1\" >expected &&\n+\tshift &&\n+\tgit $GD config \"$@\" >actual &&\n+\ttest_cmp expected actual\n+}\n+\n+test_expect_success 'setup' '\n+\ttest_commit start &&\n+\tgit config --worktree per.worktree is-ok &&\n+\tgit worktree add wt1 &&\n+\tgit worktree add wt2 &&\n+\tgit config --worktree per.worktree is-ok &&\n+\tcmp_config true extensions.worktreeConfig\n+'\n+\n+test_expect_success 'config is shared as before' '\n+\tgit config this.is shared &&\n+\tcmp_config shared this.is &&\n+\tcmp_config -C wt1 shared this.is &&\n+\tcmp_config -C wt2 shared this.is\n+'\n+\n+test_expect_success 'config is shared (set from another worktree)' '\n+\tgit -C wt1 config that.is also-shared &&\n+\tcmp_config also-shared that.is &&\n+\tcmp_config -C wt1 also-shared that.is &&\n+\tcmp_config -C wt2 also-shared that.is\n+'\n+\n+test_expect_success 'config private to main worktree' '\n+\tgit config --worktree this.is for-main &&\n+\tcmp_config for-main this.is &&\n+\tcmp_config -C wt1 shared this.is &&\n+\tcmp_config -C wt2 shared this.is\n+'\n+\n+test_expect_success 'config private to linked worktree' '\n+\tgit -C wt1 config --worktree this.is for-wt1 &&\n+\tcmp_config for-main this.is &&\n+\tcmp_config -C wt1 for-wt1 this.is &&\n+\tcmp_config -C wt2 shared this.is\n+'\n+\n+test_expect_success 'core.bare no longer for main only' '\n+\tgit config core.bare true &&\n+\tcmp_config true core.bare &&\n+\tcmp_config -C wt1 true core.bare &&\n+\tcmp_config -C wt2 true core.bare &&\n+\tgit config --unset core.bare\n+'\n+\n+test_expect_success 'config.worktree no longer read without extension' '\n+\tgit config --unset extensions.worktreeConfig &&\n+\tcmp_config shared this.is &&\n+\tcmp_config -C wt1 shared this.is &&\n+\tcmp_config -C wt2 shared this.is\n+'\n+\n+test_expect_success 'config --worktree migrate core.bare and core.worktree' '\n+\tgit config core.bare true &&\n+\tgit config --worktree foo.bar true &&\n+\tcmp_config true extensions.worktreeConfig &&\n+\tcmp_config true foo.bar &&\n+\tcmp_config true core.bare &&\n+\t! git -C wt1 config core.bare\n+'\n+\n+test_done\n-- \n2.8.2.524.g6ff3d78\n\n"},{"id":"309140","messageId":"20170110113320.13119-1-pclouds@gmail.com","threadId":"44846","inReplyTo":"20170110112524.12870-1-pclouds@gmail.com","subject":"[PATCH/RFC 5/4] Redefine core.bare in multiple working tree setting","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2017-01-10T11:33:20Z","receivedAt":"2017-01-10T11:34:02Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"When core.bare was added, time was simpler, we only had one worktree\nassociated to one repository. The situation gets a bit complicated when\nmultiple worktrees are added. If core.bare is set in the per-repo config\nfile, should all worktrees see this variable?\n\nSince core.bare affects worktree-related commands (e.g. you are not\nsupposed to run \"git status\" when core.bare is true because no worktree\nis supposed to link to the repository), when multi worktree is added,\ncore.bare is evaluated true by the main worktree only. Other worktrees\nsimply do not see core.bare even if it's there.\n\nWith per-worktree configuration in place, core.bare is moved to main\nworktree's private config file. But it does not really make sense\nbecause this is about _repository_. Instead we could leave core.bare in\nthe per-repo config and change/extend its definition from:\n\n   If true this repository is assumed to be 'bare' and has no working\n   directory associated with it.\n\nto\n\n   If true this repository is assumed to be 'bare' and has no _main_\n   working directory associated with it.\n\nIn other words, linked worktrees are not covered by core.bare. This\ndefinition is the same as before when it comes to single worktree setup.\n\nA plus of this definition is, it allows a setup where we only have\nlinked worktrees (e.g. core.bare set to true, and the main repo is\ntucked somewhere safe), which makes all worktrees equal again because\n\"the special one\" is gone.\n\nThis patch is incomplete. I need to go through all is_bare_repository()\ncalls and adjust their behavior. But I wanted to run the idea through\nthe community first..\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Documentation/config.txt       | 2 +-\n Documentation/git-worktree.txt | 7 +++----\n t/t2029-worktree-config.sh     | 4 ++--\n worktree.c                     | 6 ------\n 4 files changed, 6 insertions(+), 13 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex c508386..ff146be 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -484,7 +484,7 @@ core.preferSymlinkRefs::\n \texpect HEAD to be a symbolic link.\n \n core.bare::\n-\tIf true this repository is assumed to be 'bare' and has no\n+\tIf true this repository is assumed to be 'bare' and has no main\n \tworking directory associated with it.  If this is the case a\n \tnumber of commands that require a working directory will be\n \tdisabled, such as linkgit:git-add[1] or linkgit:git-merge[1].\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex f5aad0a..a331d0a 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -161,7 +161,7 @@ them to the `config.worktree` of the main working directory. You may\n also take this opportunity to move other configuration that you do not\n want to share to all working directories:\n \n- - `core.worktree` and `core.bare` should never be shared\n+ - `core.worktree` should never be shared\n \n  - `core.sparseCheckout` is recommended per working directory, unless\n    you are sure you always use sparse checkout for all working\n@@ -169,9 +169,8 @@ want to share to all working directories:\n \n When `git config --worktree` is used to set a configuration variable\n in multiple working directory setup, `extensions.worktreeConfig` will\n-be automatically set. The two variables `core.worktree` and\n-`core.bare` if present will be moved to `config.worktree` of the main\n-working tree.\n+be automatically set. The variable `core.worktree` if present will be\n+moved to `config.worktree` of the main working tree.\n \n DETAILS\n -------\ndiff --git a/t/t2029-worktree-config.sh b/t/t2029-worktree-config.sh\nindex 4ebdf13..dc84c94 100755\n--- a/t/t2029-worktree-config.sh\n+++ b/t/t2029-worktree-config.sh\n@@ -70,13 +70,13 @@ test_expect_success 'config.worktree no longer read without extension' '\n \tcmp_config -C wt2 shared this.is\n '\n \n-test_expect_success 'config --worktree migrate core.bare and core.worktree' '\n+test_expect_success 'config --worktree migrate core.worktree' '\n \tgit config core.bare true &&\n \tgit config --worktree foo.bar true &&\n \tcmp_config true extensions.worktreeConfig &&\n \tcmp_config true foo.bar &&\n \tcmp_config true core.bare &&\n-\t! git -C wt1 config core.bare\n+\tcmp_config -C wt1 true core.bare\n '\n \n test_done\ndiff --git a/worktree.c b/worktree.c\nindex d8c9d85..c07cc50 100644\n--- a/worktree.c\n+++ b/worktree.c\n@@ -395,12 +395,6 @@ void migrate_worktree_config(void)\n \tread_repository_format(&format, main_path.buf);\n \tassert(format.worktree_config == 0);\n \n-\tif (format.is_bare >= 0) {\n-\t\tgit_config_set_in_file(worktree_path.buf,\n-\t\t\t\t       \"core.bare\", \"true\");\n-\t\tgit_config_set_in_file(main_path.buf,\n-\t\t\t\t       \"core.bare\", NULL);\n-\t}\n \tif (format.work_tree) {\n \t\tgit_config_set_in_file(worktree_path.buf,\n \t\t\t\t       \"core.worktree\",\n-- \n2.8.2.524.g6ff3d78\n\n"},{"id":"309141","messageId":"CACsJy8CGr56X7p19T=4Urq77NLO-fYeYEHbJJBwt9QafVRFVvg@mail.gmail.com","threadId":"44846","inReplyTo":"20170110112524.12870-1-pclouds@gmail.com","subject":"Re: [PATCH v5 0/4] Per-worktree config file support","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2017-01-10T11:41:45Z","receivedAt":"2017-01-10T11:42:23Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Tue, Jan 10, 2017 at 6:25 PM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> Not much has changed from v4, except that the migration to new config\n> layout is done automatically _update_ a config variable with \"git\n> config --worktree\".\n\nI accidentally two words that may make it hard to understand this\nsentence. It should be \"... is done automatically when you update..\"\n-- \nDuy\n"},{"id":"309144","messageId":"CAGZ79kZe_EG8YhpPtBwPqrR+yPjp2rQbqkAvUX6zeVNXg58NqQ@mail.gmail.com","threadId":"44846","inReplyTo":"20170110112524.12870-3-pclouds@gmail.com","subject":"Re: [PATCH v5 2/4] config: --worktree for manipulating per-worktree config file","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-01-10T16:52:00Z","receivedAt":"2017-01-10T16:52:06Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"> +               if (repository_format_worktree_config)\n> +                       given_config_source.file = git_pathdup(\"config.worktree\");\n> +               else if (worktrees[0] && worktrees[1]) {\n> +                       die(\"BUG: migration is not supported yet\");\n> +               } else\n> +                       given_config_source.file = git_pathdup(\"config\");\n\nnit: inconsistent use uf braces for single statements here.\nI mean the braces are needed in the BUG case, as otherwise we'd\nhave a dangling else, but then you could put the brace in the else case as well.\nThis nit doesn't warrant a reroll on its own.\n\n> +               free_worktrees(worktrees);\n> +       } else if (given_config_source.file) {\n>                 if (!is_absolute_path(given_config_source.file) && prefix)\n>                         given_config_source.file =\n>                                 xstrdup(prefix_filename(prefix,\n> --\n> 2.8.2.524.g6ff3d78\n>\n"},{"id":"309145","messageId":"CAGZ79ka+zkr83tSkg_kJWoN1u3fgu1O3u1-7USEoSM1tj-53vA@mail.gmail.com","threadId":"44846","inReplyTo":"20170110112524.12870-1-pclouds@gmail.com","subject":"Re: [PATCH v5 0/4] Per-worktree config file support","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-01-10T17:01:30Z","receivedAt":"2017-01-10T17:01:37Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Tue, Jan 10, 2017 at 3:25 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> Let's get this rolling again. To refresh your memory because it's half\n> a year since v4 [1], this is about letting each worktree in multi\n> worktree setup has their own config settings. The most prominent ones\n> are core.worktree, used by submodules, and core.sparseCheckout.\n\nThanks for getting this rolling again.\n\n>\n> This time I'm not touching submodules at all. I'm leaving it in the\n> good hands of \"submodule people\". All I'm providing is mechanism. How\n> you use it is up to you. So the series benefits sparse checkout users\n> only.\n\nAs one of the \"submodule people\", I have no complaints here.\n\n>\n> Not much has changed from v4, except that the migration to new config\n> layout is done automatically _update_ a config variable with \"git\n> config --worktree\".\n>\n> I think this one is more or less ready. I have an RFC follow-up patch\n> about core.bare, but that could be handled separately.\n\nI have read through the series and think the design is sound for worktrees\n(though I have little knowledge about them).\n\n---\nNow even further:\n\nSo to build on top of this series, I'd like to make submodules usable\nwith worktrees (i.e. shared object store, only clone/fetch once and\nall worktrees\nbenefit from it), the big question is how to get the underlying data\nmodel right.\n\nWould a submodule go into the superprojects\n\n    .git/worktrees/<worktree-name>/modules/<submodule-name>/\n\nor rather\n\n    .git/modules<submodule-name>/worktrees/<worktree-name>\n\nOr both (one of them being a gitlink file pointing at the other?)\n\nI have not made up my mind, as I haven't laid out all cases that are\nrelevant here.\n\nThanks,\nStefan\n\n\n>\n> [1] http://public-inbox.org/git/20160720172419.25473-1-pclouds@gmail.com/\n>\n> Nguyễn Thái Ngọc Duy (4):\n>   config: read per-worktree config files\n>   config: --worktree for manipulating per-worktree config file\n>   config: automatically migrate to new config layout when --worktree is used\n>   t2029: add tests for per-worktree config\n>\n>  Documentation/config.txt               | 11 ++++-\n>  Documentation/git-config.txt           | 26 ++++++++---\n>  Documentation/git-worktree.txt         | 37 +++++++++++++++\n>  Documentation/gitrepository-layout.txt |  8 ++++\n>  builtin/config.c                       | 16 ++++++-\n>  cache.h                                |  2 +\n>  config.c                               |  7 +++\n>  environment.c                          |  1 +\n>  setup.c                                |  5 ++-\n>  t/t2029-worktree-config.sh (new +x)    | 82 ++++++++++++++++++++++++++++++++++\n>  worktree.c                             | 40 +++++++++++++++++\n>  worktree.h                             |  6 +++\n>  12 files changed, 230 insertions(+), 11 deletions(-)\n>  create mode 100755 t/t2029-worktree-config.sh\n>\n> --\n> 2.8.2.524.g6ff3d78\n>\n"},{"id":"309302","messageId":"xmqqh953j2q0.fsf@gitster.mtv.corp.google.com","threadId":"44846","inReplyTo":"20170110113320.13119-1-pclouds@gmail.com","subject":"Re: [PATCH/RFC 5/4] Redefine core.bare in multiple working tree setting","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-01-12T23:08:39Z","receivedAt":"2017-01-12T23:08:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> With per-worktree configuration in place, core.bare is moved to main\n> worktree's private config file. But it does not really make sense\n> because this is about _repository_. Instead we could leave core.bare in\n> the per-repo config and change/extend its definition from:\n>\n>    If true this repository is assumed to be 'bare' and has no working\n>    directory associated with it.\n>\n> to\n>\n>    If true this repository is assumed to be 'bare' and has no _main_\n>    working directory associated with it.\n>\n> In other words, linked worktrees are not covered by core.bare. This\n> definition is the same as before when it comes to single worktree setup.\n\nUp to this point, I think it is not _wrong_ per-se, but it does not\nsay anything about secondary worktrees.  Some may have their own\nworking tree, others may be bare, and there is no way for programs\nto discover if a particular secondary worktree has or lacks its own\nworking tree.\n\nGranted, \"git worktree\" porcelain may be incapable of creating a\nsecondary worktree without a working tree, but I think the\nunderlying repository layout still is capable of expressing such a\nsecondary worktree.\n\nSo there still is something else necessary, I suspect, to make the\ndefinition complete.  Perhaps core.bare should be set in\nper-worktree configuration for all worktrees including the primary\none, and made the definition/explanation of core.bare to be\n\"definition of this variable, if done, must be done in per-worktree\nconfig file.  If set to true, the worktree is 'bare' and has no\nworking directory associated with it\"?  That makes things even more\nequal, as there is truly no \"special one\" at that point.\n\nI dunno.\n"},{"id":"309721","messageId":"CACsJy8B3TQ5va_wvbiKgkVggYJG=x+RVyabtAkzbqQqWFO2F-A@mail.gmail.com","threadId":"44846","inReplyTo":"xmqqh953j2q0.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH/RFC 5/4] Redefine core.bare in multiple working tree setting","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2017-01-19T12:02:19Z","receivedAt":"2017-01-19T12:02:55Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Thanks. I'll shelve this for now, maybe sleep on it for a while. The\nseries is complete without this patch by the way, if you want to pick\nit up.\n\nOn Fri, Jan 13, 2017 at 6:08 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n>\n>> With per-worktree configuration in place, core.bare is moved to main\n>> worktree's private config file. But it does not really make sense\n>> because this is about _repository_. Instead we could leave core.bare in\n>> the per-repo config and change/extend its definition from:\n>>\n>>    If true this repository is assumed to be 'bare' and has no working\n>>    directory associated with it.\n>>\n>> to\n>>\n>>    If true this repository is assumed to be 'bare' and has no _main_\n>>    working directory associated with it.\n>>\n>> In other words, linked worktrees are not covered by core.bare. This\n>> definition is the same as before when it comes to single worktree setup.\n>\n> Up to this point, I think it is not _wrong_ per-se, but it does not\n> say anything about secondary worktrees.  Some may have their own\n> working tree, others may be bare, and there is no way for programs\n> to discover if a particular secondary worktree has or lacks its own\n> working tree.\n>\n> Granted, \"git worktree\" porcelain may be incapable of creating a\n> secondary worktree without a working tree, but I think the\n> underlying repository layout still is capable of expressing such a\n> secondary worktree.\n>\n> So there still is something else necessary, I suspect, to make the\n> definition complete.  Perhaps core.bare should be set in\n> per-worktree configuration for all worktrees including the primary\n> one, and made the definition/explanation of core.bare to be\n> \"definition of this variable, if done, must be done in per-worktree\n> config file.  If set to true, the worktree is 'bare' and has no\n> working directory associated with it\"?  That makes things even more\n> equal, as there is truly no \"special one\" at that point.\n>\n> I dunno.\n\n\n\n-- \nDuy\n"},{"id":"309722","messageId":"CACsJy8BHgc8o+SydeiVnqaZRCbkJEWVzqDZM4sgey04ZLtG3tQ@mail.gmail.com","threadId":"44846","inReplyTo":"CAGZ79ka+zkr83tSkg_kJWoN1u3fgu1O3u1-7USEoSM1tj-53vA@mail.gmail.com","subject":"Re: [PATCH v5 0/4] Per-worktree config file support","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2017-01-19T12:09:27Z","receivedAt":"2017-01-19T12:10:03Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Jan 11, 2017 at 12:01 AM, Stefan Beller <sbeller@google.com> wrote:\n> On Tue, Jan 10, 2017 at 3:25 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n>> Let's get this rolling again. To refresh your memory because it's half\n>> a year since v4 [1], this is about letting each worktree in multi\n>> worktree setup has their own config settings. The most prominent ones\n>> are core.worktree, used by submodules, and core.sparseCheckout.\n>\n> Thanks for getting this rolling again.\n>\n>>\n>> This time I'm not touching submodules at all. I'm leaving it in the\n>> good hands of \"submodule people\". All I'm providing is mechanism. How\n>> you use it is up to you. So the series benefits sparse checkout users\n>> only.\n>\n> As one of the \"submodule people\", I have no complaints here.\n>\n>>\n>> Not much has changed from v4, except that the migration to new config\n>> layout is done automatically _update_ a config variable with \"git\n>> config --worktree\".\n>>\n>> I think this one is more or less ready. I have an RFC follow-up patch\n>> about core.bare, but that could be handled separately.\n>\n> I have read through the series and think the design is sound for worktrees\n> (though I have little knowledge about them).\n\nSubmodules and multi worktrees start to look very similar, the more I\nthink about it. Well, except that multi worktree does not separate odb\nand config files, maybe. And we have already seen both have a need to\nshare code (like the moving .git dir operation). I suspect I'll learn\nmore about submodules along the way, and you worktrees ;-)\n\n> Now even further:\n>\n> So to build on top of this series, I'd like to make submodules usable\n> with worktrees (i.e. shared object store, only clone/fetch once and\n> all worktrees\n> benefit from it), the big question is how to get the underlying data\n> model right.\n>\n> Would a submodule go into the superprojects\n>\n>     .git/worktrees/<worktree-name>/modules/<submodule-name>/\n>\n> or rather\n>\n>     .git/modules<submodule-name>/worktrees/<worktree-name>\n>\n> Or both (one of them being a gitlink file pointing at the other?)\n>\n> I have not made up my mind, as I haven't laid out all cases that are\n> relevant here.\n\nI would go with a conservative step first, keep submodules\nper-worktree. After it's sorted out. You can change the layout (e.g.\nas a config extension). The latter probably has some complication (but\nyeah sharing would be a big plus).\n-- \nDuy\n"},{"id":"309765","messageId":"CAGZ79kYy2q9ZMt8r7MdysuNOu84bY7uSUTGJXVxA1nnP-ZJW0Q@mail.gmail.com","threadId":"44846","inReplyTo":"CACsJy8BHgc8o+SydeiVnqaZRCbkJEWVzqDZM4sgey04ZLtG3tQ@mail.gmail.com","subject":"Re: [PATCH v5 0/4] Per-worktree config file support","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-01-19T20:03:12Z","receivedAt":"2017-01-19T20:03:24Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Thu, Jan 19, 2017 at 4:09 AM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Wed, Jan 11, 2017 at 12:01 AM, Stefan Beller <sbeller@google.com> wrote:\n>> On Tue, Jan 10, 2017 at 3:25 AM, Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n>>> Let's get this rolling again. To refresh your memory because it's half\n>>> a year since v4 [1], this is about letting each worktree in multi\n>>> worktree setup has their own config settings. The most prominent ones\n>>> are core.worktree, used by submodules, and core.sparseCheckout.\n>>\n>> Thanks for getting this rolling again.\n>>\n>>>\n>>> This time I'm not touching submodules at all. I'm leaving it in the\n>>> good hands of \"submodule people\". All I'm providing is mechanism. How\n>>> you use it is up to you. So the series benefits sparse checkout users\n>>> only.\n>>\n>> As one of the \"submodule people\", I have no complaints here.\n>>\n>>>\n>>> Not much has changed from v4, except that the migration to new config\n>>> layout is done automatically _update_ a config variable with \"git\n>>> config --worktree\".\n>>>\n>>> I think this one is more or less ready. I have an RFC follow-up patch\n>>> about core.bare, but that could be handled separately.\n>>\n>> I have read through the series and think the design is sound for worktrees\n>> (though I have little knowledge about them).\n>\n> Submodules and multi worktrees start to look very similar, the more I\n> think about it. Well, except that multi worktree does not separate odb\n> and config files, maybe.\n\nSimilar to worktrees submodules can appear and disappear without\naffecting the project/main tree. (though the mechanism is different,\nfor submodules, you'd checkout a version that doesn't have the submodule,\nwhereas for worktrees the user explicitely says: \"I don't want to see this\nworktree any more\")\n\n> And we have already seen both have a need to\n> share code (like the moving .git dir operation). I suspect I'll learn\n> more about submodules along the way, and you worktrees ;-)\n\nI sure hope so.\n\n>\n>> Now even further:\n>>\n>> So to build on top of this series, I'd like to make submodules usable\n>> with worktrees (i.e. shared object store, only clone/fetch once and\n>> all worktrees\n>> benefit from it), the big question is how to get the underlying data\n>> model right.\n>>\n>> Would a submodule go into the superprojects\n>>\n>>     .git/worktrees/<worktree-name>/modules/<submodule-name>/\n>>\n>> or rather\n>>\n>>     .git/modules<submodule-name>/worktrees/<worktree-name>\n>>\n>> Or both (one of them being a gitlink file pointing at the other?)\n>>\n>> I have not made up my mind, as I haven't laid out all cases that are\n>> relevant here.\n>\n> I would go with a conservative step first, keep submodules\n> per-worktree. After it's sorted out. You can change the layout (e.g.\n> as a config extension). The latter probably has some complication (but\n> yeah sharing would be a big plus).\n\nThe sharing is what we are asked for as it would \"make\nsubmodules usable\" (compared to the repo tool, which\ndoesn't have object sharing AFAIK). ;)\n\nCurrently I am leaning to put the worktree directory first and the\nsubmodules within, i.e.\n\n.git/worktrees/<worktree-name>/modules/<submodule-name>/\n\nbut in that directory, we'd only have the per-worktree\nspecific stuff, the object store would live with the superprojects\nmain worktree, i.e. at .git/modules/<submodule-name> we'd have\nthe main git dir for the submodule.\n\nThanks,\nStefan\n\n> --\n> Duy\n"}]}