{"thread":{"id":"50239","subject":"[RFC/PATCH 00/10] Support using submodules with worktrees","startedAt":"2019-01-16T10:32:09Z","lastAt":"2019-01-17T10:22:41Z","messageCount":14,"participants":["Nguyễn Thái Ngọc Duy","Stefan Beller","Duy Nguyen"],"isPatch":true,"patchVersion":1,"patchTotal":10},"messages":[{"id":"366801","messageId":"20190116103159.9305-1-pclouds@gmail.com","threadId":"50239","inReplyTo":null,"subject":"[RFC/PATCH 00/10] Support using submodules with worktrees","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2019-01-16T10:31:49Z","receivedAt":"2019-01-16T10:32:09Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Since this topic has come up twice recently, I'll take this opportunity\nto gather early comments on this series. It depends nd/config-move-to and\nat least has one known problem reported Tomasz. But I'll fix that\nlater once nd/config-move-to lands.\n\nFor more details, head for 01/10. This basically makes it possible\nto create secondary worktrees in either supermodules or submodules. The\nuser will be required to turn on extensions.worktreeConfig and this is\nsomething I'll need to work on, to make the transition smoother.\n\nNote that while it works, it's not really optimal because worktree\nclones of the same submodule could be duplicated. But hopefully I could\ntackle this one step at a time. Make it work first, shake out bugs, then\nthink about sharing repos.\n\nNguyễn Thái Ngọc Duy (10):\n  doc: about submodule support with multiple worktrees\n  submodule--helper: add missing \\n\n  submodule add: support multiple worktrees\n  submodule init: support multiple worktrees\n  submodule update: add tests for multiple worktrees\n  submodule sync: support multiple worktrees\n  submodule deinit: support multiple worktrees\n  submodule clone: use repo_config_set()\n  submodule clone: propagate extensions.worktreeConfig\n  submodule ensure-core-worktree: write to config.worktree\n\n Documentation/git-worktree.txt  |   8 ++\n Documentation/gitsubmodules.txt |  17 +++++\n builtin/submodule--helper.c     |  86 ++++++++++++----------\n config.c                        |  10 +++\n config.h                        |   1 +\n git-submodule.sh                |   8 +-\n repository.c                    |  21 ++++--\n repository.h                    |   4 +\n t/t2405-worktree-submodules.sh  | 125 ++++++++++++++++++++++++++++++++\n 9 files changed, 228 insertions(+), 52 deletions(-)\n create mode 100755 t/t2405-worktree-submodules.sh\n\n-- \n2.20.0.482.g66447595a7\n\n"},{"id":"366802","messageId":"20190116103159.9305-2-pclouds@gmail.com","threadId":"50239","inReplyTo":"20190116103159.9305-1-pclouds@gmail.com","subject":"[PATCH 01/10] doc: about submodule support with multiple worktrees","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2019-01-16T10:31:50Z","receivedAt":"2019-01-16T10:32:15Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This lays out the very first step of making multiple worktrees and\nsubmodules work together.\n\nThe first problem is git-submodule keeps per-worktree config in\n$GIT_DIR/config, which is shared for all worktrees. This series makes\ngit-submodule use extensions.worktreeConfig and write submodule.* to\nconfig.worktree instead.\n\nThe rest goes on and on about the remaining problems. But let's talk a\nbit more about solving the first problem. Since it relies on the\nexperimental extensions.worktreeConfig, this support is of course also\nexperimental. On the other hand, submodules have never really worked\nwith multi worktrees before, this change can't bite anybody.\n\nSecond problem. That is about multiple worktrees at superproject\nlevel. At submodule level, we still can't have multiple worktrees\nbecause git-submodule writes to submodule's \"config\" file\n(again). Fixing this is not particularly hard. Absorbing submodule's\ngit dir takes some work but is feasible. This could be addressed soon\nin the future.\n\nThe third problem is a big and complicaed one. Submodule clones\n(inside the superproject) are per-worktree. So if you have two\nworktrees, and these have one submodule, you need space for _two_\nclones. This is definitely not elegant. The tenative plan is to move\nclones from $GIT_COMMON_DIR/worktrees/X/modules to\n$GIT_COMMON_DIR/common/modules.\n\nThe latter directory is shared across all worktrees. Once we keep the\nclone in a common place, the submodule's worktree can be created and\nmanaged with git-worktree[1].\n\nAnother good point about this approach is we could finally safely\nallow \"git worktree remove\" to work with submodules. With current\nsolution, removing $GIT_COMMON_DIR/worktrees/X directory means also\nremoving potentially precious clones inside the \"modules\" subdir.\n\nBut whether we can do this depends on:\n\n- if we need separate ref namespace for submodule on each worktree\n\n- how does submodule's worktrees (remember the second problem)\n  interact these worktrees\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Documentation/git-worktree.txt  |  8 ++++++++\n Documentation/gitsubmodules.txt | 17 +++++++++++++++++\n 2 files changed, 25 insertions(+)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex aae8e1d8b2..3510fd5331 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -267,6 +267,14 @@ configuration that you do not want to share to all working trees:\n  - `core.sparseCheckout` is recommended per working tree, unless you\n    are sure you always use sparse checkout for all working trees.\n \n+ - Most configuration variables under `submodule` group in superproject\n+   should not be shared.\n++\n+------------\n+$ git config --local --move-to --worktree submodule.active\n+$ git config --local --move-to-regexp --worktree 'submodule\\..*\\..*'\n+------------\n+\n DETAILS\n -------\n Each linked working tree has a private sub-directory in the repository's\ndiff --git a/Documentation/gitsubmodules.txt b/Documentation/gitsubmodules.txt\nindex 57999e9f36..d91817b45d 100644\n--- a/Documentation/gitsubmodules.txt\n+++ b/Documentation/gitsubmodules.txt\n@@ -222,6 +222,23 @@ submodule active pathspec, which specifies that any submodule\n starting with 'b' except 'baz' are also active, regardless of the\n presence of the .url field.\n \n+MULTIPLE WORKING TREE SUPPORT\n+-----------------------------\n+When you have more than one working tree, created by\n+linkgit:git-worktree[1], submodules will not work on any working tree\n+until `extensions.worktreeConfig` is enabled. Since this config\n+affects more than just submodules, please see \"CONFIGURATION FILE\"\n+section for more information before turning it on.\n+\n+Once on, submodules can be added in any working tree. The submodule\n+itself though cannot have more than one working tree.\n+\n+When submodules are created in a working tree, their git directory is\n+also per-worktree, e.g. inside\n+'$GIT_COMMON_DIR/worktrees/<worktree>/modules' and not shared with\n+other working trees. This means if you have the same submodule on\n+different working trees, you need disk space for multiple clones.\n+\n Workflow for a third party library\n ----------------------------------\n \n-- \n2.20.0.482.g66447595a7\n\n"},{"id":"366803","messageId":"20190116103159.9305-3-pclouds@gmail.com","threadId":"50239","inReplyTo":"20190116103159.9305-1-pclouds@gmail.com","subject":"[PATCH 02/10] submodule--helper: add missing \\n","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2019-01-16T10:31:51Z","receivedAt":"2019-01-16T10:32:19Z","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 builtin/submodule--helper.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex d38113a31a..232bfaac7f 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1297,7 +1297,7 @@ static int add_possible_reference_from_superproject(\n \t\t\t\tdie(_(\"submodule '%s' cannot add alternate: %s\"),\n \t\t\t\t    sas->submodule_name, err.buf);\n \t\t\tcase SUBMODULE_ALTERNATE_ERROR_INFO:\n-\t\t\t\tfprintf(stderr, _(\"submodule '%s' cannot add alternate: %s\"),\n+\t\t\t\tfprintf(stderr, _(\"submodule '%s' cannot add alternate: %s\\n\"),\n \t\t\t\t\tsas->submodule_name, err.buf);\n \t\t\tcase SUBMODULE_ALTERNATE_ERROR_IGNORE:\n \t\t\t\t; /* nothing */\n-- \n2.20.0.482.g66447595a7\n\n"},{"id":"366804","messageId":"20190116103159.9305-4-pclouds@gmail.com","threadId":"50239","inReplyTo":"20190116103159.9305-1-pclouds@gmail.com","subject":"[PATCH 03/10] submodule add: support multiple worktrees","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2019-01-16T10:31:52Z","receivedAt":"2019-01-16T10:32:26Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"The entire submodule section in the superproject will be per-worktree\nand written to $GIT_DIR/config.worktree.\n\nThe behavior when you only have one worktree (and not enabled\nextensions.worktreeConfig) is the same as before, everything is still\nwritten in $GIT_DIR/config\n\n'submodule-helper config --check-writable' also checks if it's\nsupported worktree configuration.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/submodule--helper.c    | 17 +++++++++++++-\n git-submodule.sh               |  8 +++----\n t/t2405-worktree-submodules.sh | 42 ++++++++++++++++++++++++++++++++++\n 3 files changed, 61 insertions(+), 6 deletions(-)\n create mode 100755 t/t2405-worktree-submodules.sh\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 232bfaac7f..7b328ec060 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -18,6 +18,7 @@\n #include \"diffcore.h\"\n #include \"diff.h\"\n #include \"object-store.h\"\n+#include \"worktree.h\"\n \n #define OPT_QUIET (1 << 0)\n #define OPT_CACHED (1 << 1)\n@@ -27,6 +28,18 @@\n typedef void (*each_submodule_fn)(const struct cache_entry *list_item,\n \t\t\t\t  void *cb_data);\n \n+static void check_multi_worktree_support(void)\n+{\n+\tchar *worktree_config = get_worktree_config(the_repository);\n+\tif (!worktree_config)\n+\t\tdie(_(\"submodules cannot be used with multiple \"\n+\t\t      \"working trees unless the config\\n\"\n+\t\t      \"extension worktreeConfig is enabled. \"\n+\t\t      \"Please read \\\"CONFIGURATION FILE\\\"\\n\"\n+\t\t      \"section in \\\"git help worktree\\\" for details\"));\n+\tfree(worktree_config);\n+}\n+\n static char *get_default_remote(void)\n {\n \tchar *dest = NULL, *ret;\n@@ -2162,8 +2175,10 @@ static int module_config(int argc, const char **argv, const char *prefix)\n \targc = parse_options(argc, argv, prefix, module_config_options,\n \t\t\t     git_submodule_helper_usage, PARSE_OPT_KEEP_ARGV0);\n \n-\tif (argc == 1 && command == CHECK_WRITEABLE)\n+\tif (argc == 1 && command == CHECK_WRITEABLE) {\n+\t\tcheck_multi_worktree_support();\n \t\treturn is_writing_gitmodules_ok() ? 0 : -1;\n+\t}\n \n \t/* Equivalent to ACTION_GET in builtin/config.c */\n \tif (argc == 2)\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 5e608f8bad..695939eff9 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -288,7 +288,7 @@ or you are unsure what this means choose another name with the '--name' option.\"\n \t\t\tesac\n \t\t) || die \"$(eval_gettext \"Unable to checkout submodule '\\$sm_path'\")\"\n \tfi\n-\tgit config submodule.\"$sm_name\".url \"$realrepo\"\n+\tgit config --worktree submodule.\"$sm_name\".url \"$realrepo\"\n \n \tgit add --no-warn-embedded-repo $force \"$sm_path\" ||\n \tdie \"$(eval_gettext \"Failed to add submodule '\\$sm_path'\")\"\n@@ -302,18 +302,16 @@ or you are unsure what this means choose another name with the '--name' option.\"\n \tgit add --force .gitmodules ||\n \tdie \"$(eval_gettext \"Failed to register submodule '\\$sm_path'\")\"\n \n-\t# NEEDSWORK: In a multi-working-tree world, this needs to be\n-\t# set in the per-worktree config.\n \tif git config --get submodule.active >/dev/null\n \tthen\n \t\t# If the submodule being adding isn't already covered by the\n \t\t# current configured pathspec, set the submodule's active flag\n \t\tif ! git submodule--helper is-active \"$sm_path\"\n \t\tthen\n-\t\t\tgit config submodule.\"$sm_name\".active \"true\"\n+\t\t\tgit config --worktree submodule.\"$sm_name\".active \"true\"\n \t\tfi\n \telse\n-\t\tgit config submodule.\"$sm_name\".active \"true\"\n+\t\tgit config --worktree submodule.\"$sm_name\".active \"true\"\n \tfi\n }\n \ndiff --git a/t/t2405-worktree-submodules.sh b/t/t2405-worktree-submodules.sh\nnew file mode 100755\nindex 0000000000..3ee5380e88\n--- /dev/null\n+++ b/t/t2405-worktree-submodules.sh\n@@ -0,0 +1,42 @@\n+#!/bin/sh\n+\n+test_description='multiple worktrees as superprojects'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'set up submodule source' '\n+\ttest_create_repo submodsrc &&\n+\t(\n+\t\tcd submodsrc &&\n+\t\ttest_commit one\n+\t) &&\n+\ttest_commit initial &&\n+\tgit worktree add -b secondary secondary HEAD &&\n+\tgit config extensions.worktreeConfig true\n+'\n+\n+test_expect_success 'add submodules' '\n+\tSRC=\"$(pwd)/submodsrc\" &&\n+\tgit submodule add \"$SRC\" sub1 &&\n+\tgit commit -m sub1 &&\n+\tgit -C secondary submodule add \"$SRC\" sub2 &&\n+\tgit -C secondary commit -m sub2 &&\n+\n+\tgit config --get-regexp \"submodule.*\" | sort >actual1 &&\n+\tcat >expected1 <<-EOF &&\n+\tsubmodule.sub1.active true\n+\tsubmodule.sub1.url $(pwd)/submodsrc\n+\tEOF\n+\ttest_cmp expected1 actual1 &&\n+\ttest -d .git/modules/sub1 &&\n+\n+\tgit -C secondary config --get-regexp \"submodule.*\" | sort >actual2 &&\n+\tcat >expected2 <<-EOF &&\n+\tsubmodule.sub2.active true\n+\tsubmodule.sub2.url $(pwd)/submodsrc\n+\tEOF\n+\ttest_cmp expected2 actual2 &&\n+\ttest -d .git/worktrees/secondary/modules/sub2\n+'\n+\n+test_done\n-- \n2.20.0.482.g66447595a7\n\n"},{"id":"366805","messageId":"20190116103159.9305-5-pclouds@gmail.com","threadId":"50239","inReplyTo":"20190116103159.9305-1-pclouds@gmail.com","subject":"[PATCH 04/10] submodule init: support multiple worktrees","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2019-01-16T10:31:53Z","receivedAt":"2019-01-16T10:32:32Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"The entire submodule section in the superproject will be per-worktree\nand written to $GIT_DIR/config.worktree.\n\nThe behavior when you only have one worktree (and not enabled\nextensions.worktreeConfig) is the same as before, everything is still\nwritten in $GIT_DIR/config\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/submodule--helper.c    | 14 +++++---------\n t/t2405-worktree-submodules.sh | 28 ++++++++++++++++++++++++++++\n 2 files changed, 33 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 7b328ec060..6b749b41fb 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -639,15 +639,11 @@ static void init_submodule(const char *path, const char *prefix,\n \t\tdie(_(\"No url found for submodule path '%s' in .gitmodules\"),\n \t\t\tdisplaypath);\n \n-\t/*\n-\t * NEEDSWORK: In a multi-working-tree world, this needs to be\n-\t * set in the per-worktree config.\n-\t *\n-\t * Set active flag for the submodule being initialized\n-\t */\n+\tcheck_multi_worktree_support();\n+\n \tif (!is_submodule_active(the_repository, path)) {\n \t\tstrbuf_addf(&sb, \"submodule.%s.active\", sub->name);\n-\t\tgit_config_set_gently(sb.buf, \"true\");\n+\t\trepo_config_set_worktree_gently(the_repository, sb.buf, \"true\");\n \t\tstrbuf_reset(&sb);\n \t}\n \n@@ -672,7 +668,7 @@ static void init_submodule(const char *path, const char *prefix,\n \t\t\tfree(oldurl);\n \t\t}\n \n-\t\tif (git_config_set_gently(sb.buf, url))\n+\t\tif (repo_config_set_worktree_gently(the_repository, sb.buf, url))\n \t\t\tdie(_(\"Failed to register url for submodule path '%s'\"),\n \t\t\t    displaypath);\n \t\tif (!(flags & OPT_QUIET))\n@@ -693,7 +689,7 @@ static void init_submodule(const char *path, const char *prefix,\n \t\t} else\n \t\t\tupd = xstrdup(submodule_strategy_to_string(&sub->update_strategy));\n \n-\t\tif (git_config_set_gently(sb.buf, upd))\n+\t\tif (repo_config_set_worktree_gently(the_repository, sb.buf, upd))\n \t\t\tdie(_(\"Failed to register update mode for submodule path '%s'\"), displaypath);\n \t}\n \tstrbuf_release(&sb);\ndiff --git a/t/t2405-worktree-submodules.sh b/t/t2405-worktree-submodules.sh\nindex 3ee5380e88..2ee3e2d039 100755\n--- a/t/t2405-worktree-submodules.sh\n+++ b/t/t2405-worktree-submodules.sh\n@@ -39,4 +39,32 @@ test_expect_success 'add submodules' '\n \ttest -d .git/worktrees/secondary/modules/sub2\n '\n \n+test_expect_success 'init submodules' '\n+\tgit clone --no-local .git cloned &&\n+\t(\n+\t\tcd cloned &&\n+\t\tgit config extensions.worktreeConfig true &&\n+\t\tgit submodule init sub1 &&\n+\t\tgit worktree add secondary origin/secondary &&\n+\t\tcd secondary &&\n+\t\tgit submodule init sub2\n+\t) &&\n+\n+\tgit -C cloned config --get-regexp \"submodule.*\" | sort >actual1 &&\n+\tcat >expected1 <<-EOF &&\n+\tsubmodule.sub1.active true\n+\tsubmodule.sub1.url $(pwd)/submodsrc\n+\tEOF\n+\ttest_cmp expected1 actual1 &&\n+\t! test -d cloned/.git/modules/sub1 &&\n+\n+\tgit -C cloned/secondary config --get-regexp \"submodule.*\" | sort >actual2 &&\n+\tcat >expected2 <<-EOF &&\n+\tsubmodule.sub2.active true\n+\tsubmodule.sub2.url $(pwd)/submodsrc\n+\tEOF\n+\ttest_cmp expected2 actual2 &&\n+\t! test -d cloned/.git/worktrees/secondary/modules/sub2\n+'\n+\n test_done\n-- \n2.20.0.482.g66447595a7\n\n"},{"id":"366806","messageId":"20190116103159.9305-6-pclouds@gmail.com","threadId":"50239","inReplyTo":"20190116103159.9305-1-pclouds@gmail.com","subject":"[PATCH 05/10] submodule update: add tests for multiple worktrees","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2019-01-16T10:31:54Z","receivedAt":"2019-01-16T10:32:37Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"There are no changes needed for 'submodule update'. The clones will be\nper-worktree and all the support is already in place. Add a test to\nmake sure it actually works.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n t/t2405-worktree-submodules.sh | 11 +++++++++++\n 1 file changed, 11 insertions(+)\n\ndiff --git a/t/t2405-worktree-submodules.sh b/t/t2405-worktree-submodules.sh\nindex 2ee3e2d039..c1b19ad613 100755\n--- a/t/t2405-worktree-submodules.sh\n+++ b/t/t2405-worktree-submodules.sh\n@@ -67,4 +67,15 @@ test_expect_success 'init submodules' '\n \t! test -d cloned/.git/worktrees/secondary/modules/sub2\n '\n \n+test_expect_success 'update submodules' '\n+\t(\n+\t\tcd cloned &&\n+\t\tgit submodule update sub1 &&\n+\t\tcd secondary &&\n+\t\tgit submodule update sub2\n+\t) &&\n+\ttest -d cloned/.git/modules/sub1 &&\n+\ttest -d cloned/.git/worktrees/secondary/modules/sub2\n+'\n+\n test_done\n-- \n2.20.0.482.g66447595a7\n\n"},{"id":"366807","messageId":"20190116103159.9305-7-pclouds@gmail.com","threadId":"50239","inReplyTo":"20190116103159.9305-1-pclouds@gmail.com","subject":"[PATCH 06/10] submodule sync: support multiple worktrees","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2019-01-16T10:31:55Z","receivedAt":"2019-01-16T10:32:43Z","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 builtin/submodule--helper.c    | 12 +++++++-----\n t/t2405-worktree-submodules.sh | 33 +++++++++++++++++++++++++++++++++\n 2 files changed, 40 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 6b749b41fb..288858af83 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -939,6 +939,7 @@ static void sync_submodule(const char *path, const char *prefix,\n \tstruct strbuf sb = STRBUF_INIT;\n \tstruct child_process cp = CHILD_PROCESS_INIT;\n \tchar *sub_config_path = NULL;\n+\tstruct repository subrepo;\n \n \tif (!is_submodule_active(the_repository, path))\n \t\treturn;\n@@ -979,7 +980,7 @@ static void sync_submodule(const char *path, const char *prefix,\n \n \tstrbuf_reset(&sb);\n \tstrbuf_addf(&sb, \"submodule.%s.url\", sub->name);\n-\tif (git_config_set_gently(sb.buf, super_config_url))\n+\tif (repo_config_set_worktree_gently(the_repository, sb.buf, super_config_url))\n \t\tdie(_(\"failed to register url for submodule path '%s'\"),\n \t\t      displaypath);\n \n@@ -1000,14 +1001,15 @@ static void sync_submodule(const char *path, const char *prefix,\n \tstrbuf_strip_suffix(&sb, \"\\n\");\n \tremote_key = xstrfmt(\"remote.%s.url\", sb.buf);\n \n-\tstrbuf_reset(&sb);\n-\tsubmodule_to_gitdir(&sb, path);\n-\tstrbuf_addstr(&sb, \"/config\");\n+\tif (repo_submodule_init(&subrepo, the_repository, path))\n+\t\tdie(_(\"could not get a repository handle for submodule '%s'\"), path);\n \n-\tif (git_config_set_in_file_gently(sb.buf, remote_key, sub_origin_url))\n+\tif (repo_config_set_worktree_gently(&subrepo, remote_key, sub_origin_url))\n \t\tdie(_(\"failed to update remote for submodule '%s'\"),\n \t\t      path);\n \n+\trepo_clear(&subrepo);\n+\n \tif (flags & OPT_RECURSIVE) {\n \t\tstruct child_process cpr = CHILD_PROCESS_INIT;\n \ndiff --git a/t/t2405-worktree-submodules.sh b/t/t2405-worktree-submodules.sh\nindex c1b19ad613..55daace672 100755\n--- a/t/t2405-worktree-submodules.sh\n+++ b/t/t2405-worktree-submodules.sh\n@@ -78,4 +78,37 @@ test_expect_success 'update submodules' '\n \ttest -d cloned/.git/worktrees/secondary/modules/sub2\n '\n \n+test_expect_success 'sync submodules' '\n+\tsed s/submodsrc/crsdombus/ .gitmodules >temp &&\n+\tmv temp .gitmodules &&\n+\tgit submodule sync &&\n+\t(\n+\t\tcd secondary &&\n+\t\tsed s/submodsrc/crsdombus/ .gitmodules >temp &&\n+\t\tmv temp .gitmodules &&\n+\t\tgit submodule sync\n+\t) &&\n+\n+\tgit config --get-regexp \"submodule.*\" | sort >actual1 &&\n+\tcat >expected1 <<-EOF &&\n+\tsubmodule.sub1.active true\n+\tsubmodule.sub1.url $(pwd)/crsdombus\n+\tEOF\n+\ttest_cmp expected1 actual1 &&\n+\n+\tgit -C secondary config --get-regexp \"submodule.*\" | sort >actual2 &&\n+\tcat >expected2 <<-EOF &&\n+\tsubmodule.sub2.active true\n+\tsubmodule.sub2.url $(pwd)/crsdombus\n+\tEOF\n+\ttest_cmp expected2 actual2\n+'\n+\n+test_expect_success 'reset sync submodules' '\n+\tgit checkout -- .gitmodules &&\n+\tgit submodule sync &&\n+\tgit -C secondary checkout -- .gitmodules &&\n+\tgit -C secondary submodule sync\n+'\n+\n test_done\n-- \n2.20.0.482.g66447595a7\n\n"},{"id":"366808","messageId":"20190116103159.9305-8-pclouds@gmail.com","threadId":"50239","inReplyTo":"20190116103159.9305-1-pclouds@gmail.com","subject":"[PATCH 07/10] submodule deinit: support multiple worktrees","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2019-01-16T10:31:56Z","receivedAt":"2019-01-16T10:32:50Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This is the reverse of 'init' or 'add', config from superproject is\nremoved from config.worktree (or just config in standard single\nworktree setup)\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/submodule--helper.c    |  8 ++++++--\n t/t2405-worktree-submodules.sh | 11 +++++++++++\n 2 files changed, 17 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 288858af83..8943127ae7 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1097,6 +1097,8 @@ static void deinit_submodule(const char *path, const char *prefix,\n \tstruct strbuf sb_config = STRBUF_INIT;\n \tchar *sub_git_dir = xstrfmt(\"%s/.git\", path);\n \n+\tcheck_multi_worktree_support();\n+\n \tsub = submodule_from_path(the_repository, &null_oid, path);\n \n \tif (!sub || !sub->name)\n@@ -1150,21 +1152,23 @@ static void deinit_submodule(const char *path, const char *prefix,\n \t\t      displaypath);\n \n \tcp_config.git_cmd = 1;\n-\targv_array_pushl(&cp_config.args, \"config\", \"--get-regexp\", NULL);\n+\targv_array_pushl(&cp_config.args, \"config\", \"--worktree\", \"--get-regexp\", NULL);\n \targv_array_pushf(&cp_config.args, \"submodule.%s\\\\.\", sub->name);\n \n \t/* remove the .git/config entries (unless the user already did it) */\n \tif (!capture_command(&cp_config, &sb_config, 0) && sb_config.len) {\n+\t\tchar *config_file = get_worktree_config(the_repository);\n \t\tchar *sub_key = xstrfmt(\"submodule.%s\", sub->name);\n \t\t/*\n \t\t * remove the whole section so we have a clean state when\n \t\t * the user later decides to init this submodule again\n \t\t */\n-\t\tgit_config_rename_section_in_file(NULL, sub_key, NULL);\n+\t\tgit_config_rename_section_in_file(config_file, sub_key, NULL);\n \t\tif (!(flags & OPT_QUIET))\n \t\t\tprintf(_(\"Submodule '%s' (%s) unregistered for path '%s'\\n\"),\n \t\t\t\t sub->name, sub->url, displaypath);\n \t\tfree(sub_key);\n+\t\tfree(config_file);\n \t}\n \n cleanup:\ndiff --git a/t/t2405-worktree-submodules.sh b/t/t2405-worktree-submodules.sh\nindex 55daace672..8d53f639c9 100755\n--- a/t/t2405-worktree-submodules.sh\n+++ b/t/t2405-worktree-submodules.sh\n@@ -111,4 +111,15 @@ test_expect_success 'reset sync submodules' '\n \tgit -C secondary submodule sync\n '\n \n+test_expect_success 'deinit submodules' '\n+\tgit submodule deinit sub1 &&\n+\tgit -C secondary submodule deinit sub2 &&\n+\tgit config --get-regexp \"submodule.*\" | sort >actual1 &&\n+\ttest_must_be_empty actual1 &&\n+\ttest -d .git/modules/sub1 &&\n+\tgit -C secondary config --get-regexp \"submodule.*\" | sort >actual2 &&\n+\ttest_must_be_empty actual2 &&\n+\ttest -d .git/worktrees/secondary/modules/sub2\n+'\n+\n test_done\n-- \n2.20.0.482.g66447595a7\n\n"},{"id":"366809","messageId":"20190116103159.9305-9-pclouds@gmail.com","threadId":"50239","inReplyTo":"20190116103159.9305-1-pclouds@gmail.com","subject":"[PATCH 08/10] submodule clone: use repo_config_set()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2019-01-16T10:31:57Z","receivedAt":"2019-01-16T10:32:55Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Avoid direct access to $SUBMODULE/config and do it through\nrepo_config_set() instead. Note that repo_submodule_init() cannot be\nused because this early in the submodule initialization process, we\nmay fail to get and parse .gitmodules with submodule_from_path().\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/submodule--helper.c | 24 +++++++-----------------\n config.c                    | 10 ++++++++++\n config.h                    |  1 +\n repository.c                | 21 ++++++++++++++-------\n repository.h                |  4 ++++\n 5 files changed, 36 insertions(+), 24 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 8943127ae7..b5d74cd415 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1366,11 +1366,11 @@ static int module_clone(int argc, const char **argv, const char *prefix)\n \tconst char *name = NULL, *url = NULL, *depth = NULL;\n \tint quiet = 0;\n \tint progress = 0;\n-\tchar *p, *path = NULL, *sm_gitdir;\n+\tchar *path = NULL, *sm_gitdir;\n \tstruct strbuf sb = STRBUF_INIT;\n \tstruct string_list reference = STRING_LIST_INIT_NODUP;\n \tint dissociate = 0;\n-\tchar *sm_alternate = NULL, *error_strategy = NULL;\n+\tstruct repository subrepo;\n \n \tstruct option module_clone_options[] = {\n \t\tOPT_STRING(0, \"prefix\", &prefix,\n@@ -1443,27 +1443,17 @@ static int module_clone(int argc, const char **argv, const char *prefix)\n \n \tconnect_work_tree_and_git_dir(path, sm_gitdir, 0);\n \n-\tp = git_pathdup_submodule(path, \"config\");\n-\tif (!p)\n-\t\tdie(_(\"could not get submodule directory for '%s'\"), path);\n+\tif (repo_submodule_init_by_name(&subrepo, the_repository, path, name))\n+\t\tdie(_(\"could not get a repository handle for submodule '%s'\"), path);\n \n \t/* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */\n-\tgit_config_get_string(\"submodule.alternateLocation\", &sm_alternate);\n-\tif (sm_alternate)\n-\t\tgit_config_set_in_file(p, \"submodule.alternateLocation\",\n-\t\t\t\t\t   sm_alternate);\n-\tgit_config_get_string(\"submodule.alternateErrorStrategy\", &error_strategy);\n-\tif (error_strategy)\n-\t\tgit_config_set_in_file(p, \"submodule.alternateErrorStrategy\",\n-\t\t\t\t\t   error_strategy);\n-\n-\tfree(sm_alternate);\n-\tfree(error_strategy);\n+\trepo_config_copy(&subrepo, the_repository, \"submodule.alternateLocation\");\n+\trepo_config_copy(&subrepo, the_repository, \"submodule.alternateErrorStrategy\");\n \n+\trepo_clear(&subrepo);\n \tstrbuf_release(&sb);\n \tfree(sm_gitdir);\n \tfree(path);\n-\tfree(p);\n \treturn 0;\n }\n \ndiff --git a/config.c b/config.c\nindex 151d28664e..007436b382 100644\n--- a/config.c\n+++ b/config.c\n@@ -2157,6 +2157,16 @@ void repo_config_set(struct repository *r, const char *key, const char *value)\n \t\tdie(_(\"could not unset '%s'\"), key);\n }\n \n+void repo_config_copy(struct repository *dst, struct repository *src, const char *key)\n+{\n+\tchar *value = NULL;\n+\n+\trepo_config_get_string(src, key, &value);\n+\tif (value)\n+\t\trepo_config_set(dst, key, value);\n+\tfree(value);\n+}\n+\n int repo_config_set_worktree_gently(struct repository *r,\n \t\t\t\t    const char *key, const char *value)\n {\ndiff --git a/config.h b/config.h\nindex 62204dc252..22edd96716 100644\n--- a/config.h\n+++ b/config.h\n@@ -105,6 +105,7 @@ extern void git_config_set_in_file(const char *, const char *, const char *);\n extern int git_config_set_gently(const char *, const char *);\n extern int repo_config_set_gently(struct repository *, const char *, const char *);\n extern void repo_config_set(struct repository *, const char *, const char *);\n+extern void repo_config_copy(struct repository *dst, struct repository *src, const char *key);\n extern int repo_config_set_worktree_gently(struct repository *, const char *, const char *);\n extern void git_config_set(const char *, const char *);\n extern int git_config_parse_key(const char *, char **, int *);\ndiff --git a/repository.c b/repository.c\nindex 5dd1486718..f997bd1629 100644\n--- a/repository.c\n+++ b/repository.c\n@@ -176,16 +176,23 @@ int repo_submodule_init(struct repository *submodule,\n \t\t\tconst char *path)\n {\n \tconst struct submodule *sub;\n+\n+\tsub = submodule_from_path(superproject, &null_oid, path);\n+\tif (!sub)\n+\t\treturn -1;\n+\treturn repo_submodule_init_by_name(submodule, superproject,\n+\t\t\t\t\t   path, sub->name);\n+}\n+\n+int repo_submodule_init_by_name(struct repository *submodule,\n+\t\t\t\tstruct repository *superproject,\n+\t\t\t\tconst char *path,\n+\t\t\t\tconst char *name)\n+{\n \tstruct strbuf gitdir = STRBUF_INIT;\n \tstruct strbuf worktree = STRBUF_INIT;\n \tint ret = 0;\n \n-\tsub = submodule_from_path(superproject, &null_oid, path);\n-\tif (!sub) {\n-\t\tret = -1;\n-\t\tgoto out;\n-\t}\n-\n \tstrbuf_repo_worktree_path(&gitdir, superproject, \"%s/.git\", path);\n \tstrbuf_repo_worktree_path(&worktree, superproject, \"%s\", path);\n \n@@ -199,7 +206,7 @@ int repo_submodule_init(struct repository *submodule,\n \t\t */\n \t\tstrbuf_reset(&gitdir);\n \t\tstrbuf_repo_git_path(&gitdir, superproject,\n-\t\t\t\t     \"modules/%s\", sub->name);\n+\t\t\t\t     \"modules/%s\", name);\n \n \t\tif (repo_init(submodule, gitdir.buf, NULL)) {\n \t\t\tret = -1;\ndiff --git a/repository.h b/repository.h\nindex 9f16c42c1e..d3f0592471 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -119,6 +119,10 @@ int repo_init(struct repository *r, const char *gitdir, const char *worktree);\n int repo_submodule_init(struct repository *submodule,\n \t\t\tstruct repository *superproject,\n \t\t\tconst char *path);\n+int repo_submodule_init_by_name(struct repository *submodule,\n+\t\t\t\tstruct repository *superproject,\n+\t\t\t\tconst char *path,\n+\t\t\t\tconst char *name);\n void repo_clear(struct repository *repo);\n \n /*\n-- \n2.20.0.482.g66447595a7\n\n"},{"id":"366810","messageId":"20190116103159.9305-10-pclouds@gmail.com","threadId":"50239","inReplyTo":"20190116103159.9305-1-pclouds@gmail.com","subject":"[PATCH 09/10] submodule clone: propagate extensions.worktreeConfig","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2019-01-16T10:31:58Z","receivedAt":"2019-01-16T10:33:01Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"If this extension is already enabled on the superproject, the user\nlikes to use multiple worktrees very much and is already aware of\nit. Enable it in submodules too so that when they want to make\nsecondary submodule worktrees, they will not be worried about enabling\nit or migrating per-worktree config away.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/submodule--helper.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex b5d74cd415..8a12d2f0ed 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -1449,6 +1449,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)\n \t/* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */\n \trepo_config_copy(&subrepo, the_repository, \"submodule.alternateLocation\");\n \trepo_config_copy(&subrepo, the_repository, \"submodule.alternateErrorStrategy\");\n+\trepo_config_copy(&subrepo, the_repository, \"extensions.worktreeConfig\");\n \n \trepo_clear(&subrepo);\n \tstrbuf_release(&sb);\n-- \n2.20.0.482.g66447595a7\n\n"},{"id":"366811","messageId":"20190116103159.9305-11-pclouds@gmail.com","threadId":"50239","inReplyTo":"20190116103159.9305-1-pclouds@gmail.com","subject":"[PATCH 10/10] submodule ensure-core-worktree: write to config.worktree","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2019-01-16T10:31:59Z","receivedAt":"2019-01-16T10:33:09Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Use repo_config_set_worktree_gently() to write core.worktree. If the\nsubmodule has extensions.worktreeConfig on, the key will be in\nconfig.worktree instead of config file and not affect any new\nsubmodule's worktrees.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/submodule--helper.c | 8 +++-----\n 1 file changed, 3 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 8a12d2f0ed..890de5902c 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -2063,18 +2063,16 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)\n \t\tdie(_(\"could not get a repository handle for submodule '%s'\"), path);\n \n \tif (!repo_config_get_string(&subrepo, \"core.worktree\", &cw)) {\n-\t\tchar *cfg_file, *abs_path;\n+\t\tchar *abs_path;\n \t\tconst char *rel_path;\n \t\tstruct strbuf sb = STRBUF_INIT;\n \n-\t\tcfg_file = repo_git_path(&subrepo, \"config\");\n-\n \t\tabs_path = absolute_pathdup(path);\n \t\trel_path = relative_path(abs_path, subrepo.gitdir, &sb);\n \n-\t\tgit_config_set_in_file(cfg_file, \"core.worktree\", rel_path);\n+\t\tif (repo_config_set_worktree_gently(&subrepo, \"core.worktree\", rel_path))\n+\t\t\tdie(_(\"could not set '%s' to '%s'\"), \"core.worktree\", rel_path);\n \n-\t\tfree(cfg_file);\n \t\tfree(abs_path);\n \t\tstrbuf_release(&sb);\n \t}\n-- \n2.20.0.482.g66447595a7\n\n"},{"id":"366879","messageId":"CAGZ79kYWi0EDr-XvoXm=-Oo-_9FiieNHbWzA5o8TiirLw+xXBg@mail.gmail.com","threadId":"50239","inReplyTo":"20190116103159.9305-2-pclouds@gmail.com","subject":"Re: [PATCH 01/10] doc: about submodule support with multiple worktrees","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2019-01-16T22:06:24Z","receivedAt":"2019-01-16T22:07:36Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"> The third problem is a big and complicaed one. Submodule clones\n\ncomplicated\n\n> (inside the superproject) are per-worktree. So if you have two\n> worktrees, and these have one submodule, you need space for _two_\n> clones. This is definitely not elegant. The tenative plan is to move\n\ntentative?\n\n> clones from $GIT_COMMON_DIR/worktrees/X/modules to\n> $GIT_COMMON_DIR/common/modules.\n\n... from the submodule side of things this is big problem,\nas the submodule is usually assumed at $GIT_DIR/modules/<name>\n(I think we have not been strict in $GIT_DIR $GIT_COMMON_DIR\nin the submodule code)\n\nSo the plan is to neither use\n$GIT_COMMON_DIR/worktrees/X/modules/Y\n$GIT_COMMON_DIR/modules/Y/worktrees/X\nbut to create a new third location at\n$GIT_COMMON_DIR/common/modules\nto which either new submodule worktrees\nor superproject worktrees that happen to have this submodule\ncan point to?\n\n>\n> The latter directory is shared across all worktrees. Once we keep the\n> clone in a common place, the submodule's worktree can be created and\n> managed with git-worktree[1].\n\nSo even when the user has never heard of worktrees, the internal structure\nwill be worktree oriented, the common dir in common/modules/Y and in\n$GIT_DIR/modules/Y we could just have a worktree git dir?\n\n> Another good point about this approach is we could finally safely\n> allow \"git worktree remove\" to work with submodules. With current\n> solution, removing $GIT_COMMON_DIR/worktrees/X directory means also\n> removing potentially precious clones inside the \"modules\" subdir.\n\nyup, very sensible.\n\nI like this approach very much.\n"},{"id":"366880","messageId":"CAGZ79kY73eYTSDqyQAYcqVJn4t9kMNW00_=uPN1yCEwaOij3MA@mail.gmail.com","threadId":"50239","inReplyTo":"20190116103159.9305-4-pclouds@gmail.com","subject":"Re: [PATCH 03/10] submodule add: support multiple worktrees","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2019-01-16T22:27:55Z","receivedAt":"2019-01-16T22:28:11Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"> --- /dev/null\n> +++ b/t/t2405-worktree-submodules.sh\n> @@ -0,0 +1,42 @@\n> +#!/bin/sh\n> +\n> +test_description='multiple worktrees as superprojects'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success 'set up submodule source' '\n> +       test_create_repo submodsrc &&\n> +       (\n> +               cd submodsrc &&\n> +               test_commit one\n> +       ) &&\n\nJust like git itself, test_commit now supports the -C <dir>\nargument, so you could replace the whole subshell with\n\n    test_commit -C submodsrc one &&\n\n\n> +       test_commit initial &&\n> +       git worktree add -b secondary secondary HEAD &&\n\nCould we have multiple things not named the same?\n(i.e. have the the branch and worktree be spelled differently)\nThat way it is less confusing and we'd catch errors of swapping\nthese two in the implementation (unlikely, but...)\n\n> +       git config extensions.worktreeConfig true\n> +'\n> +\n> +test_expect_success 'add submodules' '\n> +       SRC=\"$(pwd)/submodsrc\" &&\n> +       git submodule add \"$SRC\" sub1 &&\n\nyou can also use relative paths in submodules:\n\n    git submodule add ./submodsrc sub1 &&\n\nif you want to.\n\n> +       git commit -m sub1 &&\n> +       git -C secondary submodule add \"$SRC\" sub2 &&\n\nOh never mind, by having the absolute path we\nadd the submodule with the same setting.\n(When using relative path we'd have to use ../submodusrc\nhere, but would that matter?)\n\n> +       git -C secondary commit -m sub2 &&\n> +\n> +       git config --get-regexp \"submodule.*\" | sort >actual1 &&\n> +       cat >expected1 <<-EOF &&\n> +       submodule.sub1.active true\n> +       submodule.sub1.url $(pwd)/submodsrc\n> +       EOF\n> +       test_cmp expected1 actual1 &&\n> +       test -d .git/modules/sub1 &&\n> +\n> +       git -C secondary config --get-regexp \"submodule.*\" | sort >actual2 &&\n> +       cat >expected2 <<-EOF &&\n> +       submodule.sub2.active true\n> +       submodule.sub2.url $(pwd)/submodsrc\n> +       EOF\n> +       test_cmp expected2 actual2 &&\n> +       test -d .git/worktrees/secondary/modules/sub2\n\nThis section is very brittle. For example the way how submodules\nare active changed not so long ago, and might change again, which\nseems unrelated to the thing tested here?\n"},{"id":"366908","messageId":"CACsJy8DV=BF44j8Eu01At1fwD2FH9ANa+7g66xn82du3yhQJKA@mail.gmail.com","threadId":"50239","inReplyTo":"CAGZ79kYWi0EDr-XvoXm=-Oo-_9FiieNHbWzA5o8TiirLw+xXBg@mail.gmail.com","subject":"Re: [PATCH 01/10] doc: about submodule support with multiple worktrees","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2019-01-17T10:22:12Z","receivedAt":"2019-01-17T10:22:41Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Jan 17, 2019 at 5:06 AM Stefan Beller <sbeller@google.com> wrote:\n> > clones from $GIT_COMMON_DIR/worktrees/X/modules to\n> > $GIT_COMMON_DIR/common/modules.\n>\n> ... from the submodule side of things this is big problem,\n> as the submodule is usually assumed at $GIT_DIR/modules/<name>\n> (I think we have not been strict in $GIT_DIR $GIT_COMMON_DIR\n> in the submodule code)\n>\n> So the plan is to neither use\n>\n> $GIT_COMMON_DIR/worktrees/X/modules/Y\n> $GIT_COMMON_DIR/modules/Y/worktrees/X\n>\n> but to create a new third location at\n>\n> $GIT_COMMON_DIR/common/modules\n>\n> to which either new submodule worktrees\n> or superproject worktrees that happen to have this submodule\n> can point to?\n\nYes. And this is yet another \"absorb\" operation to move from the\ncurrent location to the new one. The code will have to check both\nplaces, just as it has to check if \"foo/bar/.git\" is a real repo\nbefore it goes to $GIT_DIR/.git/modules/bar (at least this is how I\nunderstand it).\n\n> > The latter directory is shared across all worktrees. Once we keep the\n> > clone in a common place, the submodule's worktree can be created and\n> > managed with git-worktree[1].\n>\n> So even when the user has never heard of worktrees, the internal structure\n> will be worktree oriented, the common dir in common/modules/Y and in\n> $GIT_DIR/modules/Y we could just have a worktree git dir?\n\nI think the .git dir will be in common/modules/Y. $GIT_DIR/modules/Y\nis basically replaced by $GIT_COMMON_DIR/common/modules/Y, which\nshould work even when you don't use git-worktree (in single-worktree\nsetting, $GIT_COMMON_DIR == $GIT_DIR).\n-- \nDuy\n"}]}