{"thread":{"id":"48277","subject":"[RFC 03/10] submodule: use the 'submodules_file' variable in output messages","startedAt":"2018-04-12T22:57:13Z","lastAt":"2018-04-30T12:51:47Z","messageCount":28,"participants":["Antonio Ospite","Stefan Beller","Jonathan Nieder"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"344569","messageId":"20180412222047.5716-4-ao2@ao2.it","threadId":"48277","inReplyTo":"20180412222047.5716-1-ao2@ao2.it","subject":"[RFC 03/10] submodule: use the 'submodules_file' variable in output messages","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-12T22:20:40Z","receivedAt":"2018-04-12T22:57:13Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"The gitmodules file path can be customized by setting the\n'core.submodulesFile' config option.\n\nUse the 'submodules_file' variable instead of the hardcoded\n'.gitmodules' in output messages, to reflect the actual path of the\ngitmodules file.\n\nNOTE: the default git configuration has to be initialized in\n'builtin/submodule--helper.c' to make the actual value of\n'submodules_file', overridden by 'core.submodulesFile', available to the\nhelper command.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n builtin/mv.c                |  3 ++-\n builtin/rm.c                |  3 ++-\n builtin/submodule--helper.c | 18 ++++++++++--------\n submodule-config.c          |  4 ++--\n submodule.c                 | 14 +++++++-------\n 5 files changed, 23 insertions(+), 19 deletions(-)\n\ndiff --git a/builtin/mv.c b/builtin/mv.c\nindex 6d141f7a5..ec8f139c4 100644\n--- a/builtin/mv.c\n+++ b/builtin/mv.c\n@@ -82,7 +82,8 @@ static void prepare_move_submodule(const char *src, int first,\n \tif (!S_ISGITLINK(active_cache[first]->ce_mode))\n \t\tdie(_(\"Directory %s is in index and no submodule?\"), src);\n \tif (!is_staging_gitmodules_ok(&the_index))\n-\t\tdie(_(\"Please stage your changes to .gitmodules or stash them to proceed\"));\n+\t\tdie(_(\"Please stage your changes to %s or stash them to proceed\"),\n+\t\t    submodules_file);\n \tstrbuf_addf(&submodule_dotgit, \"%s/.git\", src);\n \t*submodule_gitfile = read_gitfile(submodule_dotgit.buf);\n \tif (*submodule_gitfile)\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex 5b6fc7ee8..6fd015d86 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -286,7 +286,8 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t\tlist.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode);\n \t\tif (list.entry[list.nr++].is_submodule &&\n \t\t    !is_staging_gitmodules_ok(&the_index))\n-\t\t\tdie (_(\"Please stage your changes to .gitmodules or stash them to proceed\"));\n+\t\t\tdie (_(\"Please stage your changes to %s or stash them to proceed\"),\n+\t\t\t     submodules_file);\n \t}\n \n \tif (pathspec.nr) {\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex a404df3ea..72b95d27b 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -458,8 +458,8 @@ static void init_submodule(const char *path, const char *prefix,\n \tsub = submodule_from_path(&null_oid, path);\n \n \tif (!sub)\n-\t\tdie(_(\"No url found for submodule path '%s' in .gitmodules\"),\n-\t\t\tdisplaypath);\n+\t\tdie(_(\"No url found for submodule path '%s' in %s\"),\n+\t\t\tdisplaypath, submodules_file);\n \n \t/*\n \t * NEEDSWORK: In a multi-working-tree world, this needs to be\n@@ -481,8 +481,8 @@ static void init_submodule(const char *path, const char *prefix,\n \tstrbuf_addf(&sb, \"submodule.%s.url\", sub->name);\n \tif (git_config_get_string(sb.buf, &url)) {\n \t\tif (!sub->url)\n-\t\t\tdie(_(\"No url found for submodule path '%s' in .gitmodules\"),\n-\t\t\t\tdisplaypath);\n+\t\t\tdie(_(\"No url found for submodule path '%s' in %s\"),\n+\t\t\t\tdisplaypath, submodules_file);\n \n \t\turl = xstrdup(sub->url);\n \n@@ -623,8 +623,8 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,\n \tint diff_files_result;\n \n \tif (!submodule_from_path(&null_oid, path))\n-\t\tdie(_(\"no submodule mapping found in .gitmodules for path '%s'\"),\n-\t\t      path);\n+\t\tdie(_(\"no submodule mapping found in %s for path '%s'\"),\n+\t\t      submodules_file, path);\n \n \tdisplaypath = get_submodule_displaypath(path, prefix);\n \n@@ -749,8 +749,8 @@ static int module_name(int argc, const char **argv, const char *prefix)\n \tsub = submodule_from_path(&null_oid, argv[1]);\n \n \tif (!sub)\n-\t\tdie(_(\"no submodule mapping found in .gitmodules for path '%s'\"),\n-\t\t    argv[1]);\n+\t\tdie(_(\"no submodule mapping found in %s for path '%s'\"),\n+\t\t    submodules_file, argv[1]);\n \n \tprintf(\"%s\\n\", sub->name);\n \n@@ -1855,6 +1855,8 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix)\n \tif (argc < 2 || !strcmp(argv[1], \"-h\"))\n \t\tusage(\"git submodule--helper <command>\");\n \n+\tgit_config(git_default_config, NULL);\n+\n \tfor (i = 0; i < ARRAY_SIZE(commands); i++) {\n \t\tif (!strcmp(argv[1], commands[i].cmd)) {\n \t\t\tif (get_super_prefix() &&\ndiff --git a/submodule-config.c b/submodule-config.c\nindex 8a3396ade..620d522ee 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -347,9 +347,9 @@ static void warn_multiple_config(const unsigned char *treeish_name,\n \tconst char *commit_string = \"WORKTREE\";\n \tif (treeish_name)\n \t\tcommit_string = sha1_to_hex(treeish_name);\n-\twarning(\"%s:.gitmodules, multiple configurations found for \"\n+\twarning(\"%s:%s, multiple configurations found for \"\n \t\t\t\"'submodule.%s.%s'. Skipping second one!\",\n-\t\t\tcommit_string, name, option);\n+\t\t\tcommit_string, submodules_file, name, option);\n }\n \n struct parse_config_parameter {\ndiff --git a/submodule.c b/submodule.c\nindex 2afbdb644..97213b549 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -94,11 +94,11 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath)\n \t\treturn -1;\n \n \tif (is_gitmodules_unmerged(&the_index))\n-\t\tdie(_(\"Cannot change unmerged .gitmodules, resolve merge conflicts first\"));\n+\t\tdie(_(\"Cannot change unmerged %s, resolve merge conflicts first\"), submodules_file);\n \n \tsubmodule = submodule_from_path(&null_oid, oldpath);\n \tif (!submodule || !submodule->name) {\n-\t\twarning(_(\"Could not find section in .gitmodules where path=%s\"), oldpath);\n+\t\twarning(_(\"Could not find section in %s where path=%s\"), submodules_file, oldpath);\n \t\treturn -1;\n \t}\n \tstrbuf_addstr(&entry, \"submodule.\");\n@@ -106,7 +106,7 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath)\n \tstrbuf_addstr(&entry, \".path\");\n \tif (git_config_set_in_file_gently(submodules_file, entry.buf, newpath) < 0) {\n \t\t/* Maybe the user already did that, don't error out here */\n-\t\twarning(_(\"Could not update .gitmodules entry %s\"), entry.buf);\n+\t\twarning(_(\"Could not update %s entry %s\"), submodules_file, entry.buf);\n \t\tstrbuf_release(&entry);\n \t\treturn -1;\n \t}\n@@ -128,18 +128,18 @@ int remove_path_from_gitmodules(const char *path)\n \t\treturn -1;\n \n \tif (is_gitmodules_unmerged(&the_index))\n-\t\tdie(_(\"Cannot change unmerged .gitmodules, resolve merge conflicts first\"));\n+\t\tdie(_(\"Cannot change unmerged %s, resolve merge conflicts first\"), submodules_file);\n \n \tsubmodule = submodule_from_path(&null_oid, path);\n \tif (!submodule || !submodule->name) {\n-\t\twarning(_(\"Could not find section in .gitmodules where path=%s\"), path);\n+\t\twarning(_(\"Could not find section in %s where path=%s\"), submodules_file, path);\n \t\treturn -1;\n \t}\n \tstrbuf_addstr(&sect, \"submodule.\");\n \tstrbuf_addstr(&sect, submodule->name);\n \tif (git_config_rename_section_in_file(submodules_file, sect.buf, NULL) < 0) {\n \t\t/* Maybe the user already did that, don't error out here */\n-\t\twarning(_(\"Could not remove .gitmodules entry for %s\"), path);\n+\t\twarning(_(\"Could not remove %s entry for %s\"), submodules_file, path);\n \t\tstrbuf_release(&sect);\n \t\treturn -1;\n \t}\n@@ -150,7 +150,7 @@ int remove_path_from_gitmodules(const char *path)\n void stage_updated_gitmodules(struct index_state *istate)\n {\n \tif (add_file_to_index(istate, submodules_file, 0))\n-\t\tdie(_(\"staging updated .gitmodules failed\"));\n+\t\tdie(_(\"staging updated %s failed\"), submodules_file);\n }\n \n static int add_submodule_odb(const char *path)\n-- \n2.17.0\n\n"},{"id":"344570","messageId":"20180412222047.5716-1-ao2@ao2.it","threadId":"48277","inReplyTo":null,"subject":"[RFC 00/10] Make .the gitmodules file path configurable","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-12T22:20:37Z","receivedAt":"2018-04-12T22:57:16Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Hi,\n\nvcsh[1] uses bare git repositories and detached work-trees to manage\n*distinct* sets of configuration files directly into $HOME.\n\nIn general, submodules have worked perfectly fine with detached\nwork-trees for some time[2,3,4].\n\nHowever when multiple repositories take turns using the same directory\nas their work-tree, and more than one of them want to use submodules,\nthere could still be conflicts about the '.gitmodules' file because git\nhardcodes this path.\n\nFor comparison, in case of '.gitignore' a similar conflict might arise,\nbut git has alternative ways to specify exclude files, so vcsh solves\nthis by setting core.excludesFile for each repository and track ignored\nfiles somewhere else (in ~/.gitignore.d/$VCSH_REPO_NAME).\n\nThis is currently not possible with submodules configuration.\n\nSo this series proposes a mechanism to set an alternative path for the\nsubmodules configuration file (from now on \"gitmodules file\").\n\nPatches are based on fe0a9eaf31dd0c349ae4308498c33a5c3794b293.\n\nIn commit 4c0eeafe4755 (cache.h: add GITMODULES_FILE macro)[5] the\ngitmodules file path definition was centralized, AFAIU this was done\nmainly to prevent typos, as checking a symbolic constant is something\nthe compiler will do for us.\n\nExpanding on that change the first patch in the series makes the path\ncustomizable exposing a 'core.submodulesFile' configuration setting.\n\nThe new configuration setting can be used to set an *alternative*\nlocation for the gitmodules file; IMHO there is no need to provide\n*additional* locations like in the case of exclude files.\n\nFor instance vcsh could set the location to\n'~/.gitmodules.d/$VCSH_REPO_NAME' to avoid conflicts.\n\nSince the gitmodules file is meant to be checked in into the repository,\nthe overridden file path should be relative to the work-tree; is there\na way to enforce this constraint at run time (i.e. validate the config\nvalue), or is it enough to have it documented?\n\nThe last patch adds a hacky 'test-custom-gitmodules-file.sh' script\nwhich patches the test suite to fix all the hardcoded occurrences of\n'.gitmodules' and runs it twice: once with the default value and once\nwith a custom path, passed via an environmental variable.\n\nI guess in the final version just testing for a custom path (e.g.\n'.gitmodules_custom') could be enough, as the default value can be seen\nas a particular case.\n\nThe last thing I noticed is that git does not create config files\nautomatically if they are under a subdirectory which does not exist\nalready; for instance the following command would fail:\n\n  git config -f newsubdir/test-config user.name Antonio\n\nThis means that if the user wanted to use something like:\n\n  git -c core.submodulesFile=.gitmodules.d/repo_submodules ...\n\nthe subdirectory would have to be created beforehand. This is not a big\ndeal of course, but I was wondering if this is mentioned anywhere.\nFixing the current behavior to create the leading directories does not\nseem hard, but I am not sure it is worth it.\n\nThanks,\n   Antonio\n\n[1] https://github.com/RichiH/vcsh\n[2] http://git.661346.n2.nabble.com/git-submodule-vs-GIT-WORK-TREE-td7562165.html\n[3] http://git.661346.n2.nabble.com/PATCH-Solve-git-submodule-issues-with-detached-work-trees-td7563377.html\n[4] https://github.com/git/git/commit/be8779f7ac9a3be9aa783df008d59082f4054f67\n[5] https://github.com/git/git/commit/4c0eeafe4755345b0f4636bf09904cf689703e11\n\nAntonio Ospite (10):\n  submodule: add 'core.submodulesFile' to override the '.gitmodules'\n    path\n  submodule: fix getting custom gitmodule file in fetch command\n  submodule: use the 'submodules_file' variable in output messages\n  submodule: document 'core.submodulesFile' and fix references to\n    '.gitmodules'\n  submodule: adjust references to '.gitmodules' in comments\n  completion: add 'core.submodulesfile' to the git-completion.bash file\n  XXX: wrap-for-bin.sh: set 'core.submodulesFile' for each git\n    invocation\n  XXX: submodule: fix t1300-repo-config.sh to take into account the new\n    config\n  XXX: submodule: pass custom gitmodules file to 'test-tool\n    submodule-config'\n  XXX: add a hacky script to test the changes with a patched test suite\n\n Documentation/config.txt                      | 18 +++--\n Documentation/git-add.txt                     |  4 +-\n Documentation/git-submodule.txt               | 45 +++++------\n Documentation/gitmodules.txt                  | 15 ++--\n Documentation/gitsubmodules.txt               | 18 ++---\n .../technical/api-submodule-config.txt        |  6 +-\n Makefile                                      |  3 +-\n builtin/fetch.c                               |  2 +-\n builtin/mv.c                                  |  3 +-\n builtin/rm.c                                  |  3 +-\n builtin/submodule--helper.c                   | 20 ++---\n cache.h                                       |  1 +\n config.c                                      | 13 ++--\n config.h                                      |  7 +-\n contrib/completion/git-completion.bash        |  1 +\n contrib/subtree/git-subtree.txt               |  2 +-\n environment.c                                 |  1 +\n git-submodule.sh                              | 24 +++---\n repository.h                                  |  2 +-\n submodule-config.c                            | 16 ++--\n submodule-config.h                            |  2 +-\n submodule.c                                   | 54 ++++++-------\n t/helper/test-submodule-config.c              |  7 ++\n t/t0001-init.sh                               |  1 +\n t/t1300-repo-config.sh                        | 26 ++++++-\n test-custom-gitmodules-file.sh                | 75 +++++++++++++++++++\n unpack-trees.c                                |  2 +-\n wrap-for-bin.sh                               |  2 +\n 28 files changed, 250 insertions(+), 123 deletions(-)\n create mode 100755 test-custom-gitmodules-file.sh\n mode change 100644 => 100755 wrap-for-bin.sh\n\n-- \nAntonio Ospite\nhttps://ao2.it\nhttps://twitter.com/ao2it\n\nA: Because it messes up the order in which people normally read text.\n   See http://en.wikipedia.org/wiki/Posting_style\nQ: Why is top-posting such a bad thing?\n"},{"id":"344571","messageId":"20180412222047.5716-3-ao2@ao2.it","threadId":"48277","inReplyTo":"20180412222047.5716-1-ao2@ao2.it","subject":"[RFC 02/10] submodule: fix getting custom gitmodule file in fetch command","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-12T22:20:39Z","receivedAt":"2018-04-12T22:57:19Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Import the default git configuration before accessing the gitmodules\nfile.\n\nThis is important when a value different from the default one is set via\nthe 'core.submodulesfile' config.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n builtin/fetch.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/builtin/fetch.c b/builtin/fetch.c\nindex dcdfc66f0..d56636f74 100644\n--- a/builtin/fetch.c\n+++ b/builtin/fetch.c\n@@ -1428,8 +1428,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n \tfor (i = 1; i < argc; i++)\n \t\tstrbuf_addf(&default_rla, \" %s\", argv[i]);\n \n-\tconfig_from_gitmodules(gitmodules_fetch_config, NULL);\n \tgit_config(git_fetch_config, NULL);\n+\tconfig_from_gitmodules(gitmodules_fetch_config, NULL);\n \n \targc = parse_options(argc, argv, prefix,\n \t\t\t     builtin_fetch_options, builtin_fetch_usage, 0);\n-- \n2.17.0\n\n"},{"id":"344572","messageId":"20180412222047.5716-2-ao2@ao2.it","threadId":"48277","inReplyTo":"20180412222047.5716-1-ao2@ao2.it","subject":"[RFC 01/10] submodule: add 'core.submodulesFile' to override the '.gitmodules' path","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-12T22:20:38Z","receivedAt":"2018-04-12T22:57:23Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"When multiple repositories with detached work-trees take turns using the\nsame directory as their work-tree, and more than one of them want to use\nsubmodules, there will be conflicts about the '.gitmodules' file.\n\ngit hardcodes this path so it's not possible to override its location on\na per-repository basis to allow such repositories to coexists\npeacefully.\n\nMake the path of the \"gitmodules file\" customizable exposing\na 'core.submodulesFile' configuration setting.\n\nThe default value will still be '.gitmodules' when 'core.submodulesFile'\nis not set.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n cache.h            |  1 +\n config.c           |  6 +++++-\n environment.c      |  1 +\n git-submodule.sh   | 14 +++++++++-----\n submodule-config.c |  4 ++--\n submodule.c        | 20 ++++++++++----------\n unpack-trees.c     |  2 +-\n 7 files changed, 29 insertions(+), 19 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex bbaf5c349..f4dd8bc00 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1774,6 +1774,7 @@ extern void prepare_pager_args(struct child_process *, const char *pager);\n extern const char *editor_program;\n extern const char *askpass_program;\n extern const char *excludes_file;\n+extern const char *submodules_file;\n \n /* base85 */\n int decode_85(char *dst, const char *line, int linelen);\ndiff --git a/config.c b/config.c\nindex c698988f5..6ffb1d501 100644\n--- a/config.c\n+++ b/config.c\n@@ -1199,6 +1199,10 @@ static int git_default_core_config(const char *var, const char *value)\n \tif (!strcmp(var, \"core.excludesfile\"))\n \t\treturn git_config_pathname(&excludes_file, var, value);\n \n+\tif (!strcmp(var, \"core.submodulesfile\")) {\n+\t\treturn git_config_pathname(&submodules_file, var, value);\n+\t}\n+\n \tif (!strcmp(var, \"core.whitespace\")) {\n \t\tif (!value)\n \t\t\treturn config_error_nonbool(var);\n@@ -2084,7 +2088,7 @@ int git_config_get_pathname(const char *key, const char **dest)\n void config_from_gitmodules(config_fn_t fn, void *data)\n {\n \tif (the_repository->worktree) {\n-\t\tchar *file = repo_worktree_path(the_repository, GITMODULES_FILE);\n+\t\tchar *file = repo_worktree_path(the_repository, submodules_file);\n \t\tgit_config_from_file(fn, file, data);\n \t\tfree(file);\n \t}\ndiff --git a/environment.c b/environment.c\nindex 39b3d906c..69cae6d68 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -49,6 +49,7 @@ int pager_use_color = 1;\n const char *editor_program;\n const char *askpass_program;\n const char *excludes_file;\n+const char *submodules_file = GITMODULES_FILE;\n enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;\n int check_replace_refs = 1;\n char *git_replace_ref_base;\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 24914963c..610fd0dc5 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -71,7 +71,9 @@ get_submodule_config () {\n \tvalue=$(git config submodule.\"$name\".\"$option\")\n \tif test -z \"$value\"\n \tthen\n-\t\tvalue=$(git config -f .gitmodules submodule.\"$name\".\"$option\")\n+\t\tgitmodules_file=$(git config core.submodulesfile)\n+\t\t: ${gitmodules_file:=.gitmodules}\n+\t\tvalue=$(git config -f \"$gitmodules_file\" submodule.\"$name\".\"$option\")\n \tfi\n \tprintf '%s' \"${value:-$default}\"\n }\n@@ -271,13 +273,15 @@ or you are unsure what this means choose another name with the '--name' option.\"\n \tgit add --no-warn-embedded-repo $force \"$sm_path\" ||\n \tdie \"$(eval_gettext \"Failed to add submodule '\\$sm_path'\")\"\n \n-\tgit config -f .gitmodules submodule.\"$sm_name\".path \"$sm_path\" &&\n-\tgit config -f .gitmodules submodule.\"$sm_name\".url \"$repo\" &&\n+\tgitmodules_file=$(git config core.submodulesfile)\n+\t: ${gitmodules_file:=.gitmodules}\n+\tgit config -f \"$gitmodules_file\" submodule.\"$sm_name\".path \"$sm_path\" &&\n+\tgit config -f \"$gitmodules_file\" submodule.\"$sm_name\".url \"$repo\" &&\n \tif test -n \"$branch\"\n \tthen\n-\t\tgit config -f .gitmodules submodule.\"$sm_name\".branch \"$branch\"\n+\t\tgit config -f \"$gitmodules_file\" submodule.\"$sm_name\".branch \"$branch\"\n \tfi &&\n-\tgit add --force .gitmodules ||\n+\tgit add --force \"$gitmodules_file\" ||\n \tdie \"$(eval_gettext \"Failed to register submodule '\\$sm_path'\")\"\n \n \t# NEEDSWORK: In a multi-working-tree world, this needs to be\ndiff --git a/submodule-config.c b/submodule-config.c\nindex 3f2075764..8a3396ade 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -468,7 +468,7 @@ static int gitmodule_oid_from_commit(const struct object_id *treeish_name,\n \t\treturn 1;\n \t}\n \n-\tstrbuf_addf(rev, \"%s:.gitmodules\", oid_to_hex(treeish_name));\n+\tstrbuf_addf(rev, \"%s:%s\", oid_to_hex(treeish_name), submodules_file);\n \tif (get_oid(rev->buf, gitmodules_oid) >= 0)\n \t\tret = 1;\n \n@@ -583,7 +583,7 @@ void repo_read_gitmodules(struct repository *repo)\n \t\tif (repo_read_index(repo) < 0)\n \t\t\treturn;\n \n-\t\tgitmodules = repo_worktree_path(repo, GITMODULES_FILE);\n+\t\tgitmodules = repo_worktree_path(repo, submodules_file);\n \n \t\tif (!is_gitmodules_unmerged(repo->index))\n \t\t\tgit_config_from_file(gitmodules_cb, gitmodules, repo);\ndiff --git a/submodule.c b/submodule.c\nindex 9a50168b2..2afbdb644 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -36,13 +36,13 @@ static struct oid_array ref_tips_after_fetch;\n  */\n int is_gitmodules_unmerged(const struct index_state *istate)\n {\n-\tint pos = index_name_pos(istate, GITMODULES_FILE, strlen(GITMODULES_FILE));\n+\tint pos = index_name_pos(istate, submodules_file, strlen(submodules_file));\n \tif (pos < 0) { /* .gitmodules not found or isn't merged */\n \t\tpos = -1 - pos;\n \t\tif (istate->cache_nr > pos) {  /* there is a .gitmodules */\n \t\t\tconst struct cache_entry *ce = istate->cache[pos];\n-\t\t\tif (ce_namelen(ce) == strlen(GITMODULES_FILE) &&\n-\t\t\t    !strcmp(ce->name, GITMODULES_FILE))\n+\t\t\tif (ce_namelen(ce) == strlen(submodules_file) &&\n+\t\t\t    !strcmp(ce->name, submodules_file))\n \t\t\t\treturn 1;\n \t\t}\n \t}\n@@ -60,11 +60,11 @@ int is_gitmodules_unmerged(const struct index_state *istate)\n  */\n int is_staging_gitmodules_ok(struct index_state *istate)\n {\n-\tint pos = index_name_pos(istate, GITMODULES_FILE, strlen(GITMODULES_FILE));\n+\tint pos = index_name_pos(istate, submodules_file, strlen(submodules_file));\n \n \tif ((pos >= 0) && (pos < istate->cache_nr)) {\n \t\tstruct stat st;\n-\t\tif (lstat(GITMODULES_FILE, &st) == 0 &&\n+\t\tif (lstat(submodules_file, &st) == 0 &&\n \t\t    ie_match_stat(istate, istate->cache[pos], &st,\n \t\t\t\t  CE_MATCH_IGNORE_FSMONITOR) & DATA_CHANGED)\n \t\t\treturn 0;\n@@ -90,7 +90,7 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath)\n \tstruct strbuf entry = STRBUF_INIT;\n \tconst struct submodule *submodule;\n \n-\tif (!file_exists(GITMODULES_FILE)) /* Do nothing without .gitmodules */\n+\tif (!file_exists(submodules_file)) /* Do nothing without .gitmodules */\n \t\treturn -1;\n \n \tif (is_gitmodules_unmerged(&the_index))\n@@ -104,7 +104,7 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath)\n \tstrbuf_addstr(&entry, \"submodule.\");\n \tstrbuf_addstr(&entry, submodule->name);\n \tstrbuf_addstr(&entry, \".path\");\n-\tif (git_config_set_in_file_gently(GITMODULES_FILE, entry.buf, newpath) < 0) {\n+\tif (git_config_set_in_file_gently(submodules_file, entry.buf, newpath) < 0) {\n \t\t/* Maybe the user already did that, don't error out here */\n \t\twarning(_(\"Could not update .gitmodules entry %s\"), entry.buf);\n \t\tstrbuf_release(&entry);\n@@ -124,7 +124,7 @@ int remove_path_from_gitmodules(const char *path)\n \tstruct strbuf sect = STRBUF_INIT;\n \tconst struct submodule *submodule;\n \n-\tif (!file_exists(GITMODULES_FILE)) /* Do nothing without .gitmodules */\n+\tif (!file_exists(submodules_file)) /* Do nothing without .gitmodules */\n \t\treturn -1;\n \n \tif (is_gitmodules_unmerged(&the_index))\n@@ -137,7 +137,7 @@ int remove_path_from_gitmodules(const char *path)\n \t}\n \tstrbuf_addstr(&sect, \"submodule.\");\n \tstrbuf_addstr(&sect, submodule->name);\n-\tif (git_config_rename_section_in_file(GITMODULES_FILE, sect.buf, NULL) < 0) {\n+\tif (git_config_rename_section_in_file(submodules_file, sect.buf, NULL) < 0) {\n \t\t/* Maybe the user already did that, don't error out here */\n \t\twarning(_(\"Could not remove .gitmodules entry for %s\"), path);\n \t\tstrbuf_release(&sect);\n@@ -149,7 +149,7 @@ int remove_path_from_gitmodules(const char *path)\n \n void stage_updated_gitmodules(struct index_state *istate)\n {\n-\tif (add_file_to_index(istate, GITMODULES_FILE, 0))\n+\tif (add_file_to_index(istate, submodules_file, 0))\n \t\tdie(_(\"staging updated .gitmodules failed\"));\n }\n \ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex e73745051..b4d834ef4 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -283,7 +283,7 @@ static int check_submodule_move_head(const struct cache_entry *ce,\n static void load_gitmodules_file(struct index_state *index,\n \t\t\t\t struct checkout *state)\n {\n-\tint pos = index_name_pos(index, GITMODULES_FILE, strlen(GITMODULES_FILE));\n+\tint pos = index_name_pos(index, submodules_file, strlen(submodules_file));\n \n \tif (pos >= 0) {\n \t\tstruct cache_entry *ce = index->cache[pos];\n-- \n2.17.0\n\n"},{"id":"344573","messageId":"20180412222047.5716-5-ao2@ao2.it","threadId":"48277","inReplyTo":"20180412222047.5716-1-ao2@ao2.it","subject":"[RFC 04/10] submodule: document 'core.submodulesFile' and fix references to '.gitmodules'","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-12T22:20:41Z","receivedAt":"2018-04-12T22:57:26Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"The gitmodules file location can be overridden by setting the\n'core.submodulesFile' config option.\n\nDocument this new option and reflect the new behavior in the\ndocumentation by using the more generic formula \"gitmodules file\"\ninstead of the hardcoded '.gitmodules' file path.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n Documentation/config.txt                      | 18 +++++---\n Documentation/git-add.txt                     |  4 +-\n Documentation/git-submodule.txt               | 45 ++++++++++---------\n Documentation/gitmodules.txt                  | 15 ++++---\n Documentation/gitsubmodules.txt               | 18 ++++----\n .../technical/api-submodule-config.txt        |  6 +--\n contrib/subtree/git-subtree.txt               |  2 +-\n 7 files changed, 59 insertions(+), 49 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 2659153cb..647e33646 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -742,6 +742,12 @@ core.excludesFile::\n \tIf `$XDG_CONFIG_HOME` is either not set or empty, `$HOME/.config/git/ignore`\n \tis used instead. See linkgit:gitignore[5].\n \n+core.submodulesFile::\n+\tSpecifies the pathname to the file that contains the submodules\n+\tconfiguration. The path must be relative to the repository work tree.\n+\tThe specified path replaces the default per-repository '.gitmodules'\n+\tfile. See linkgit:gitmodules[5].\n+\n core.askPass::\n \tSome commands (e.g. svn and http interfaces) that interactively\n \task for a password can be told to use an external program given\n@@ -3170,7 +3176,7 @@ stash.showStat::\n \tSee description of 'show' command in linkgit:git-stash[1].\n \n submodule.<name>.url::\n-\tThe URL for a submodule. This variable is copied from the .gitmodules\n+\tThe URL for a submodule. This variable is copied from the gitmodules\n \tfile to the git config via 'git submodule init'. The user can change\n \tthe configured URL before obtaining the submodule via 'git submodule\n \tupdate'. If neither submodule.<name>.active or submodule.active are\n@@ -3191,7 +3197,7 @@ submodule.<name>.update::\n submodule.<name>.branch::\n \tThe remote branch name for a submodule, used by `git submodule\n \tupdate --remote`.  Set this option to override the value found in\n-\tthe `.gitmodules` file.  See linkgit:git-submodule[1] and\n+\tthe gitmodules file.  See linkgit:git-submodule[1] and\n \tlinkgit:gitmodules[5] for details.\n \n submodule.<name>.fetchRecurseSubmodules::\n@@ -3212,10 +3218,10 @@ submodule.<name>.ignore::\n \tlet submodules with modified tracked files in their work tree show up.\n \tUsing \"none\" (the default when this option is not set) also shows\n \tsubmodules that have untracked files in their work tree as changed.\n-\tThis setting overrides any setting made in .gitmodules for this submodule,\n-\tboth settings can be overridden on the command line by using the\n-\t\"--ignore-submodules\" option. The 'git submodule' commands are not\n-\taffected by this setting.\n+\tThis setting overrides any setting made in the gitmodules file for\n+\tthis submodule, both settings can be overridden on the command line by\n+\tusing the \"--ignore-submodules\" option. The 'git submodule' commands\n+\tare not affected by this setting.\n \n submodule.<name>.active::\n \tBoolean value indicating if the submodule is of interest to git\ndiff --git a/Documentation/git-add.txt b/Documentation/git-add.txt\nindex d50fa339d..8add7e7c0 100644\n--- a/Documentation/git-add.txt\n+++ b/Documentation/git-add.txt\n@@ -171,8 +171,8 @@ for \"git add --no-all <pathspec>...\", i.e. ignored removed files.\n --no-warn-embedded-repo::\n \tBy default, `git add` will warn when adding an embedded\n \trepository to the index without using `git submodule add` to\n-\tcreate an entry in `.gitmodules`. This option will suppress the\n-\twarning (e.g., if you are manually performing operations on\n+\tcreate an entry in the gitmodules file. This option will suppress\n+\tthe warning (e.g., if you are manually performing operations on\n \tsubmodules).\n \n --renormalize::\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex 71c5618e8..6bd8e3d44 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -58,13 +58,13 @@ for commit without cloning. The <path> is also used as the submodule's\n logical name in its configuration entries unless `--name` is used\n to specify a logical name.\n +\n-The given URL is recorded into `.gitmodules` for use by subsequent users\n-cloning the superproject. If the URL is given relative to the\n+The given URL is recorded in the gitmodules file for use by subsequent\n+users cloning the superproject. If the URL is given relative to the\n superproject's repository, the presumption is the superproject and\n submodule repositories will be kept together in the same relative\n location, and only the superproject's URL needs to be provided.\n git-submodule will correctly locate the submodule using the relative\n-URL in `.gitmodules`.\n+URL in the gitmodules file.\n \n status [--cached] [--recursive] [--] [<path>...]::\n \tShow the status of the submodules. This will print the SHA-1 of the\n@@ -86,8 +86,8 @@ too (and can also report changes to a submodule's work tree).\n init [--] [<path>...]::\n \tInitialize the submodules recorded in the index (which were\n \tadded and committed elsewhere) by setting `submodule.$name.url`\n-\tin .git/config. It uses the same setting from `.gitmodules` as\n-\ta template. If the URL is relative, it will be resolved using\n+\tin .git/config. It uses the same setting from the gitmodules file\n+\tas a template. If the URL is relative, it will be resolved using\n \tthe default remote. If there is no default remote, the current\n \trepository will be assumed to be upstream.\n +\n@@ -162,8 +162,8 @@ The following 'update' procedures are only available via the\n \tnone;; the submodule is not updated.\n \n If the submodule is not yet initialized, and you just want to use the\n-setting as stored in `.gitmodules`, you can automatically initialize the\n-submodule with the `--init` option.\n+setting as stored in the gitmodules file, you can automatically initialize\n+the submodule with the `--init` option.\n \n If `--recursive` is specified, this command will recurse into the\n registered submodules, and update any nested submodules within.\n@@ -185,8 +185,8 @@ foreach [--recursive] <command>::\n \tEvaluates an arbitrary shell command in each checked out submodule.\n \tThe command has access to the variables $name, $path, $sha1 and\n \t$toplevel:\n-\t$name is the name of the relevant submodule section in `.gitmodules`,\n-\t$path is the name of the submodule directory relative to the\n+\t$name is the name of the relevant submodule section in the gitmodules\n+\tfile, $path is the name of the submodule directory relative to the\n \tsuperproject, $sha1 is the commit as recorded in the superproject,\n \tand $toplevel is the absolute path to the top-level of the superproject.\n \tAny submodules defined in the superproject but not checked out are\n@@ -207,11 +207,11 @@ git submodule foreach 'echo $path `git rev-parse HEAD`'\n \n sync [--recursive] [--] [<path>...]::\n \tSynchronizes submodules' remote URL configuration setting\n-\tto the value specified in `.gitmodules`. It will only affect those\n-\tsubmodules which already have a URL entry in .git/config (that is the\n-\tcase when they are initialized or freshly added). This is useful when\n-\tsubmodule URLs change upstream and you need to update your local\n-\trepositories accordingly.\n+\tto the value specified in the gitmodules file. It will only affect\n+\tthose submodules which already have a URL entry in .git/config (that\n+\tis the case when they are initialized or freshly added). This is\n+\tuseful when submodule URLs change upstream and you need to update your\n+\tlocal repositories accordingly.\n +\n \"git submodule sync\" synchronizes all submodules while\n \"git submodule sync \\-- A\" synchronizes submodule \"A\" only.\n@@ -247,9 +247,9 @@ OPTIONS\n --branch::\n \tBranch of repository to add as submodule.\n \tThe name of the branch is recorded as `submodule.<name>.branch` in\n-\t`.gitmodules` for `update --remote`.  A special value of `.` is used to\n-\tindicate that the name of the branch in the submodule should be the\n-\tsame name as the current branch in the current repository.\n+\tthe gitmodules file for `update --remote`.  A special value of `.` is\n+\tused to indicate that the name of the branch in the submodule should\n+\tbe the same name as the current branch in the current repository.\n \n -f::\n --force::\n@@ -289,8 +289,8 @@ OPTIONS\n \tis branch's remote (`branch.<name>.remote`), defaulting to `origin`.\n \tThe remote branch used defaults to `master`, but the branch name may\n \tbe overridden by setting the `submodule.<name>.branch` option in\n-\teither `.gitmodules` or `.git/config` (with `.git/config` taking\n-\tprecedence).\n+\teither the gitmodules file or `.git/config` (with `.git/config`\n+\ttaking precedence).\n +\n This works for any of the supported update procedures (`--checkout`,\n `--rebase`, etc.).  The only change is the source of the target SHA-1.\n@@ -378,7 +378,7 @@ for linkgit:git-clone[1]'s `--reference` and `--shared` options carefully.\n --[no-]recommend-shallow::\n \tThis option is only valid for the update command.\n \tThe initial clone of a submodule will use the recommended\n-\t`submodule.<name>.shallow` as provided by the `.gitmodules` file\n+\t`submodule.<name>.shallow` as provided by the gitmodules file\n \tby default. To ignore the suggestions use `--no-recommend-shallow`.\n \n -j <n>::\n@@ -394,8 +394,9 @@ for linkgit:git-clone[1]'s `--reference` and `--shared` options carefully.\n \n FILES\n -----\n-When initializing submodules, a `.gitmodules` file in the top-level directory\n-of the containing repository is used to find the url of each submodule.\n+When initializing submodules, a gitmodules file is used to find the url of\n+each submodule. By default this file is named `.gitmodules` and is located in\n+the top-level directory of the containing repository.\n This file should be formatted in the same way as `$GIT_DIR/config`. The key\n to each submodule url is \"submodule.$name.url\".  See linkgit:gitmodules[5]\n for details.\ndiff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt\nindex db5d47eb1..833c0a172 100644\n--- a/Documentation/gitmodules.txt\n+++ b/Documentation/gitmodules.txt\n@@ -13,9 +13,12 @@ $GIT_WORK_DIR/.gitmodules\n DESCRIPTION\n -----------\n \n-The `.gitmodules` file, located in the top-level directory of a Git\n-working tree, is a text file with a syntax matching the requirements\n-of linkgit:git-config[1].\n+A gitmodules file is a text file with a syntax matching the requirements of\n+linkgit:git-config[1].\n+\n+By default the file is named `.gitmodules` and is located in the top-level\n+directory of a Git working tree, The location can be changed by setting the\n+`core.submodulesFile` config option.\n \n The file contains one subsection per submodule, and the subsection value\n is the name of the submodule. The name is set to the path where the\n@@ -27,7 +30,7 @@ submodule.<name>.path::\n \tDefines the path, relative to the top-level directory of the Git\n \tworking tree, where the submodule is expected to be checked out.\n \tThe path name must not end with a `/`. All submodule paths must\n-\tbe unique within the .gitmodules file.\n+\tbe unique within the gitmodules file.\n \n submodule.<name>.url::\n \tDefines a URL from which the submodule repository can be cloned.\n@@ -60,7 +63,7 @@ submodule.<name>.fetchRecurseSubmodules::\n \tThis option can be used to control recursive fetching of this\n \tsubmodule. If this option is also present in the submodules entry in\n \t.git/config of the superproject, the setting there will override the\n-\tone found in .gitmodules.\n+\tone found in the gitmodules file.\n \tBoth settings can be overridden on the command line by using the\n \t\"--[no-]recurse-submodules\" option to \"git fetch\" and \"git pull\".\n \n@@ -86,7 +89,7 @@ submodule.<name>.ignore::\n \n \tIf this option is also present in the submodules entry in .git/config\n \tof the superproject, the setting there will override the one found in\n-\t.gitmodules.\n+\tthe gitmodules file.\n \tBoth settings can be overridden on the command line by using the\n \t\"--ignore-submodule\" option. The 'git submodule' commands are not\n \taffected by this setting.\ndiff --git a/Documentation/gitsubmodules.txt b/Documentation/gitsubmodules.txt\nindex 3b9faabdb..abfb70227 100644\n--- a/Documentation/gitsubmodules.txt\n+++ b/Documentation/gitsubmodules.txt\n@@ -29,13 +29,13 @@ the submodule's working directory pointing to (i).\n Assuming the submodule has a Git directory at `$GIT_DIR/modules/foo/`\n and a working directory at `path/to/bar/`, the superproject tracks the\n submodule via a `gitlink` entry in the tree at `path/to/bar` and an entry\n-in its `.gitmodules` file (see linkgit:gitmodules[5]) of the form\n+in its gitmodules file (see linkgit:gitmodules[5]) of the form\n `submodule.foo.path = path/to/bar`.\n \n The `gitlink` entry contains the object name of the commit that the\n superproject expects the submodule's working directory to be at.\n \n-The section `submodule.foo.*` in the `.gitmodules` file gives additional\n+The section `submodule.foo.*` in the gitmodules file gives additional\n hints to Git's porcelain layer. For example, the `submodule.foo.url`\n setting specifies where to obtain the submodule.\n \n@@ -108,7 +108,7 @@ If the submodule is not yet initialized, then the configuration\n inside the submodule does not exist yet, so where to\n obtain the submodule from is configured here for example.\n \n- * The `.gitmodules` file inside the superproject. A project usually\n+ * The gitmodules file inside the superproject. A project usually\n    uses this file to suggest defaults for the upstream collection\n    of repositories for the mapping that is required between a\n    submodule's name and its path.\n@@ -127,12 +127,12 @@ FORMS\n Submodules can take the following forms:\n \n  * The basic form described in DESCRIPTION with a Git directory,\n-a working directory, a `gitlink`, and a `.gitmodules` entry.\n+a working directory, a `gitlink`, and a linkgit:gitmodules[5] entry.\n \n  * \"Old-form\" submodule: A working directory with an embedded\n-`.git` directory, and the tracking `gitlink` and `.gitmodules` entry in\n-the superproject. This is typically found in repositories generated\n-using older versions of Git.\n+`.git` directory, and the tracking `gitlink` and linkgit:gitmodules[5] entry\n+in the superproject. This is typically found in repositories generated using\n+older versions of Git.\n +\n It is possible to construct these old form repositories manually.\n +\n@@ -140,7 +140,7 @@ When deinitialized or deleted (see below), the submodule's Git\n directory is automatically moved to `$GIT_DIR/modules/<name>/`\n of the superproject.\n \n- * Deinitialized submodule: A `gitlink`, and a `.gitmodules` entry,\n+ * Deinitialized submodule: A `gitlink`, and a linkgit:gitmodules[5] entry,\n but no submodule working directory. The submodule's Git directory\n may be there as after deinitializing the Git directory is kept around.\n The directory which is supposed to be the working directory is empty instead.\n@@ -155,7 +155,7 @@ is not affected. This can be undone using `git submodule init`.\n using `git revert`.\n +\n The deletion removes the superproject's tracking data, which are\n-both the `gitlink` entry and the section in the `.gitmodules` file.\n+both the `gitlink` entry and the section in the gitmodules file.\n The submodule's working directory is removed from the file\n system, but the Git directory is kept around as it to make it\n possible to checkout past commits without requiring fetching\ndiff --git a/Documentation/technical/api-submodule-config.txt b/Documentation/technical/api-submodule-config.txt\nindex ee907c4a8..1b9f86493 100644\n--- a/Documentation/technical/api-submodule-config.txt\n+++ b/Documentation/technical/api-submodule-config.txt\n@@ -4,7 +4,7 @@ submodule config cache API\n The submodule config cache API allows to read submodule\n configurations/information from specified revisions. Internally\n information is lazily read into a cache that is used to avoid\n-unnecessary parsing of the same .gitmodules files. Lookups can be done by\n+unnecessary parsing of the same gitmodules files. Lookups can be done by\n submodule path or name.\n \n Usage\n@@ -12,7 +12,7 @@ Usage\n \n To initialize the cache with configurations from the worktree the caller\n typically first calls `gitmodules_config()` to read values from the\n-worktree .gitmodules and then to overlay the local git config values\n+worktree gitmodules file and then to overlay the local git config values\n `parse_submodule_config_option()` from the config parsing\n infrastructure.\n \n@@ -61,6 +61,6 @@ via e.g. `gitmodules_config()`, it will overwrite the null_sha1 entry.\n So in the normal case, when HEAD:.gitmodules is parsed first and then overlayed\n with the repository configuration, the null_sha1 entry contains the local\n configuration of a submodule (e.g. consolidated values from local git\n-configuration and the .gitmodules file in the worktree).\n+configuration and the gitmodules file).\n \n For an example usage see test-submodule-config.c.\ndiff --git a/contrib/subtree/git-subtree.txt b/contrib/subtree/git-subtree.txt\nindex 352deda69..a86f8b6f5 100644\n--- a/contrib/subtree/git-subtree.txt\n+++ b/contrib/subtree/git-subtree.txt\n@@ -28,7 +28,7 @@ as a subdirectory of your application.\n \n Subtrees are not to be confused with submodules, which are meant for\n the same task. Unlike submodules, subtrees do not need any special\n-constructions (like .gitmodules files or gitlinks) be present in\n+constructions (like gitmodules files or gitlinks) be present in\n your repository, and do not force end-users of your\n repository to do anything special or to understand how subtrees\n work. A subtree is just a subdirectory that can be\n-- \n2.17.0\n\n"},{"id":"344574","messageId":"20180412222047.5716-6-ao2@ao2.it","threadId":"48277","inReplyTo":"20180412222047.5716-1-ao2@ao2.it","subject":"[RFC 05/10] submodule: adjust references to '.gitmodules' in comments","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-12T22:20:42Z","receivedAt":"2018-04-12T22:57:32Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"In the comments refer to a more generic \"gitmodules file\" instead of\nusing the '.gitmodules' file name directly.\n\nSigned-off-by: Antonio Ospite <ao2@ao2.it>\n---\n builtin/submodule--helper.c |  2 +-\n config.c                    |  7 +++----\n config.h                    |  7 +++----\n git-submodule.sh            | 10 +++++-----\n repository.h                |  2 +-\n submodule-config.c          |  8 ++++----\n submodule-config.h          |  2 +-\n submodule.c                 | 24 ++++++++++++------------\n 8 files changed, 30 insertions(+), 32 deletions(-)\n\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex 72b95d27b..7e8fa26c9 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -476,7 +476,7 @@ static void init_submodule(const char *path, const char *prefix,\n \t/*\n \t * Copy url setting when it is not set yet.\n \t * To look up the url in .git/config, we must not fall back to\n-\t * .gitmodules, so look it up directly.\n+\t * the gitmodules file, so look it up directly.\n \t */\n \tstrbuf_addf(&sb, \"submodule.%s.url\", sub->name);\n \tif (git_config_get_string(sb.buf, &url)) {\ndiff --git a/config.c b/config.c\nindex 6ffb1d501..9921b6c2c 100644\n--- a/config.c\n+++ b/config.c\n@@ -2079,11 +2079,10 @@ int git_config_get_pathname(const char *key, const char **dest)\n \n /*\n  * Note: This function exists solely to maintain backward compatibility with\n- * 'fetch' and 'update_clone' storing configuration in '.gitmodules' and should\n- * NOT be used anywhere else.\n+ * 'fetch' and 'update_clone' storing configuration in the gitmodules file and\n+ * should NOT be used anywhere else.\n  *\n- * Runs the provided config function on the '.gitmodules' file found in the\n- * working directory.\n+ * Runs the provided config function on the gitmodules file.\n  */\n void config_from_gitmodules(config_fn_t fn, void *data)\n {\ndiff --git a/config.h b/config.h\nindex ef70a9cac..37aef35d5 100644\n--- a/config.h\n+++ b/config.h\n@@ -191,11 +191,10 @@ extern int repo_config_get_pathname(struct repository *repo,\n \n /*\n  * Note: This function exists solely to maintain backward compatibility with\n- * 'fetch' and 'update_clone' storing configuration in '.gitmodules' and should\n- * NOT be used anywhere else.\n+ * 'fetch' and 'update_clone' storing configuration in the gitmodules file and\n+ * should NOT be used anywhere else.\n  *\n- * Runs the provided config function on the '.gitmodules' file found in the\n- * working directory.\n+ * Runs the provided config function on the gitmodules file.\n  */\n extern void config_from_gitmodules(config_fn_t fn, void *data);\n \ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 610fd0dc5..615a65be9 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -59,10 +59,10 @@ die_if_unmatched ()\n # $3 = default value\n #\n # Checks in the usual git-config places first (for overrides),\n-# otherwise it falls back on .gitmodules.  This allows you to\n-# distribute project-wide defaults in .gitmodules, while still\n+# otherwise it falls back to the gitmodules file.  This allows you to\n+# distribute project-wide defaults in the gitmodules file, while still\n # customizing individual repositories if necessary.  If the option is\n-# not in .gitmodules either, print a default value.\n+# not in the gitmodules file either, print a default value.\n #\n get_submodule_config () {\n \tname=\"$1\"\n@@ -95,7 +95,7 @@ sanitize_submodule_env()\n }\n \n #\n-# Add a new submodule to the working tree, .gitmodules and the index\n+# Add a new submodule to the working tree, the gitmodules file and the index\n #\n # $@ = repo path\n #\n@@ -960,7 +960,7 @@ cmd_status()\n #\n # Sync remote urls for submodules\n # This makes the value for remote.$remote.url match the value\n-# specified in .gitmodules.\n+# specified in the gitmodules file.\n #\n cmd_sync()\n {\ndiff --git a/repository.h b/repository.h\nindex 09df94a47..2db62af0e 100644\n--- a/repository.h\n+++ b/repository.h\n@@ -59,7 +59,7 @@ struct repository {\n \t */\n \tstruct config_set *config;\n \n-\t/* Repository's submodule config as defined by '.gitmodules' */\n+\t/* Repository's submodule config as defined by the gitmodules file */\n \tstruct submodule_cache *submodule_cache;\n \n \t/*\ndiff --git a/submodule-config.c b/submodule-config.c\nindex 620d522ee..18984473b 100644\n--- a/submodule-config.c\n+++ b/submodule-config.c\n@@ -9,7 +9,7 @@\n /*\n  * submodule cache lookup structure\n  * There is one shared set of 'struct submodule' entries which can be\n- * looked up by their sha1 blob id of the .gitmodules file and either\n+ * looked up by their sha1 blob id of the gitmodules file and either\n  * using path or name as key.\n  * for_path stores submodule entries with path as key\n  * for_name stores submodule entries with name as key\n@@ -91,7 +91,7 @@ static void submodule_cache_clear(struct submodule_cache *cache)\n \t/*\n \t * We iterate over the name hash here to be symmetric with the\n \t * allocation of struct submodule entries. Each is allocated by\n-\t * their .gitmodules blob sha1 and submodule name.\n+\t * their gitmodules file blob sha1 and submodule name.\n \t */\n \thashmap_iter_init(&cache->for_name, &iter);\n \twhile ((entry = hashmap_iter_next(&iter)))\n@@ -476,7 +476,7 @@ static int gitmodule_oid_from_commit(const struct object_id *treeish_name,\n }\n \n /* This does a lookup of a submodule configuration by name or by path\n- * (key) with on-demand reading of the appropriate .gitmodules from\n+ * (key) with on-demand reading of the appropriate gitmodules file from\n  * revisions.\n  */\n static const struct submodule *config_from(struct submodule_cache *cache,\n@@ -614,7 +614,7 @@ static void gitmodules_read_check(struct repository *repo)\n {\n \tsubmodule_cache_check_init(repo);\n \n-\t/* read the repo's .gitmodules file if it hasn't been already */\n+\t/* read the repo's gitmodules file if it hasn't been already */\n \tif (!repo->submodule_cache->gitmodules_read)\n \t\trepo_read_gitmodules(repo);\n }\ndiff --git a/submodule-config.h b/submodule-config.h\nindex a5503a5d1..75fa54cf2 100644\n--- a/submodule-config.h\n+++ b/submodule-config.h\n@@ -17,7 +17,7 @@ struct submodule {\n \tconst char *ignore;\n \tconst char *branch;\n \tstruct submodule_update_strategy update_strategy;\n-\t/* the sha1 blob id of the responsible .gitmodules file */\n+\t/* the sha1 blob id of the responsible gitmodules file */\n \tunsigned char gitmodules_sha1[20];\n \tint recommend_shallow;\n };\ndiff --git a/submodule.c b/submodule.c\nindex 97213b549..d9b84760f 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -30,16 +30,16 @@ static struct oid_array ref_tips_before_fetch;\n static struct oid_array ref_tips_after_fetch;\n \n /*\n- * Check if the .gitmodules file is unmerged. Parsing of the .gitmodules file\n- * will be disabled because we can't guess what might be configured in\n- * .gitmodules unless the user resolves the conflict.\n+ * Check if the gitmodules file is unmerged. Parsing of the gitmodules\n+ * file will be disabled because we can't guess what might be configured in\n+ * the gitmodules file unless the user resolves the conflict.\n  */\n int is_gitmodules_unmerged(const struct index_state *istate)\n {\n \tint pos = index_name_pos(istate, submodules_file, strlen(submodules_file));\n-\tif (pos < 0) { /* .gitmodules not found or isn't merged */\n+\tif (pos < 0) { /* gitmodules file not found or isn't merged */\n \t\tpos = -1 - pos;\n-\t\tif (istate->cache_nr > pos) {  /* there is a .gitmodules */\n+\t\tif (istate->cache_nr > pos) {  /* there is a gitmodules file */\n \t\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\t\tif (ce_namelen(ce) == strlen(submodules_file) &&\n \t\t\t    !strcmp(ce->name, submodules_file))\n@@ -51,8 +51,8 @@ int is_gitmodules_unmerged(const struct index_state *istate)\n }\n \n /*\n- * Check if the .gitmodules file has unstaged modifications.  This must be\n- * checked before allowing modifications to the .gitmodules file with the\n+ * Check if the gitmodules file has unstaged modifications.  This must be\n+ * checked before allowing modifications to the gitmodules file with the\n  * intention to stage them later, because when continuing we would stage the\n  * modifications the user didn't stage herself too. That might change in a\n  * future version when we learn to stage the changes we do ourselves without\n@@ -82,7 +82,7 @@ static int for_each_remote_ref_submodule(const char *submodule,\n \n /*\n  * Try to update the \"path\" entry in the \"submodule.<name>\" section of the\n- * .gitmodules file. Return 0 only if a .gitmodules file was found, a section\n+ * gitmodules file. Return 0 only if a gitmodules file was found, a section\n  * with the correct path=<oldpath> setting was found and we could update it.\n  */\n int update_path_in_gitmodules(const char *oldpath, const char *newpath)\n@@ -90,7 +90,7 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath)\n \tstruct strbuf entry = STRBUF_INIT;\n \tconst struct submodule *submodule;\n \n-\tif (!file_exists(submodules_file)) /* Do nothing without .gitmodules */\n+\tif (!file_exists(submodules_file)) /* Do nothing without a gitmodules file */\n \t\treturn -1;\n \n \tif (is_gitmodules_unmerged(&the_index))\n@@ -115,8 +115,8 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath)\n }\n \n /*\n- * Try to remove the \"submodule.<name>\" section from .gitmodules where the given\n- * path is configured. Return 0 only if a .gitmodules file was found, a section\n+ * Try to remove the \"submodule.<name>\" section from the gitmodules file where the given\n+ * path is configured. Return 0 only if a gitmodules file was found, a section\n  * with the correct path=<path> setting was found and we could remove it.\n  */\n int remove_path_from_gitmodules(const char *path)\n@@ -124,7 +124,7 @@ int remove_path_from_gitmodules(const char *path)\n \tstruct strbuf sect = STRBUF_INIT;\n \tconst struct submodule *submodule;\n \n-\tif (!file_exists(submodules_file)) /* Do nothing without .gitmodules */\n+\tif (!file_exists(submodules_file)) /* Do nothing without a gitmodules file */\n \t\treturn -1;\n \n \tif (is_gitmodules_unmerged(&the_index))\n-- \n2.17.0\n\n"},{"id":"344575","messageId":"20180412222047.5716-7-ao2@ao2.it","threadId":"48277","inReplyTo":"20180412222047.5716-1-ao2@ao2.it","subject":"[RFC 06/10] completion: add 'core.submodulesfile' to the git-completion.bash file","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-12T22:20:43Z","receivedAt":"2018-04-12T22:57:33Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Signed-off-by: Antonio Ospite <ao2@ao2.it>\n---\n contrib/completion/git-completion.bash | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex a75707394..19beb6735 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2382,6 +2382,7 @@ _git_config ()\n \t\tcore.sparseCheckout\n \t\tcore.splitIndex\n \t\tcore.sshCommand\n+\t\tcore.submodulesfile\n \t\tcore.symlinks\n \t\tcore.trustctime\n \t\tcore.untrackedCache\n-- \n2.17.0\n\n"},{"id":"344579","messageId":"CAGZ79kZbZ03D7ysaVXYkV3v0jO6K7kEOc9sT2zA+Xc6mqLNL9Q@mail.gmail.com","threadId":"48277","inReplyTo":"20180412222047.5716-1-ao2@ao2.it","subject":"Re: [RFC 00/10] Make .the gitmodules file path configurable","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-04-12T23:36:32Z","receivedAt":"2018-04-12T23:36:38Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Hi Antonio,\n\nOn Thu, Apr 12, 2018 at 3:20 PM, Antonio Ospite <ao2@ao2.it> wrote:\n> Hi,\n>\n> vcsh[1] uses bare git repositories and detached work-trees to manage\n> *distinct* sets of configuration files directly into $HOME.\n>\n> In general, submodules have worked perfectly fine with detached\n> work-trees for some time[2,3,4].\n>\n> However when multiple repositories take turns using the same directory\n> as their work-tree, and more than one of them want to use submodules,\n> there could still be conflicts about the '.gitmodules' file because git\n> hardcodes this path.\n>\n> For comparison, in case of '.gitignore' a similar conflict might arise,\n> but git has alternative ways to specify exclude files, so vcsh solves\n> this by setting core.excludesFile for each repository and track ignored\n> files somewhere else (in ~/.gitignore.d/$VCSH_REPO_NAME).\n>\n> This is currently not possible with submodules configuration.\n\nSo far I agree w.r.t. Gits capabilities.\n\n> So this series proposes a mechanism to set an alternative path for the\n> submodules configuration file (from now on \"gitmodules file\").\n\nThat sounds interesting, so let's read on.\n\n> Patches are based on fe0a9eaf31dd0c349ae4308498c33a5c3794b293.\n\n... which is the current master branch by Junio.\n\n> In commit 4c0eeafe4755 (cache.h: add GITMODULES_FILE macro)[5] the\n> gitmodules file path definition was centralized, AFAIU this was done\n> mainly to prevent typos, as checking a symbolic constant is something\n> the compiler will do for us.\n\n+cc Brandon author of said patch.\n\nDigging up the discussion, this was indeed only done to prevent typos.\nhttps://public-inbox.org/git/20170802172633.GA36159@google.com/\n\n> Expanding on that change the first patch in the series makes the path\n> customizable exposing a 'core.submodulesFile' configuration setting.\n\nI guess the similarity to core.ignoreFile is desired here. Although these\nmechanisms are very different.\n\n> The new configuration setting can be used to set an *alternative*\n> location for the gitmodules file; IMHO there is no need to provide\n> *additional* locations like in the case of exclude files.\n\nI think there *may* be a need for additional files.\nCurrently there is only the .gitmodules file and the configuration\nin .git/config overriding settings from .gitmodules.\n\nThere was some discussion on the mailing list in the past, which\npresented a intermediate layer in between these two places, in\na special ref, such that:\n    base is in .gitmodules\n    overwritten via refs/meta/submodules:.gitmodules\n    overwritten via the .git/config\n\nThe intermediate would be a config file that is tracked on another\nref. This (a) decouples main project history from submodule history\nand (b) makes it easier to distribute as it is part of the repository.\n\nFor example (a) is desired if you dig up an old project and the\nsubmodules have all moved from one git hosting provider to another.\nAnother example would be when you fork a project with submodules\nand don't want to mess with the main history but you just want to\nadjust the submodule URLs. That is possible with such an intermediate\nadditional place.\n\nFor (b) you can imagine the fork that you want to distribute in your\ncommunity and you don't want to tell everyone to change the\nsubmodule URLs, but instead you can provide them with a prepared\n.gitmodules file, that they have to place into that special ref (which\ncan be done via fetching).\n\nI digress as these ideas seem to be orthogonal to your patch series,\njust FYI. prior discussion starting at:\nhttps://public-inbox.org/git/1462317985-640-1-git-send-email-sbeller@google.com/\nI recall there was a better discussion even prior to that, but have no\nlink handy.\n\n\n> For instance vcsh could set the location to\n> '~/.gitmodules.d/$VCSH_REPO_NAME' to avoid conflicts.\n>\n> Since the gitmodules file is meant to be checked in into the repository,\n> the overridden file path should be relative to the work-tree; is there\n> a way to enforce this constraint at run time (i.e. validate the config\n> value), or is it enough to have it documented?\n\nI think we'd want to check at run time, if we need this constraint.\n\nThanks,\nStefan\n"},{"id":"344581","messageId":"CAGZ79kZV+MLaVp4AM77bJkT=MeBvDSHTxZCni8dkqq4VLWZ0AA@mail.gmail.com","threadId":"48277","inReplyTo":"20180412222047.5716-2-ao2@ao2.it","subject":"Re: [RFC 01/10] submodule: add 'core.submodulesFile' to override the '.gitmodules' path","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-04-12T23:50:03Z","receivedAt":"2018-04-12T23:50:11Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Hi Antonio,\n\nOn Thu, Apr 12, 2018 at 3:20 PM, Antonio Ospite <ao2@ao2.it> wrote:\n> When multiple repositories with detached work-trees take turns using the\n> same directory as their work-tree, and more than one of them want to use\n> submodules, there will be conflicts about the '.gitmodules' file.\n\nunlike other files which would not conflict?\nThere might be file names such as LICENSE, Readme.md etc,\nwhich are common enough that they would produce conflicts as well?\nI find this argument on its own rather weak. (\"Just delete everything in\nthe working dir before using it with another repository\"). I might be\nmissing a crucial bit here?\n\n> git hardcodes this path so it's not possible to override its location on\n> a per-repository basis to allow such repositories to coexists\n> peacefully.\n>\n> Make the path of the \"gitmodules file\" customizable exposing\n> a 'core.submodulesFile' configuration setting.\n>\n> The default value will still be '.gitmodules' when 'core.submodulesFile'\n> is not set.\n\nok.\n\n\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -1774,6 +1774,7 @@ extern void prepare_pager_args(struct child_process *, const char *pager);\n>  extern const char *editor_program;\n>  extern const char *askpass_program;\n>  extern const char *excludes_file;\n> +extern const char *submodules_file;\n\nCould you place this variable in repository.h in struct repository?\n(Some developers currently try to move any global state to that place,\nas that makes working with e.g. nested submodules easier in-process\nand you would not need to spawn processes for submodules)\n\nOnce migrated to the repository struct mentioned above, you'd access\nit via the_repository->submodules_file for the main repository.\n\n\n> diff --git a/git-submodule.sh b/git-submodule.sh\n> index 24914963c..610fd0dc5 100755\n> --- a/git-submodule.sh\n> +++ b/git-submodule.sh\n> @@ -71,7 +71,9 @@ get_submodule_config () {\n>         value=$(git config submodule.\"$name\".\"$option\")\n>         if test -z \"$value\"\n>         then\n> -               value=$(git config -f .gitmodules submodule.\"$name\".\"$option\")\n> +               gitmodules_file=$(git config core.submodulesfile)\n> +               : ${gitmodules_file:=.gitmodules}\n> +               value=$(git config -f \"$gitmodules_file\" submodule.\"$name\".\"$option\")\n\nI wonder if it would be cheaper to write a special config lookup now, e.g.\nin builtin/submodule--helper.c we could have a \"config-from-gitmodules\"\nsubcommand that is looking up the modules file and then running the config\non that file.\n\nI am surprised how little access of the .gitmodules is left in git-submodule.sh\n(which is partially ported to the builtin/submodule--helper.c)\n\n> diff --git a/submodule-config.c b/submodule-config.c\n> index 3f2075764..8a3396ade 100644\n> --- a/submodule-config.c\n> +++ b/submodule-config.c\n> @@ -468,7 +468,7 @@ static int gitmodule_oid_from_commit(const struct object_id *treeish_name,\n>                 return 1;\n>         }\n>\n> -       strbuf_addf(rev, \"%s:.gitmodules\", oid_to_hex(treeish_name));\n> +       strbuf_addf(rev, \"%s:%s\", oid_to_hex(treeish_name), submodules_file);\n>         if (get_oid(rev->buf, gitmodules_oid) >= 0)\n>                 ret = 1;\n>\n> @@ -583,7 +583,7 @@ void repo_read_gitmodules(struct repository *repo)\n>                 if (repo_read_index(repo) < 0)\n>                         return;\n>\n> -               gitmodules = repo_worktree_path(repo, GITMODULES_FILE);\n> +               gitmodules = repo_worktree_path(repo, submodules_file);\n>\n>                 if (!is_gitmodules_unmerged(repo->index))\n>                         git_config_from_file(gitmodules_cb, gitmodules, repo);\n> diff --git a/submodule.c b/submodule.c\n> index 9a50168b2..2afbdb644 100644\n> --- a/submodule.c\n> +++ b/submodule.c\n> @@ -36,13 +36,13 @@ static struct oid_array ref_tips_after_fetch;\n>   */\n>  int is_gitmodules_unmerged(const struct index_state *istate)\n>  {\n> -       int pos = index_name_pos(istate, GITMODULES_FILE, strlen(GITMODULES_FILE));\n> +       int pos = index_name_pos(istate, submodules_file, strlen(submodules_file));\n\nAh, regarding the coverletter: This clearly assumes the modules\nfile is in the tree. So at least here we would make an exception\nfor files outside the tree to either not check for un-merged-ness or\ndisallow that case entirely.\n\n\n\nThere are quite a few functions in submodule.c which access the new global. :/\nSo moving them to the_repository should be fine, but eventually (not\nin this series)\nall these functions would would want to take a repository argument as well\nsuch that they work on more than the_repository.\n\nThanks,\nStefan\n"},{"id":"344582","messageId":"CAGZ79kbnc17PZ9_=8QLkZgUZ0DHJKfWnxrekmgkLGFBU_0ieug@mail.gmail.com","threadId":"48277","inReplyTo":"20180412222047.5716-3-ao2@ao2.it","subject":"Re: [RFC 02/10] submodule: fix getting custom gitmodule file in fetch command","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-04-12T23:55:15Z","receivedAt":"2018-04-12T23:55:22Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Hi Antonio,\n\nthe subject line could also be\n  fetch: fix custom submodule location\nas I was not expecting this patch from the subject line.\n\nOn Thu, Apr 12, 2018 at 3:20 PM, Antonio Ospite <ao2@ao2.it> wrote:\n> Import the default git configuration before accessing the gitmodules\n> file.\n>\n> This is important when a value different from the default one is set via\n> the 'core.submodulesfile' config.\n>\n> Signed-off-by: Antonio Ospite <ao2@ao2.it>\n> ---\n>  builtin/fetch.c | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n>\n> diff --git a/builtin/fetch.c b/builtin/fetch.c\n> index dcdfc66f0..d56636f74 100644\n> --- a/builtin/fetch.c\n> +++ b/builtin/fetch.c\n> @@ -1428,8 +1428,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n>         for (i = 1; i < argc; i++)\n>                 strbuf_addf(&default_rla, \" %s\", argv[i]);\n>\n> -       config_from_gitmodules(gitmodules_fetch_config, NULL);\n>         git_config(git_fetch_config, NULL);\n> +       config_from_gitmodules(gitmodules_fetch_config, NULL);\n\nWouldn't this break the overwriting behavior?\ne.g. you configure a submodule URL in .gitmodules and then override it\nin .git/config,\nthen we'd currently first load config from the modules file and then override it\nin git_config(git_fetch_config,..), whereas swapping them might have\nunintended consequences? Do the tests pass with this patch?\n"},{"id":"344589","messageId":"20180413100707.945b38dde1c75ebea8360858@ao2.it","threadId":"48277","inReplyTo":"20180412222047.5716-1-ao2@ao2.it","subject":"Re: [RFC 00/10] Make .the gitmodules file path configurable","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-13T08:07:07Z","receivedAt":"2018-04-13T08:07:20Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"On Fri, 13 Apr 2018 00:20:37 +0200\nAntonio Ospite <ao2@ao2.it> wrote:\n\n[...]\n> Antonio Ospite (10):\n>   submodule: add 'core.submodulesFile' to override the '.gitmodules'\n>     path\n>   submodule: fix getting custom gitmodule file in fetch command\n>   submodule: use the 'submodules_file' variable in output messages\n>   submodule: document 'core.submodulesFile' and fix references to\n>     '.gitmodules'\n>   submodule: adjust references to '.gitmodules' in comments\n>   completion: add 'core.submodulesfile' to the git-completion.bash file\n>   XXX: wrap-for-bin.sh: set 'core.submodulesFile' for each git\n>     invocation\n>   XXX: submodule: fix t1300-repo-config.sh to take into account the new\n>     config\n>   XXX: submodule: pass custom gitmodules file to 'test-tool\n>     submodule-config'\n>   XXX: add a hacky script to test the changes with a patched test suite\n> \n\nI am re-sending the last four highly experimental patches changing the\n\"XXX\" into \"FIXME\" in the subject lines because vger.kernel.org refused\nthe original ones with the following message:\n\n  The capital Triple-X in subject is way too often associated with junk\n  email, please rephrase.\n\nSorry for the inconvenience.\n\n-- \nAntonio Ospite\nhttps://ao2.it\nhttps://twitter.com/ao2it\n\nA: Because it messes up the order in which people normally read text.\n   See http://en.wikipedia.org/wiki/Posting_style\nQ: Why is top-posting such a bad thing?\n"},{"id":"344590","messageId":"20180413080733.6380-3-ao2@ao2.it","threadId":"48277","inReplyTo":"20180413080733.6380-1-ao2@ao2.it","subject":"[RFC 09/10] FIXME: submodule: pass custom gitmodules file to 'test-tool submodule-config'","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-13T08:07:32Z","receivedAt":"2018-04-13T08:07:57Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Add a new option to 't/helper/test-submodule-config.c' to set a custom\npath for the gitmodules file.\n\nIn particular this is needed to make 't/t7411-submodule-config.sh' pass.\n\nThe option is actually put in use by the script that patches the test\nsuite.\n---\n t/helper/test-submodule-config.c | 7 +++++++\n 1 file changed, 7 insertions(+)\n\ndiff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c\nindex 5c6e4b010..30b4ea3da 100644\n--- a/t/helper/test-submodule-config.c\n+++ b/t/helper/test-submodule-config.c\n@@ -25,6 +25,13 @@ int cmd__submodule_config(int argc, const char **argv)\n \t\t\toutput_url = 1;\n \t\tif (!strcmp(arg[0], \"--name\"))\n \t\t\tlookup_name = 1;\n+\t\tif (!strcmp(arg[0], \"--submodules_file\")) {\n+\t\t\targ++;\n+\t\t\tmy_argc--;\n+\t\t\tsubmodules_file = expand_user_path(arg[0], 0);\n+\t\t\tif (!submodules_file)\n+\t\t\t\tdie(_(\"failed to expand user dir in: '%s'\"), arg[0]);\n+\t\t}\n \t\targ++;\n \t\tmy_argc--;\n \t}\n-- \n2.17.0\n\n"},{"id":"344591","messageId":"20180413080733.6380-1-ao2@ao2.it","threadId":"48277","inReplyTo":"20180412222047.5716-1-ao2@ao2.it","subject":"[RFC 07/10] FIXME: wrap-for-bin.sh: set 'core.submodulesFile' for each git invocation","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-13T08:07:30Z","receivedAt":"2018-04-13T08:08:01Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"This is to test custom gitmodules file paths. The default path can be\noverridden using the 'GIT_MODULES_FILE' environmental variable.\n\nMaybe In the final patch the option should be set only when running\ntests and not unconditionally in the wrapper script, but as a proof of\nconcept the wrapper script was a convenient location.\n\nAlso, in the final patch a fixed custom file path could be used instead\nof the environmental variable: to exercise the code it should be enough\nto have a value different from the default one.\n\nThe change to 't0001-init.sh' is needed to make the test pass, since now\na config is set on the command line.\n---\n Makefile        | 3 ++-\n t/t0001-init.sh | 1 +\n wrap-for-bin.sh | 2 ++\n 3 files changed, 5 insertions(+), 1 deletion(-)\n mode change 100644 => 100755 wrap-for-bin.sh\n\ndiff --git a/Makefile b/Makefile\nindex f18168725..38ee1f6a2 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2480,7 +2480,8 @@ bin-wrappers/%: wrap-for-bin.sh\n \t@mkdir -p bin-wrappers\n \t$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n \t     -e 's|@@BUILD_DIR@@|$(shell pwd)|' \\\n-\t     -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%,$(@F))|' < $< > $@ && \\\n+\t     -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%,$(@F))|' \\\n+\t     -e 's|git\\\"|git\\\" $$GIT_OPTIONS|' < $< > $@ && \\\n \tchmod +x $@\n \n # GNU make supports exporting all variables by \"export\" without parameters.\ndiff --git a/t/t0001-init.sh b/t/t0001-init.sh\nindex c413bff9c..6fa3fd24e 100755\n--- a/t/t0001-init.sh\n+++ b/t/t0001-init.sh\n@@ -93,6 +93,7 @@ test_expect_success 'No extra GIT_* on alias scripts' '\n \t\tsed -n \\\n \t\t\t-e \"/^GIT_PREFIX=/d\" \\\n \t\t\t-e \"/^GIT_TEXTDOMAINDIR=/d\" \\\n+\t\t\t-e \"/^GIT_CONFIG_PARAMETERS=/d\" \\\n \t\t\t-e \"/^GIT_/s/=.*//p\" |\n \t\tsort\n \tEOF\ndiff --git a/wrap-for-bin.sh b/wrap-for-bin.sh\nold mode 100644\nnew mode 100755\nindex 584240881..02bf41cbd\n--- a/wrap-for-bin.sh\n+++ b/wrap-for-bin.sh\n@@ -20,6 +20,8 @@ PATH='@@BUILD_DIR@@/bin-wrappers:'\"$PATH\"\n \n export GIT_EXEC_PATH GITPERLLIB PATH GIT_TEXTDOMAINDIR\n \n+GIT_OPTIONS=\"-c core.submodulesfile=${GITMODULES_FILE:-.gitmodules}\"\n+\n if test -n \"$GIT_TEST_GDB\"\n then\n \tunset GIT_TEST_GDB\n-- \n2.17.0\n\n"},{"id":"344592","messageId":"20180413080733.6380-4-ao2@ao2.it","threadId":"48277","inReplyTo":"20180413080733.6380-1-ao2@ao2.it","subject":"[RFC 10/10] FIXME: add a hacky script to test the changes with a patched test suite","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-13T08:07:33Z","receivedAt":"2018-04-13T08:08:06Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Patch all the hardcoded occurrences of '.gitmodules' and make the file\nconfigurable via an environment variable.\n\nThis is only for demonstration purposes, the final patch to the test\nsuite could just use a fixed path for the custom gitmodules file,\nmatching the path passed in the wrapper script via the\n'core.submodulesfile' option.\n\nThe rationale would be that testing with a custom gitmodules file covers\nalso the case of the default gitmodules file path.\n\nExecute 'test-custom-gitmodules-file.sh' to check that the test pass\nwith either the default anda custom gitmodules file.\n---\n test-custom-gitmodules-file.sh | 75 ++++++++++++++++++++++++++++++++++\n 1 file changed, 75 insertions(+)\n create mode 100755 test-custom-gitmodules-file.sh\n\ndiff --git a/test-custom-gitmodules-file.sh b/test-custom-gitmodules-file.sh\nnew file mode 100755\nindex 000000000..d59b1e40d\n--- /dev/null\n+++ b/test-custom-gitmodules-file.sh\n@@ -0,0 +1,75 @@\n+#!/bin/sh\n+#\n+# This is a test script to demonstrate that the changes about\n+# 'core.submodulesfile' do not cause regressions and even work as intended\n+# when a custom gitmodules file is specified O_O.\n+#\n+# The script patches the hardcoded '.gitmodules' occurrences to be overridden\n+# by an environment variable.\n+#\n+# Note that 'core.submodulesfile' affects no only the 'submodule' git command\n+# but many other git commands that directly or or *indirecly* use the\n+# submodules_file variable.\n+#\n+# In particular all the commands that use unpack_trees(), like 'am', 'clone',\n+# etc. are affected.\n+#\n+# Anyways this is not a problem because the option is passed to all git\n+# commands in the \"./bin-wrappers/git\" wrapper script.\n+\n+set -e\n+\n+if [ ! -e .patched_test_suite ];\n+then\n+\n+  echo \"Patching the test suite...\"\n+\n+  find t/ -type f -name t7506-status-submodule.sh -exec sed -i \\\n+    -e \"s/^cat \\(.*\\)\\\\\\EOF/cat \\1EOF/g\" \\\n+    -e \"s/\\(.*\\)\\.gitmodules$/\\1\\${GITMODULES_FILE:-.gitmodules}/g\" \\\n+    -e \"s/^AA \\.gitmodules$/AA \\${GITMODULES_FILE:-.gitmodules}/g\" \\\n+    {} \\;\n+\n+  find t/ -type f -name t7508-status.sh -exec sed -i \\\n+    -e \"s/touch \\(.*\\)\\.gitmodules/touch \\1\\\\\\\"\\${GITMODULES_FILE:-.gitmodules}\\\\\\\"/g\" \\\n+    -e \"s/\\t\\.gitmodules$/\\t\\${GITMODULES_FILE:-.gitmodules}/g\" \\\n+    {} \\;\n+\n+  find t/ -type f -exec sed -i \\\n+    -e \"s/git \\(.*\\)config \\(.*\\)-f ..\\/\\.gitmodules/git \\1config \\2-f ..\\/\\'\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"\\'/g\" \\\n+    -e \"s/git \\(.*\\)config \\(.*\\)-f \\.gitmodules/git \\1config \\2-f \\\"\\${GITMODULES_FILE:-.gitmodules}\\\"/g\" \\\n+    -e \"s/git \\(.*\\)config \\(.*\\)--file=\\.gitmodules/git \\1config \\2--file=\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"/g\" \\\n+    -e \"s/git add \\(.*\\)\\.gitmodules\\(.*\\)/git add \\1\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"\\2/g\" \\\n+    -e \"s/test_cmp expect \\.gitmodules/test_cmp expect \\\"\\${GITMODULES_FILE:-.gitmodules}\\\"/g\" \\\n+    -e \"s/cp .gitmodules pristine-\\.gitmodules/cp \\\"\\${GITMODULES_FILE:-.gitmodules}\\\" pristine-gitmodules/g\" \\\n+    -e \"s/cp pristine-\\.gitmodules .gitmodules/cp pristine-gitmodules \\\"\\${GITMODULES_FILE:-.gitmodules}\\\"/g\" \\\n+    -e \"s/cp \\.gitmodules \\.gitmodules.bak/cp \\'\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"\\' .gitmodules.bak/g\" \\\n+    -e \"s/test-tool submodule-config/test-tool submodule-config --submodules_file \\'\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"\\'/g\" \\\n+    -e \"s/\\$sha1:\\.gitmodules/\\$sha1:\\'\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"\\'/g\" \\\n+    -e \"s/cat >\\.gitmodules/cat >\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"/g\" \\\n+    -e \"s/sed \\(.*\\)<\\.gitmodules/sed \\1<\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"/g\" \\\n+    -e \"s/rm \\(.*\\)\\.gitmodules/rm \\1\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"/g\" \\\n+    -e \"s/echo \\(.*\\)\\.gitmodules/echo \\1\\\\\\\"\\${GITMODULES_FILE:-.gitmodules}\\\\\\\"/g\" \\\n+    -e \"s/\\t\\(.*\\)\\.gitmodules$/\\t\\1\\'\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"\\'/g\" \\\n+    -e \"s/\\t\\(.*\\)\\.gitmodules:/\\t\\1\\'\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"\\':/g\" \\\n+    -e \"s/\\t\\(.*\\)\\.gitmodules \\&\\&$/\\t\\1\\'\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"\\' \\&\\&/g\" \\\n+    -e \"s/\\t\\(.*\\)\\.gitmodules) \\&\\&$/\\t\\1\\'\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"\\') \\&\\&/g\" \\\n+    -e \"s/repo\\/\\.gitmodules /repo\\/\\'\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"\\' /g\" \\\n+    -e \"s/Submodule sm2 a5a65c9..280969a:/Submodule sm2 a5a65c9..\\'\\$(git -C sm2 rev-list -1 HEAD | cut -c1-7)\\':/g\" \\\n+    -e \"s/diff --git a\\/sm2\\/\\.gitmodules /diff --git a\\/sm2\\/\\'\\\"\\${GITMODULES_FILE:-.gitmodules}\\\"\\' /g\" \\\n+    -e \"s/^M\\([ ]\\{1,2\\}\\)\\.gitmodules$/M\\1\\${GITMODULES_FILE:-.gitmodules}/g\" \\\n+    -e \"s/^D\\([ ]\\{1,2\\}\\)\\.gitmodules$/D\\1\\${GITMODULES_FILE:-.gitmodules}/g\" \\\n+    {} \\;\n+\n+    make clean\n+    make\n+    touch .patched_test_suite\n+fi\n+\n+echo \"Running the tests with the default gitmodules file...\"\n+make test\n+\n+echo \"Running the tests with a custom gitmodules file...\"\n+GITMODULES_FILE=.gitmodules_custom make test\n+\n+echo \"Done.\"\n-- \n2.17.0\n\n"},{"id":"344593","messageId":"20180413080733.6380-2-ao2@ao2.it","threadId":"48277","inReplyTo":"20180413080733.6380-1-ao2@ao2.it","subject":"[RFC 08/10] FIXME: submodule: fix t1300-repo-config.sh to take into account the new config","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-13T08:07:31Z","receivedAt":"2018-04-13T08:08:08Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"Tests are run with the 'core.submodulesfile' config set, so\n't/t1300-repo-config.sh' needs to be fixed to account for that.\n\nThe changes to the HEREDOC lines are temporary and only needed to\nsupport the environmental variable expansion, they could go away\neventually is using a fixed value is good enough.\n---\n t/t1300-repo-config.sh | 26 ++++++++++++++++++++++----\n 1 file changed, 22 insertions(+), 4 deletions(-)\n\ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex e95b1e67d..f672a6c37 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -338,6 +338,7 @@ beta.noindent=sillyValue\n nextsection.nonewline=wow2 for me\n 123456.a123=987\n version.1.2.3eX.alpha=beta\n+core.submodulesfile=${GITMODULES_FILE:-.gitmodules}\n EOF\n \n test_expect_success 'working --list' '\n@@ -345,6 +346,7 @@ test_expect_success 'working --list' '\n \ttest_cmp expect output\n '\n cat > expect << EOF\n+core.submodulesfile=${GITMODULES_FILE:-.gitmodules}\n EOF\n \n test_expect_success '--list without repo produces empty output' '\n@@ -357,6 +359,7 @@ beta.noindent\n nextsection.nonewline\n 123456.a123\n version.1.2.3eX.alpha\n+core.submodulesfile\n EOF\n \n test_expect_success '--name-only --list' '\n@@ -964,10 +967,11 @@ inued\n inued\"\n EOF\n \n-cat > expect <<\\EOF\n+cat > expect << EOF\n section.continued=continued\n section.noncont=not continued\n section.quotecont=cont;inued\n+core.submodulesfile=${GITMODULES_FILE:-.gitmodules}\n EOF\n \n test_expect_success 'value continued on next line' '\n@@ -984,7 +988,7 @@ cat > .git/config <<\\EOF\n \tval5\n EOF\n \n-cat > expect <<\\EOF\n+cat > expect << EOF\n section.sub=section.val1\n foo=barQsection.sub=section.val2\n foo\n@@ -992,7 +996,8 @@ barQsection.sub=section.val3\n \n \n Qsection.sub=section.val4\n-Qsection.sub=section.val5Q\n+Qsection.sub=section.val5Qcore.submodulesfile\n+${GITMODULES_FILE:-.gitmodules}Q\n EOF\n test_expect_success '--null --list' '\n \tgit config --null --list >result.raw &&\n@@ -1001,6 +1006,17 @@ test_expect_success '--null --list' '\n \ttest_cmp expect result\n '\n \n+cat > expect << EOF\n+section.sub=section.val1\n+foo=barQsection.sub=section.val2\n+foo\n+barQsection.sub=section.val3\n+\n+\n+Qsection.sub=section.val4\n+Qsection.sub=section.val5Q\n+EOF\n+\n test_expect_success '--null --get-regexp' '\n \tgit config --null --get-regexp \"val[0-9]\" >result.raw &&\n \tnul_to_q <result.raw >result &&\n@@ -1495,6 +1511,7 @@ test_expect_success '--show-origin with --list' '\n \t\tfile:.git/config\tuser.override=local\n \t\tfile:.git/config\tinclude.path=../include/relative.include\n \t\tfile:.git/../include/relative.include\tuser.relative=include\n+\t\tcommand line:\tcore.submodulesfile=${GITMODULES_FILE:-.gitmodules}\n \t\tcommand line:\tuser.cmdline=true\n \tEOF\n \tgit -c user.cmdline=true config --list --show-origin >output &&\n@@ -1511,7 +1528,8 @@ test_expect_success '--show-origin with --list --null' '\n \t\ttrueQfile:.git/configQuser.override\n \t\tlocalQfile:.git/configQinclude.path\n \t\t../include/relative.includeQfile:.git/../include/relative.includeQuser.relative\n-\t\tincludeQcommand line:Quser.cmdline\n+\t\tincludeQcommand line:Qcore.submodulesfile\n+\t\t${GITMODULES_FILE:-.gitmodules}Qcommand line:Quser.cmdline\n \t\ttrueQ\n \tEOF\n \tgit -c user.cmdline=true config --null --list --show-origin >output.raw &&\n-- \n2.17.0\n\n"},{"id":"344636","messageId":"CAGZ79kagFY_AnLJ0Zjcu++e567JHYeHaW-0k8=4Q4rsyqtnU9w@mail.gmail.com","threadId":"48277","inReplyTo":"20180413080733.6380-1-ao2@ao2.it","subject":"Re: [RFC 07/10] FIXME: wrap-for-bin.sh: set 'core.submodulesFile' for each git invocation","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-04-13T20:05:18Z","receivedAt":"2018-04-13T20:05:25Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Hi Antonio,\n\nOn Fri, Apr 13, 2018 at 1:07 AM, Antonio Ospite <ao2@ao2.it> wrote:\n> This is to test custom gitmodules file paths. The default path can be\n> overridden using the 'GIT_MODULES_FILE' environmental variable.\n>\n> Maybe In the final patch the option should be set only when running\n> tests and not unconditionally in the wrapper script, but as a proof of\n> concept the wrapper script was a convenient location.\n>\n> Also, in the final patch a fixed custom file path could be used instead\n> of the environmental variable: to exercise the code it should be enough\n> to have a value different from the default one.\n>\n> The change to 't0001-init.sh' is needed to make the test pass, since now\n> a config is set on the command line.\n\nMissing sign off.\n\nSo you'd think we'd have to rerun the test suite with GIT_MODULES_FILE set?\nThat makes for an expensive test. Can we have just a few tests for a few\ncommands to see that the basics are working correctly?\n\n\n> ---\n>  Makefile        | 3 ++-\n>  t/t0001-init.sh | 1 +\n>  wrap-for-bin.sh | 2 ++\n>  3 files changed, 5 insertions(+), 1 deletion(-)\n>  mode change 100644 => 100755 wrap-for-bin.sh\n>\n> diff --git a/Makefile b/Makefile\n> index f18168725..38ee1f6a2 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -2480,7 +2480,8 @@ bin-wrappers/%: wrap-for-bin.sh\n>         @mkdir -p bin-wrappers\n>         $(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n>              -e 's|@@BUILD_DIR@@|$(shell pwd)|' \\\n> -            -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%,$(@F))|' < $< > $@ && \\\n> +            -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%,$(@F))|' \\\n> +            -e 's|git\\\"|git\\\" $$GIT_OPTIONS|' < $< > $@ && \\\n>         chmod +x $@\n>\n>  # GNU make supports exporting all variables by \"export\" without parameters.\n> diff --git a/t/t0001-init.sh b/t/t0001-init.sh\n> index c413bff9c..6fa3fd24e 100755\n> --- a/t/t0001-init.sh\n> +++ b/t/t0001-init.sh\n> @@ -93,6 +93,7 @@ test_expect_success 'No extra GIT_* on alias scripts' '\n>                 sed -n \\\n>                         -e \"/^GIT_PREFIX=/d\" \\\n>                         -e \"/^GIT_TEXTDOMAINDIR=/d\" \\\n> +                       -e \"/^GIT_CONFIG_PARAMETERS=/d\" \\\n>                         -e \"/^GIT_/s/=.*//p\" |\n>                 sort\n>         EOF\n> diff --git a/wrap-for-bin.sh b/wrap-for-bin.sh\n> old mode 100644\n> new mode 100755\n> index 584240881..02bf41cbd\n> --- a/wrap-for-bin.sh\n> +++ b/wrap-for-bin.sh\n> @@ -20,6 +20,8 @@ PATH='@@BUILD_DIR@@/bin-wrappers:'\"$PATH\"\n>\n>  export GIT_EXEC_PATH GITPERLLIB PATH GIT_TEXTDOMAINDIR\n>\n> +GIT_OPTIONS=\"-c core.submodulesfile=${GITMODULES_FILE:-.gitmodules}\"\n> +\n>  if test -n \"$GIT_TEST_GDB\"\n>  then\n>         unset GIT_TEST_GDB\n> --\n> 2.17.0\n>\n"},{"id":"344784","messageId":"20180416133312.241ada0390d6fec18856b027@ao2.it","threadId":"48277","inReplyTo":"CAGZ79kZbZ03D7ysaVXYkV3v0jO6K7kEOc9sT2zA+Xc6mqLNL9Q@mail.gmail.com","subject":"Re: [RFC 00/10] Make .the gitmodules file path configurable","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-16T11:33:12Z","receivedAt":"2018-04-16T11:33:19Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"On Thu, 12 Apr 2018 16:36:32 -0700\nStefan Beller <sbeller@google.com> wrote:\n\n> Hi Antonio,\n>\n\nHi Stefan,\n\n> On Thu, Apr 12, 2018 at 3:20 PM, Antonio Ospite <ao2@ao2.it> wrote:\n> > Hi,\n> >\n> > vcsh[1] uses bare git repositories and detached work-trees to manage\n> > *distinct* sets of configuration files directly into $HOME.\n> >\n> > In general, submodules have worked perfectly fine with detached\n> > work-trees for some time[2,3,4].\n> >\n> > However when multiple repositories take turns using the same directory\n> > as their work-tree, and more than one of them want to use submodules,\n> > there could still be conflicts about the '.gitmodules' file because git\n> > hardcodes this path.\n> >\n[...]\n> \n> > So this series proposes a mechanism to set an alternative path for the\n> > submodules configuration file (from now on \"gitmodules file\").\n> \n[...]\n> > Expanding on that change the first patch in the series makes the path\n> > customizable exposing a 'core.submodulesFile' configuration setting.\n> \n> I guess the similarity to core.ignoreFile is desired here. Although these\n> mechanisms are very different.\n>\n\nThe option name is similar to 'core.excludesFile' also because, when I\nstarted, I first looked at how multiple ignore files were used, so I\nmay have been influenced by that.\n\nI acknowledge that the two mechanisms are different, in particular\nbecause git *writes* the gitmodules file itself.\n\nI am not opposed to change the name, something like\n'core.submodulesConfigFile' might highlight that the syntax of the file\nis the one of git config, but I think it's too long.\n\n> > The new configuration setting can be used to set an *alternative*\n> > location for the gitmodules file; IMHO there is no need to provide\n> > *additional* locations like in the case of exclude files.\n> \n> I think there *may* be a need for additional files.\n> Currently there is only the .gitmodules file and the configuration\n> in .git/config overriding settings from .gitmodules.\n> \n> There was some discussion on the mailing list in the past, which\n> presented a intermediate layer in between these two places, in\n> a special ref, such that:\n>     base is in .gitmodules\n>     overwritten via refs/meta/submodules:.gitmodules\n>     overwritten via the .git/config\n> \n> The intermediate would be a config file that is tracked on another\n> ref. This (a) decouples main project history from submodule history\n> and (b) makes it easier to distribute as it is part of the repository.\n> \n> For example (a) is desired if you dig up an old project and the\n> submodules have all moved from one git hosting provider to another.\n> Another example would be when you fork a project with submodules\n> and don't want to mess with the main history but you just want to\n> adjust the submodule URLs. That is possible with such an intermediate\n> additional place.\n> \n> For (b) you can imagine the fork that you want to distribute in your\n> community and you don't want to tell everyone to change the\n> submodule URLs, but instead you can provide them with a prepared\n> .gitmodules file, that they have to place into that special ref (which\n> can be done via fetching).\n> \n> I digress as these ideas seem to be orthogonal to your patch series,\n> just FYI. prior discussion starting at:\n> https://public-inbox.org/git/1462317985-640-1-git-send-email-sbeller@google.com/\n> I recall there was a better discussion even prior to that, but have no\n> link handy.\n>\n\nJust to understand, is that 'refs/meta/submodules:.gitmodules' file\nmeant to be managed manually? Or do you imagine some options to\ninstruct \"git submodule\" to *write* to that file instead of .gitmodules?\n\nIn the latter case your idea could cover my use case too, couldn't it?\n\nBut most importantly, is this realistically going to be added?\nCurrently I am not that familiar with the git code base to do it\nmyself, and I've never explicitly dealt with special refs in git.\n\nThe approach of this patch series is a lot simpler, and something I can\nwork on in my spare time.\n\nPresumably (b) could even be partially supported with my changes, by\nhaving both '.gitmodules' and some custom '.gitmodules-alternative'\nfiles in the repository and tell users to clone with:\n\n  git clone --config core.submodulesFile=.gitmodules-alternative URL\n\nNot as clean as your idea but doable.\n\n[...]\n> > Since the gitmodules file is meant to be checked in into the repository,\n> > the overridden file path should be relative to the work-tree; is there\n> > a way to enforce this constraint at run time (i.e. validate the config\n> > value), or is it enough to have it documented?\n> \n> I think we'd want to check at run time, if we need this constraint.\n> \n\nI'll look into it once we decide which the way to go.\n\nThank you.\n\nCiao,\n   Antonio\n\n-- \nAntonio Ospite\nhttps://ao2.it\nhttps://twitter.com/ao2it\n\nA: Because it messes up the order in which people normally read text.\n   See http://en.wikipedia.org/wiki/Posting_style\nQ: Why is top-posting such a bad thing?\n"},{"id":"344785","messageId":"20180416133610.b0c85e131fe58819e62560f6@ao2.it","threadId":"48277","inReplyTo":"CAGZ79kagFY_AnLJ0Zjcu++e567JHYeHaW-0k8=4Q4rsyqtnU9w@mail.gmail.com","subject":"Re: [RFC 07/10] FIXME: wrap-for-bin.sh: set 'core.submodulesFile' for each git invocation","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-16T11:36:10Z","receivedAt":"2018-04-16T11:36:16Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"On Fri, 13 Apr 2018 13:05:18 -0700\nStefan Beller <sbeller@google.com> wrote:\n\n> Hi Antonio,\n> \n> On Fri, Apr 13, 2018 at 1:07 AM, Antonio Ospite <ao2@ao2.it> wrote:\n> > This is to test custom gitmodules file paths. The default path can be\n> > overridden using the 'GIT_MODULES_FILE' environmental variable.\n> >\n> > Maybe In the final patch the option should be set only when running\n> > tests and not unconditionally in the wrapper script, but as a proof of\n> > concept the wrapper script was a convenient location.\n> >\n> > Also, in the final patch a fixed custom file path could be used instead\n> > of the environmental variable: to exercise the code it should be enough\n> > to have a value different from the default one.\n> >\n> > The change to 't0001-init.sh' is needed to make the test pass, since now\n> > a config is set on the command line.\n> \n> Missing sign off.\n> \n> So you'd think we'd have to rerun the test suite with GIT_MODULES_FILE set?\n> That makes for an expensive test. Can we have just a few tests for a few\n> commands to see that the basics are working correctly?\n>\n\nThis approach of running the test suite twice was only \"exploratory\",\nsee the script in 10/10: it was never meant as a the final mechanism.\n\nThat's also why the FIXME patches do not have a sign-off.\n\nAs I tried to comment above a final version could just\nreplace the references to '.gitmodules' with some fixed non-default\nvalue, provided that the same value is passed to git via\ncore.submodulesfile \n\nIf the tests pass with a custom value they'll pass with the default\n'.gitmodules' one which is a particular case.\n\nCiao,\n   Antonio\n\n-- \nAntonio Ospite\nhttps://ao2.it\nhttps://twitter.com/ao2it\n\nA: Because it messes up the order in which people normally read text.\n   See http://en.wikipedia.org/wiki/Posting_style\nQ: Why is top-posting such a bad thing?\n"},{"id":"344802","messageId":"20180416181841.b486524b8b9b0e68e3a31bfa@ao2.it","threadId":"48277","inReplyTo":"CAGZ79kbnc17PZ9_=8QLkZgUZ0DHJKfWnxrekmgkLGFBU_0ieug@mail.gmail.com","subject":"Re: [RFC 02/10] submodule: fix getting custom gitmodule file in fetch command","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-16T16:18:41Z","receivedAt":"2018-04-16T16:18:49Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"On Thu, 12 Apr 2018 16:55:15 -0700\nStefan Beller <sbeller@google.com> wrote:\n\n> Hi Antonio,\n> \n> the subject line could also be\n>   fetch: fix custom submodule location\n> as I was not expecting this patch from the subject line.\n>\n\nOK.\n\n> On Thu, Apr 12, 2018 at 3:20 PM, Antonio Ospite <ao2@ao2.it> wrote:\n> > Import the default git configuration before accessing the gitmodules\n> > file.\n> >\n> > This is important when a value different from the default one is set via\n> > the 'core.submodulesfile' config.\n> >\n> > Signed-off-by: Antonio Ospite <ao2@ao2.it>\n> > ---\n> >  builtin/fetch.c | 2 +-\n> >  1 file changed, 1 insertion(+), 1 deletion(-)\n> >\n> > diff --git a/builtin/fetch.c b/builtin/fetch.c\n> > index dcdfc66f0..d56636f74 100644\n> > --- a/builtin/fetch.c\n> > +++ b/builtin/fetch.c\n> > @@ -1428,8 +1428,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n> >         for (i = 1; i < argc; i++)\n> >                 strbuf_addf(&default_rla, \" %s\", argv[i]);\n> >\n> > -       config_from_gitmodules(gitmodules_fetch_config, NULL);\n> >         git_config(git_fetch_config, NULL);\n> > +       config_from_gitmodules(gitmodules_fetch_config, NULL);\n> \n> Wouldn't this break the overwriting behavior?\n> e.g. you configure a submodule URL in .gitmodules and then override it\n> in .git/config,\n> then we'd currently first load config from the modules file and then override it\n> in git_config(git_fetch_config,..), whereas swapping them might have\n> unintended consequences? Do the tests pass with this patch?\n\nThe patch changes the current behavior indeed, but it does not break\nany of the existing tests.\n\nAnyway, to be on the safe side, I could load only the\ncore.submodulesFile option from the global configuration, maybe even in\nconfig_from_gitmodules() itself, before accessing the gitmodules file,\nbut I still don't know how to do that.\n\nIs there an API to just load one config setting?\n\nCiao,\n   Antonio\n\n-- \nAntonio Ospite\nhttps://ao2.it\nhttps://twitter.com/ao2it\n\nA: Because it messes up the order in which people normally read text.\n   See http://en.wikipedia.org/wiki/Posting_style\nQ: Why is top-posting such a bad thing?\n"},{"id":"344806","messageId":"20180416183742.032530a4d44faccd44189ea6@ao2.it","threadId":"48277","inReplyTo":"CAGZ79kZV+MLaVp4AM77bJkT=MeBvDSHTxZCni8dkqq4VLWZ0AA@mail.gmail.com","subject":"Re: [RFC 01/10] submodule: add 'core.submodulesFile' to override the '.gitmodules' path","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-16T16:37:42Z","receivedAt":"2018-04-16T16:37:48Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"On Thu, 12 Apr 2018 16:50:03 -0700\nStefan Beller <sbeller@google.com> wrote:\n\n> Hi Antonio,\n> \n> On Thu, Apr 12, 2018 at 3:20 PM, Antonio Ospite <ao2@ao2.it> wrote:\n> > When multiple repositories with detached work-trees take turns using the\n> > same directory as their work-tree, and more than one of them want to use\n> > submodules, there will be conflicts about the '.gitmodules' file.\n> \n> unlike other files which would not conflict?\n> There might be file names such as LICENSE, Readme.md etc,\n> which are common enough that they would produce conflicts as well?\n> I find this argument on its own rather weak. (\"Just delete everything in\n> the working dir before using it with another repository\"). I might be\n> missing a crucial bit here?\n>\n\nAll the vcsh repositories _share_ the same work-tree; they may control\nit taking turns but, in general, all files are meant to be checked out\nat all times as the basic use case is: *distinct* sets of config files.\n\nMaybe saying that the repositories \"take turns\" is confusing.\nIt's an unnecessary information, so I will omit that part form the\ncommit message.\n\nAfter your question I've done some research and I've seen other vcsh\nusers managing conflicting LICENSE and README files using git\nsparse-checkouts, to have these files in the single repositories but\nnot checked out in the shared work-tree:\nhttps://github.com/RichiH/vcsh/issues/120#issuecomment-42639619\nhttps://github.com/jwhitley/vcsh-root/commit/30b0d495c2cbe47ae9617ace9c2c14720d961d78\n\nHowever I guess that my point here is that the gitmodules file is\nsomething that influences git behavior so it should not be on the user's\nshoulder to manage conflicts for it, and most importantly it needs to\nbe checked out for git to access it, doesn't it?\n\n> > git hardcodes this path so it's not possible to override its location on\n> > a per-repository basis to allow such repositories to coexists\n> > peacefully.\n> >\n> > Make the path of the \"gitmodules file\" customizable exposing\n> > a 'core.submodulesFile' configuration setting.\n> >\n> > The default value will still be '.gitmodules' when 'core.submodulesFile'\n> > is not set.\n> \n> ok.\n> \n> \n> > --- a/cache.h\n> > +++ b/cache.h\n> > @@ -1774,6 +1774,7 @@ extern void prepare_pager_args(struct child_process *, const char *pager);\n> >  extern const char *editor_program;\n> >  extern const char *askpass_program;\n> >  extern const char *excludes_file;\n> > +extern const char *submodules_file;\n> \n> Could you place this variable in repository.h in struct repository?\n> (Some developers currently try to move any global state to that place,\n> as that makes working with e.g. nested submodules easier in-process\n> and you would not need to spawn processes for submodules)\n> \n> Once migrated to the repository struct mentioned above, you'd access\n> it via the_repository->submodules_file for the main repository.\n>\n\nOK, thanks, I didn't like the global variable either, I was just copying\nfrom excludes_file.\n\n> \n> > diff --git a/git-submodule.sh b/git-submodule.sh\n> > index 24914963c..610fd0dc5 100755\n> > --- a/git-submodule.sh\n> > +++ b/git-submodule.sh\n> > @@ -71,7 +71,9 @@ get_submodule_config () {\n> >         value=$(git config submodule.\"$name\".\"$option\")\n> >         if test -z \"$value\"\n> >         then\n> > -               value=$(git config -f .gitmodules submodule.\"$name\".\"$option\")\n> > +               gitmodules_file=$(git config core.submodulesfile)\n> > +               : ${gitmodules_file:=.gitmodules}\n> > +               value=$(git config -f \"$gitmodules_file\" submodule.\"$name\".\"$option\")\n> \n> I wonder if it would be cheaper to write a special config lookup now, e.g.\n> in builtin/submodule--helper.c we could have a \"config-from-gitmodules\"\n> subcommand that is looking up the modules file and then running the config\n> on that file.\n>\n\nCan you give an example from the user point of view of such a\n\"config-from-gitmodules\" command?\n\nI might look into it, but that can also be a followup change. \n\n> I am surprised how little access of the .gitmodules is left in git-submodule.sh\n> (which is partially ported to the builtin/submodule--helper.c)\n> \n> > diff --git a/submodule-config.c b/submodule-config.c\n> > index 3f2075764..8a3396ade 100644\n> > --- a/submodule-config.c\n> > +++ b/submodule-config.c\n> > @@ -468,7 +468,7 @@ static int gitmodule_oid_from_commit(const struct object_id *treeish_name,\n> >                 return 1;\n> >         }\n> >\n> > -       strbuf_addf(rev, \"%s:.gitmodules\", oid_to_hex(treeish_name));\n> > +       strbuf_addf(rev, \"%s:%s\", oid_to_hex(treeish_name), submodules_file);\n> >         if (get_oid(rev->buf, gitmodules_oid) >= 0)\n> >                 ret = 1;\n> >\n> > @@ -583,7 +583,7 @@ void repo_read_gitmodules(struct repository *repo)\n> >                 if (repo_read_index(repo) < 0)\n> >                         return;\n> >\n> > -               gitmodules = repo_worktree_path(repo, GITMODULES_FILE);\n> > +               gitmodules = repo_worktree_path(repo, submodules_file);\n> >\n> >                 if (!is_gitmodules_unmerged(repo->index))\n> >                         git_config_from_file(gitmodules_cb, gitmodules, repo);\n> > diff --git a/submodule.c b/submodule.c\n> > index 9a50168b2..2afbdb644 100644\n> > --- a/submodule.c\n> > +++ b/submodule.c\n> > @@ -36,13 +36,13 @@ static struct oid_array ref_tips_after_fetch;\n> >   */\n> >  int is_gitmodules_unmerged(const struct index_state *istate)\n> >  {\n> > -       int pos = index_name_pos(istate, GITMODULES_FILE, strlen(GITMODULES_FILE));\n> > +       int pos = index_name_pos(istate, submodules_file, strlen(submodules_file));\n> \n> Ah, regarding the coverletter: This clearly assumes the modules\n> file is in the tree. So at least here we would make an exception\n> for files outside the tree to either not check for un-merged-ness or\n> disallow that case entirely.\n>\n\nSorry I am not sure I follow what you are saying here, keep in mind\nthat I am new to git internals.\n\nDo you mean that, even if we ensure (in\nconfig.c::git_default_core_config) that only paths relative to\nthe work-tree are allowed, we still have to check here that the\nconstraint is respected? And is so, why?\n\n> There are quite a few functions in submodule.c which access the new global. :/\n> So moving them to the_repository should be fine, but eventually (not\n> in this series)\n> all these functions would would want to take a repository argument as well\n> such that they work on more than the_repository.\n> \n\nI will surely get rid of the global variable, but about changing the\nfunctions signatures I don't feel like promising anything just yet.\n\nThanks,\n   Antonio\n\n-- \nAntonio Ospite\nhttps://ao2.it\nhttps://twitter.com/ao2it\n\nA: Because it messes up the order in which people normally read text.\n   See http://en.wikipedia.org/wiki/Posting_style\nQ: Why is top-posting such a bad thing?\n"},{"id":"344814","messageId":"CAGZ79kZE-uKSMBhOF-Xu+HW5Vr5p+C1aHTmQN40OArpmM22-YA@mail.gmail.com","threadId":"48277","inReplyTo":"20180416133312.241ada0390d6fec18856b027@ao2.it","subject":"Re: [RFC 00/10] Make .the gitmodules file path configurable","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-04-16T19:22:38Z","receivedAt":"2018-04-16T19:22:46Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Hi Antonio,\n\n> I acknowledge that the two mechanisms are different, in particular\n> because git *writes* the gitmodules file itself.\n>\n> I am not opposed to change the name, something like\n> 'core.submodulesConfigFile' might highlight that the syntax of the file\n> is the one of git config, but I think it's too long.\n\nI was not speculating on a better name, but on the nature of the\nconfiguration, gitignore is additive and errors are easy to see, but in\ngitmodules, there is only one \"correct\" path+name, so the problem\nspace is not additive, rather we can have a discussion where we get\nthe correct config from with low odds of errors.\n\n>> > The new configuration setting can be used to set an *alternative*\n>> > location for the gitmodules file; IMHO there is no need to provide\n>> > *additional* locations like in the case of exclude files.\n>>\n>> I think there *may* be a need for additional files.\n>> Currently there is only the .gitmodules file and the configuration\n>> in .git/config overriding settings from .gitmodules.\n>>\n>> There was some discussion on the mailing list in the past, which\n>> presented a intermediate layer in between these two places, in\n>> a special ref, such that:\n>>     base is in .gitmodules\n>>     overwritten via refs/meta/submodules:.gitmodules\n>>     overwritten via the .git/config\n>>\n>> The intermediate would be a config file that is tracked on another\n>> ref. This (a) decouples main project history from submodule history\n>> and (b) makes it easier to distribute as it is part of the repository.\n>>\n>> For example (a) is desired if you dig up an old project and the\n>> submodules have all moved from one git hosting provider to another.\n>> Another example would be when you fork a project with submodules\n>> and don't want to mess with the main history but you just want to\n>> adjust the submodule URLs. That is possible with such an intermediate\n>> additional place.\n>>\n>> For (b) you can imagine the fork that you want to distribute in your\n>> community and you don't want to tell everyone to change the\n>> submodule URLs, but instead you can provide them with a prepared\n>> .gitmodules file, that they have to place into that special ref (which\n>> can be done via fetching).\n>>\n>> I digress as these ideas seem to be orthogonal to your patch series,\n>> just FYI. prior discussion starting at:\n>> https://public-inbox.org/git/1462317985-640-1-git-send-email-sbeller@google.com/\n>> I recall there was a better discussion even prior to that, but have no\n>> link handy.\n>>\n>\n> Just to understand, is that 'refs/meta/submodules:.gitmodules' file\n> meant to be managed manually? Or do you imagine some options to\n> instruct \"git submodule\" to *write* to that file instead of .gitmodules?\n\nI imagined it to be managed manually as it would enable some\nworkflows for downstream users of superproject repos.\n\nBut I'd think a convenient way to write to this location would be\nsuper useful, so we ought to have that eventually.\n\n> In the latter case your idea could cover my use case too, couldn't it?\n\nI would think so, yes.\n\n> But most importantly, is this realistically going to be added?\n\nI plan on adding it eventually. It depends on the priorities and\nschedule, no promises, though.\n\n> Currently I am not that familiar with the git code base to do it\n> myself, and I've never explicitly dealt with special refs in git.\n\nI think core git only uses them for \"actual refs\", e.g. remote\ntracking branches are used to know about the sha1. This new\nspecial ref would be used to store content outside the main tree,\nso we'd have too lookup the blob in that not-checked-out commit\nand read and write there.\n\n> The approach of this patch series is a lot simpler, and something I can\n> work on in my spare time.\n> Presumably (b) could even be partially supported with my changes, by\n> having both '.gitmodules' and some custom '.gitmodules-alternative'\n> files in the repository and tell users to clone with:\n>\n>   git clone --config core.submodulesFile=.gitmodules-alternative URL\n>\n> Not as clean as your idea but doable.\n\nTraditionally Git had a strong stance on not transporting config\nin the repo (except submodule URLs :/) itself, so I guess\nthis .gitmodules-alternative would not be a file in the tree, but\na URL or something?\n\n> [...]\n>> > Since the gitmodules file is meant to be checked in into the repository,\n>> > the overridden file path should be relative to the work-tree; is there\n>> > a way to enforce this constraint at run time (i.e. validate the config\n>> > value), or is it enough to have it documented?\n>>\n>> I think we'd want to check at run time, if we need this constraint.\n>>\n>\n> I'll look into it once we decide which the way to go.\n>\n> Thank you.\n>\n\nThanks for bringing up this easier approach.\nStefan\n"},{"id":"344815","messageId":"CAGZ79kZMXjEAHewkwBR4R91c46+jEL5s9rX2D+2gXo2X6dcozA@mail.gmail.com","threadId":"48277","inReplyTo":"20180416181841.b486524b8b9b0e68e3a31bfa@ao2.it","subject":"Re: [RFC 02/10] submodule: fix getting custom gitmodule file in fetch command","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-04-16T19:23:59Z","receivedAt":"2018-04-16T19:24:06Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Mon, Apr 16, 2018 at 9:18 AM, Antonio Ospite <ao2@ao2.it> wrote:\n\n>\n> Is there an API to just load one config setting?\n\nDo you mean to\n\n  git -c key=value foo-command --options ...\n"},{"id":"344820","messageId":"20180416224645.f5d2f49702ad647cabd8c98d@ao2.it","threadId":"48277","inReplyTo":"CAGZ79kZMXjEAHewkwBR4R91c46+jEL5s9rX2D+2gXo2X6dcozA@mail.gmail.com","subject":"Re: [RFC 02/10] submodule: fix getting custom gitmodule file in fetch command","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-16T20:46:45Z","receivedAt":"2018-04-16T20:46:52Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"On Mon, 16 Apr 2018 12:23:59 -0700\nStefan Beller <sbeller@google.com> wrote:\n\n> On Mon, Apr 16, 2018 at 9:18 AM, Antonio Ospite <ao2@ao2.it> wrote:\n> \n> >\n> > Is there an API to just load one config setting?\n> \n> Do you mean to\n> \n>   git -c key=value foo-command --options ...\n\nI meant, instead of:\n\n  git_config(git_fetch_config, NULL);\n\nwhich updates a series of config settings, something which loads\n_in_the_code_ just the one value for 'core.submodulesFile' previously\nset either via \"git -c\" or \"git config\".\n\nIt turns out what I was looking for is git_config_get_string_const().\n\nThe new patch will be simply this:\n\ndiff --git a/config.c b/config.c\nindex 6ffb1d501..1ef9801d3 100644\n--- a/config.c\n+++ b/config.c\n@@ -2087,6 +2087,7 @@ int git_config_get_pathname(const char *key, const char **dest)\n  */\n void config_from_gitmodules(config_fn_t fn, void *data)\n {\n+       git_config_get_string_const(\"core.submodulesFile\", &submodules_file);\n        if (the_repository->worktree) {\n                char *file = repo_worktree_path(the_repository, submodules_file);\n                git_config_from_file(fn, file, data);\n\n\nWhich covers my use case without changing the fetch behavior for previous\nusers, as \"core.submodulesFile\" is a new option.\n\nThanks,\n   Antonio\n\n-- \nAntonio Ospite\nhttps://ao2.it\nhttps://twitter.com/ao2it\n\nA: Because it messes up the order in which people normally read text.\n   See http://en.wikipedia.org/wiki/Posting_style\nQ: Why is top-posting such a bad thing?\n"},{"id":"344822","messageId":"CAGZ79kajTdkPKpcjH3NXBE75qWnNCCq_OefAjQsw17hK_VEyCw@mail.gmail.com","threadId":"48277","inReplyTo":"20180416183742.032530a4d44faccd44189ea6@ao2.it","subject":"Re: [RFC 01/10] submodule: add 'core.submodulesFile' to override the '.gitmodules' path","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-04-16T21:22:35Z","receivedAt":"2018-04-16T21:22:44Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Mon, Apr 16, 2018 at 9:37 AM, Antonio Ospite <ao2@ao2.it> wrote:\n> On Thu, 12 Apr 2018 16:50:03 -0700\n> Stefan Beller <sbeller@google.com> wrote:\n>\n>> Hi Antonio,\n>>\n>> On Thu, Apr 12, 2018 at 3:20 PM, Antonio Ospite <ao2@ao2.it> wrote:\n>> > When multiple repositories with detached work-trees take turns using the\n>> > same directory as their work-tree, and more than one of them want to use\n>> > submodules, there will be conflicts about the '.gitmodules' file.\n>>\n>> unlike other files which would not conflict?\n>> There might be file names such as LICENSE, Readme.md etc,\n>> which are common enough that they would produce conflicts as well?\n>> I find this argument on its own rather weak. (\"Just delete everything in\n>> the working dir before using it with another repository\"). I might be\n>> missing a crucial bit here?\n>>\n>\n> All the vcsh repositories _share_ the same work-tree; they may control\n> it taking turns but, in general, all files are meant to be checked out\n> at all times as the basic use case is: *distinct* sets of config files.\n>\n> Maybe saying that the repositories \"take turns\" is confusing.\n> It's an unnecessary information, so I will omit that part form the\n> commit message.\n\nSo they all have the same workdir, do they track the same set of files\nor do they track a disjoint set of files, and ignoring the other repositories\nfiles via the ignore mechanism?\n\nThis sounds like an interesting setup. I never though of that as something\nuseful (in either configuration).\n\n> After your question I've done some research and I've seen other vcsh\n> users managing conflicting LICENSE and README files using git\n> sparse-checkouts, to have these files in the single repositories but\n> not checked out in the shared work-tree:\n> https://github.com/RichiH/vcsh/issues/120#issuecomment-42639619\n> https://github.com/jwhitley/vcsh-root/commit/30b0d495c2cbe47ae9617ace9c2c14720d961d78\n>\n> However I guess that my point here is that the gitmodules file is\n> something that influences git behavior so it should not be on the user's\n> shoulder to manage conflicts for it, and most importantly it needs to\n> be checked out for git to access it, doesn't it?\n\nGood point! I wonder if the cleaner solution would be to just\ntell git to use HEAD:.gitmodules and not check out the file?\nthen you would not need to come up with a namespace for names\nof the .gitmodules files and scatter them into the worktree as well?\n\n\n>> > -               value=$(git config -f .gitmodules submodule.\"$name\".\"$option\")\n>> > +               gitmodules_file=$(git config core.submodulesfile)\n>> > +               : ${gitmodules_file:=.gitmodules}\n>> > +               value=$(git config -f \"$gitmodules_file\" submodule.\"$name\".\"$option\")\n>>\n>> I wonder if it would be cheaper to write a special config lookup now, e.g.\n>> in builtin/submodule--helper.c we could have a \"config-from-gitmodules\"\n>> subcommand that is looking up the modules file and then running the config\n>> on that file.\n>>\n>\n> Can you give an example from the user point of view of such a\n> \"config-from-gitmodules\" command?\n>\n\n    git submodule config <name> <option>\n\nas an 'alias' for\n\n               gitmodules_file=$(git config core.submodulesfile)\n               : ${gitmodules_file:=.gitmodules}\n               value=$(git config -f \"$gitmodules_file\"\nsubmodule.\"$name\".\"$option\")\n\nThe helper would figure out which config file to load form\n(.gitmodules in tree, HEAD:.gitmodules, your new proposed gitmodules file,\n.git/config... or the special ref) and then return the <option> for <name>\n\nSo maybe:\n\n    $ git clone https://gerrit.googlesource.com/gerrit && cd gerrit\n    # ^ My goto-repo with submodules\n\n    $ git submodule config \"plugins/hooks\" URL\n    ../plugins/hooks\n\n\n\n> I might look into it, but that can also be a followup change.\n\n\n>> > diff --git a/submodule.c b/submodule.c\n>> > index 9a50168b2..2afbdb644 100644\n>> > --- a/submodule.c\n>> > +++ b/submodule.c\n>> > @@ -36,13 +36,13 @@ static struct oid_array ref_tips_after_fetch;\n>> >   */\n>> >  int is_gitmodules_unmerged(const struct index_state *istate)\n>> >  {\n>> > -       int pos = index_name_pos(istate, GITMODULES_FILE, strlen(GITMODULES_FILE));\n>> > +       int pos = index_name_pos(istate, submodules_file, strlen(submodules_file));\n>>\n>> Ah, regarding the coverletter: This clearly assumes the modules\n>> file is in the tree. So at least here we would make an exception\n>> for files outside the tree to either not check for un-merged-ness or\n>> disallow that case entirely.\n>>\n>\n> Sorry I am not sure I follow what you are saying here, keep in mind\n> that I am new to git internals.\n>\n> Do you mean that, even if we ensure (in\n> config.c::git_default_core_config) that only paths relative to\n> the work-tree are allowed, we still have to check here that the\n> constraint is respected? And is so, why?\n\nindex_name_pos looks up a position of a file in the index,\nwhich would fail for any file not in the index.\n\nSo if we give a path outside the tree, the lookup would fail\nand we'd treat it as no .gitmodules file would be found,\nwhich implies is_gitmodules_unmerged = false.\n\nThat sounds about right, but I think we could make the\ndistinction clearer, i.e. out-of-tree .gitmodule files *cannot*\nbe \"unmerged\" as that requires them to be part of a git\nrepository with a merge in progress.\n\n>> There are quite a few functions in submodule.c which access the new global. :/\n>> So moving them to the_repository should be fine, but eventually (not\n>> in this series)\n>> all these functions would would want to take a repository argument as well\n>> such that they work on more than the_repository.\n>>\n>\n> I will surely get rid of the global variable, but about changing the\n> functions signatures I don't feel like promising anything just yet.\n\nYes, I would just use the_repository->... for now and as said by\n\"(not in this series)\" we can do that later. It was more of a reminder\nto myself, sorry for the confusion.\n\nThanks,\nStefan\n"},{"id":"344978","messageId":"20180418134357.1e417fb22201b6a6b67c02c0@ao2.it","threadId":"48277","inReplyTo":"CAGZ79kajTdkPKpcjH3NXBE75qWnNCCq_OefAjQsw17hK_VEyCw@mail.gmail.com","subject":"Re: [RFC 01/10] submodule: add 'core.submodulesFile' to override the '.gitmodules' path","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-18T11:43:57Z","receivedAt":"2018-04-18T11:44:05Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"On Mon, 16 Apr 2018 14:22:35 -0700\nStefan Beller <sbeller@google.com> wrote:\n\n> On Mon, Apr 16, 2018 at 9:37 AM, Antonio Ospite <ao2@ao2.it> wrote:\n> > On Thu, 12 Apr 2018 16:50:03 -0700\n> > Stefan Beller <sbeller@google.com> wrote:\n> >\n> >> Hi Antonio,\n> >>\n> >> On Thu, Apr 12, 2018 at 3:20 PM, Antonio Ospite <ao2@ao2.it> wrote:\n> >> > When multiple repositories with detached work-trees take turns using the\n> >> > same directory as their work-tree, and more than one of them want to use\n> >> > submodules, there will be conflicts about the '.gitmodules' file.\n> >>\n> >> unlike other files which would not conflict?\n> >> There might be file names such as LICENSE, Readme.md etc,\n> >> which are common enough that they would produce conflicts as well?\n> >> I find this argument on its own rather weak. (\"Just delete everything in\n> >> the working dir before using it with another repository\"). I might be\n> >> missing a crucial bit here?\n> >>\n> >\n> > All the vcsh repositories _share_ the same work-tree; they may control\n> > it taking turns but, in general, all files are meant to be checked out\n> > at all times as the basic use case is: *distinct* sets of config files.\n> >\n> > Maybe saying that the repositories \"take turns\" is confusing.\n> > It's an unnecessary information, so I will omit that part form the\n> > commit message.\n> \n> So they all have the same workdir, do they track the same set of files\n> or do they track a disjoint set of files, and ignoring the other repositories\n> files via the ignore mechanism?\n>\n\nTo recap,\n\nvcsh[1] sets $HOME as the work-tree of multiple repositories to track\ndifferent sets of dotfiles in distinct repositories, while still having\nthe files directly available in $HOME. Each repository can ignore\nuntracked files via the ignore mechanism (namely core.excludesFile).\n\n[1] https://github.com/RichiH/vcsh\n\nFor all this to work well, the sets of the tracked files would also need\nto be disjoint, and usually they \"practically\" are, once a few\nexceptions are taken care of.\n\nCommon intersecting items like LICENSE and README can be handled via\nsparse-checkout to have \"disjoint checkouts\" and this solves most of\nthe problems, but the same mechanism cannot be used for .gitmodules as\nit needs to be checked out.\n\nAnd the problem cannot be worked around like done with .gitignore\n(using core.excludesFile instead) because .gitmodules is unique and\nhardcoded.\n\n> This sounds like an interesting setup. I never though of that as something\n> useful (in either configuration).\n>\n\nGive vcsh a try maybe.\n\n[...]\n> > However I guess that my point here is that the gitmodules file is\n> > something that influences git behavior so it should not be on the user's\n> > shoulder to manage conflicts for it, and most importantly it needs to\n> > be checked out for git to access it, doesn't it?\n> \n> Good point! I wonder if the cleaner solution would be to just\n> tell git to use HEAD:.gitmodules and not check out the file?\n> then you would not need to come up with a namespace for names\n> of the .gitmodules files and scatter them into the worktree as well?\n>\n\nAny solution which:\n\n  1. prevents the gitmodules file to be checked out\n  2. but still tracks it in the git repository\n\nOR\n  \n  1. allows to set the gitmoudles file under some namespace\n\nwould work for vcsh I guess.\n\n> \n> >> > -               value=$(git config -f .gitmodules submodule.\"$name\".\"$option\")\n> >> > +               gitmodules_file=$(git config core.submodulesfile)\n> >> > +               : ${gitmodules_file:=.gitmodules}\n> >> > +               value=$(git config -f \"$gitmodules_file\" submodule.\"$name\".\"$option\")\n> >>\n> >> I wonder if it would be cheaper to write a special config lookup now, e.g.\n> >> in builtin/submodule--helper.c we could have a \"config-from-gitmodules\"\n> >> subcommand that is looking up the modules file and then running the config\n> >> on that file.\n> >>\n> >\n> > Can you give an example from the user point of view of such a\n> > \"config-from-gitmodules\" command?\n> >\n> \n>     git submodule config <name> <option>\n> \n> as an 'alias' for\n> \n>                gitmodules_file=$(git config core.submodulesfile)\n>                : ${gitmodules_file:=.gitmodules}\n>                value=$(git config -f \"$gitmodules_file\"\n> submodule.\"$name\".\"$option\")\n> \n> The helper would figure out which config file to load form\n> (.gitmodules in tree, HEAD:.gitmodules, your new proposed gitmodules file,\n> .git/config... or the special ref) and then return the <option> for <name>\n> \n> So maybe:\n> \n>     $ git clone https://gerrit.googlesource.com/gerrit && cd gerrit\n>     # ^ My goto-repo with submodules\n> \n>     $ git submodule config \"plugins/hooks\" URL\n>     ../plugins/hooks\n> \n>\n\nI may look into such supporting changes once you decide the approach to\ntake for the bigger problem.\n\nThank you,\n   Antonio\n\n-- \nAntonio Ospite\nhttps://ao2.it\nhttps://twitter.com/ao2it\n\nA: Because it messes up the order in which people normally read text.\n   See http://en.wikipedia.org/wiki/Posting_style\nQ: Why is top-posting such a bad thing?\n"},{"id":"345003","messageId":"CAGZ79kb6-JaqUhgb_BdegbmyZowbMwR35UDcvSaXLCvWtVkjmA@mail.gmail.com","threadId":"48277","inReplyTo":"20180418134357.1e417fb22201b6a6b67c02c0@ao2.it","subject":"Re: [RFC 01/10] submodule: add 'core.submodulesFile' to override the '.gitmodules' path","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-04-18T18:44:26Z","receivedAt":"2018-04-18T18:44:32Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Hi Antonio,\n\n>>\n>> Good point! I wonder if the cleaner solution would be to just\n>> tell git to use HEAD:.gitmodules and not check out the file?\n>> then you would not need to come up with a namespace for names\n>> of the .gitmodules files and scatter them into the worktree as well?\n>>\n>\n> Any solution which:\n>\n>   1. prevents the gitmodules file to be checked out\n>   2. but still tracks it in the git repository\n>\n> OR\n>\n>   1. allows to set the gitmoudles file under some namespace\n>\n> would work for vcsh I guess.\n\nI personally would tend to rather go for supporting your first solution\n(prevent .gitmodules from checked-out, load from sparse HEAD),\nbut I do not have strong arguments or feeling about this dimension.\nI am fine with a namespaced .gtimodules solution, too.\n\nBoth solutions can be implemented by either:\n\nA) adding the code where it is (like your patch, e.g. using\n\n> -               value=$(git config -f .gitmodules submodule.\"$name\".\"$option\")\n> +               gitmodules_file=$(git config core.submodulesfile)\n> +               : ${gitmodules_file:=.gitmodules}\n> +               value=$(git config -f \"$gitmodules_file\" submodule.\"$name\".\"$option\")\n\nB) adding a helper, which is a layer of indirection\nto load the relevant configuration.\n\nAnd when it comes to this dimension, I'd strongly favor B over A.\nHaving this indirection helper in place enables to add more options\nlater easily as only one place needs to be touched.\n(These other options could include the other solution as presented above,\nor the idea with the special ref as mentioned in an earlier email)\n\n\n>> > Can you give an example from the user point of view of such a\n>> > \"config-from-gitmodules\" command?\n>> >\n>>\n>>     git submodule config <name> <option>\n>>\n>> as an 'alias' for\n>>\n>>                gitmodules_file=$(git config core.submodulesfile)\n>>                : ${gitmodules_file:=.gitmodules}\n>>                value=$(git config -f \"$gitmodules_file\"\n>> submodule.\"$name\".\"$option\")\n>>\n>> The helper would figure out which config file to load form\n>> (.gitmodules in tree, HEAD:.gitmodules, your new proposed gitmodules file,\n>> .git/config... or the special ref) and then return the <option> for <name>\n>>\n>> So maybe:\n>>\n>>     $ git clone https://gerrit.googlesource.com/gerrit && cd gerrit\n>>     # ^ My goto-repo with submodules\n>>\n>>     $ git submodule config \"plugins/hooks\" URL\n>>     ../plugins/hooks\n>>\n>>\n>\n> I may look into such supporting changes once you decide the approach to\n> take for the bigger problem.\n\nI think once we have the helper in place you can implement the solution\nto the bigger problem as you like?\n\nThere are a few pros and cons for namespaced .gitmodules and\nnon-checked-out sparse HEAD .gitmodules:\n\nHow do you modify the .gitmodules config?\n============\nIn the namespaced solution, you can tell users to edit that\nfile manually or use \"git config -f $new_location\" to manipulate\nthat file.\n\nIn the sparse solution editing becomes a little bit trickier, as you\nneed to edit a file in the index (or HEAD).\n\nIf you have the special ref, you could just checkout the\nspecial ref in another worktree and make changes and\ncommit there\n\n\nHow do you change the setup?\n============\nIn case of a sparse gitmodules file, you can just check it out\n(make it non-sparse) or vice versa.\n\nIn case of a namespaced gitmodules file, you'd change the\nconfig setting and have to move the file to the new location.\nas git config is just about configuring, the user is left alone\nwith moving the file, or would we have a helper for that?\n(\"git submodule relocate-gitmodules\" or such)?\n\nIf you have the special ref, you could just checkout the\nspecial ref in another worktree and make changes and\ncommit there.\n\nI hope this helps instead of confusing more,\n\nThanks,\nStefan\n"},{"id":"345489","messageId":"20180423174709.GA25128@aiede.svl.corp.google.com","threadId":"48277","inReplyTo":"20180412222047.5716-1-ao2@ao2.it","subject":"Re: [RFC 00/10] Make .the gitmodules file path configurable","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2018-04-23T17:47:09Z","receivedAt":"2018-04-23T17:47:41Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nAntonio Ospite wrote:\n\n> vcsh[1] uses bare git repositories and detached work-trees to manage\n> *distinct* sets of configuration files directly into $HOME.\n\nCool!  I like the tooling you're creating for this, though keep in mind\nthat Git has some weaknesses as a tool for deployment.\n\nIn particular, keep in mind that when git updates a file, there is a\nperiod of time while it is missing from the filesystem, which can be\nproblematic for dotfiles.\n\n[...]\n> However when multiple repositories take turns using the same directory\n> as their work-tree, and more than one of them want to use submodules,\n> there could still be conflicts about the '.gitmodules' file because git\n> hardcodes this path.\n>\n> For comparison, in case of '.gitignore' a similar conflict might arise,\n> but git has alternative ways to specify exclude files, so vcsh solves\n> this by setting core.excludesFile for each repository and track ignored\n> files somewhere else (in ~/.gitignore.d/$VCSH_REPO_NAME).\n\nFor reference:\n\n\tcore.excludesFile\n\t\tSpecifies the pathname to the file that contains\n\t\tpatterns to describe paths that are not meant to be\n\t\ttracked, in addition to .gitignore (per-directory) and\n\t\t.git/info/exclude. Defaults to\n\t\t$XDG_CONFIG_HOME/git/ignore. If $XDG_CONFIG_HOME is\n\t\teither not set or empty, $HOME/.config/git/ignore is\n\t\tused instead. See gitignore(5).\n\nUsing this as a substitute for <worktree>/.gitignore is a bit of a\nhack.  It happens to work, though, so reading on. :)\n\n[...]\n> So this series proposes a mechanism to set an alternative path for the\n> submodules configuration file (from now on \"gitmodules file\").\n\nI am nervous about this.  I wonder if there is another way to\naccomplish the goal.\n\nOne possibility would be to handle the case where .gitmodules is\nexcluded by a sparse checkout specification and use .gitmodules from\nthe index in that case.  Would that work for you?\n\nThanks,\nJonathan\n"},{"id":"346144","messageId":"20180430145114.3c68c026b1e2844aaa9d4b6d@ao2.it","threadId":"48277","inReplyTo":"20180423174709.GA25128@aiede.svl.corp.google.com","subject":"Re: [RFC 00/10] Make .the gitmodules file path configurable","fromName":"Antonio Ospite","fromEmail":"ao2@ao2.it","sentAt":"2018-04-30T12:51:14Z","receivedAt":"2018-04-30T12:51:47Z","isPatch":false,"sender":{"key":"ao2@ao2.it","avatar":"https://avatars.githubusercontent.com/u/1249395?v=4"},"body":"On Mon, 23 Apr 2018 10:47:09 -0700\nJonathan Nieder <jrnieder@gmail.com> wrote:\n\n> Hi,\n>\n\nHi Jonathan, thank you for your comment.\n\n> Antonio Ospite wrote:\n> \n> > vcsh[1] uses bare git repositories and detached work-trees to manage\n> > *distinct* sets of configuration files directly into $HOME.\n> \n> Cool!  I like the tooling you're creating for this, though keep in mind\n> that Git has some weaknesses as a tool for deployment.\n>\n\nI am not the author BTW, just a user trying to address the remaining\ncorner cases.\n\n> In particular, keep in mind that when git updates a file, there is a\n> period of time while it is missing from the filesystem, which can be\n> problematic for dotfiles.\n>\n\nThanks for the reminder, it may be worth mentioning this in vcsh\ndocumentation, however I don't have knowledge of users experiencing\nproblems related to that.\n\n> [...]\n> > However when multiple repositories take turns using the same directory\n> > as their work-tree, and more than one of them want to use submodules,\n> > there could still be conflicts about the '.gitmodules' file because git\n> > hardcodes this path.\n> >\n> > For comparison, in case of '.gitignore' a similar conflict might arise,\n> > but git has alternative ways to specify exclude files, so vcsh solves\n> > this by setting core.excludesFile for each repository and track ignored\n> > files somewhere else (in ~/.gitignore.d/$VCSH_REPO_NAME).\n> \n> For reference:\n> \n> \tcore.excludesFile\n> \t\tSpecifies the pathname to the file that contains\n> \t\tpatterns to describe paths that are not meant to be\n> \t\ttracked, in addition to .gitignore (per-directory) and\n> \t\t.git/info/exclude. Defaults to\n> \t\t$XDG_CONFIG_HOME/git/ignore. If $XDG_CONFIG_HOME is\n> \t\teither not set or empty, $HOME/.config/git/ignore is\n> \t\tused instead. See gitignore(5).\n> \n> Using this as a substitute for <worktree>/.gitignore is a bit of a\n> hack.  It happens to work, though, so reading on. :)\n> \n> [...]\n> > So this series proposes a mechanism to set an alternative path for the\n> > submodules configuration file (from now on \"gitmodules file\").\n> \n> I am nervous about this.  I wonder if there is another way to\n> accomplish the goal.\n>\n> One possibility would be to handle the case where .gitmodules is\n> excluded by a sparse checkout specification and use .gitmodules from\n> the index in that case.  Would that work for you?\n> \n\nSince part of the problem is that .gitmodules *collide* between\nrepositories, a sparse-checkout approach make sense indeed.\n\nAs discussed[1] with Stefan Beller having git use .gitmodules from the\nindex without the need to have it checked out should work for us.\n\n[1] https://www.spinics.net/lists/git/msg329153.html\n\nIdeally git should also be able to write to that file when it's not\nchecked out (e.g. when running \"git submodule add\"), to save the\nuser from tedious sparse/unsparse rounds when operating with submodules.\n\nAs suggested by Stefan I'll first try to remove the hardcoded references\nto .gitmodules in git-submodule.sh adding a helper sub-command to\naccess .gitmodules in a more robust way, and after that git could\nbe taught to use the file from the index, but this second part\nis currently beyond my current git knowledge.\n\nIf this mechanism of using unchecked-out files from the index could be\nextended to .gitignore (and .gitattributes), then vcsh might even stop\nabusing core.excludesFile; sparse checkouts seem the more natural git\nway to deal with colliding files in a shared-workdir scenario.\n\nHowever, having users *write* to .gitignore and .gitattributes while\nthey are not checked out still sounds quite problematic to me, but maybe\nthis could be handled by vcsh itself, similarly to what is done for the\nfile pointed by core.excludesFile.\n\nCiao,\n   Antonio\n\n-- \nAntonio Ospite\nhttps://ao2.it\nhttps://twitter.com/ao2it\n\nA: Because it messes up the order in which people normally read text.\n   See http://en.wikipedia.org/wiki/Posting_style\nQ: Why is top-posting such a bad thing?\n"}]}