{"thread":{"id":"49399","subject":"[PATCH] fetch: Ensure that fetch.recurseSubmodules overrides submodule.recurse.","startedAt":"2018-09-21T19:00:36Z","lastAt":"2018-09-21T19:23:10Z","messageCount":2,"participants":["Marc Branchaud","Stefan Beller"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"358640","messageId":"20180921185149.8670-1-marcnarc@xiplink.com","threadId":"49399","inReplyTo":null,"subject":"[PATCH] fetch: Ensure that fetch.recurseSubmodules overrides submodule.recurse.","fromName":"Marc Branchaud","fromEmail":"marcnarc@xiplink.com","sentAt":"2018-09-21T18:51:49Z","receivedAt":"2018-09-21T19:00:36Z","isPatch":true,"sender":{"key":"marcnarc@xiplink.com","avatar":"https://avatars.githubusercontent.com/u/14980203?v=4"},"body":"Also document this fact.\n\nSigned-off-by: Marc Branchaud <marcnarc@xiplink.com>\n---\n\nI ran into this bug when I had both fetch.recurseSubmodules=on-demand and\nsubmodule.recurse=true, and submodule.recurse was set *after*\nfetch.recurseSubmodules in my config.\n\nThe fix ensures that fetch.recurseSubmodules always overrides\nsubmodule.recurse.  If neither is set then fetch still behaves as if\nfetch.recurseSubmodules=on-demand (the documented default).\n\nI'm not sure if this is the most elegant implementation, but it gets the job\ndone.\n\n\t\tM.\n\n\n Documentation/config.txt | 6 ++++--\n builtin/fetch.c          | 5 ++++-\n 2 files changed, 8 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex eb66a11975..67b0adc1d4 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1514,7 +1514,8 @@ fetch.recurseSubmodules::\n \trecurse at all when set to false. When set to 'on-demand' (the default\n \tvalue), fetch and pull will only recurse into a populated submodule\n \twhen its superproject retrieves a commit that updates the submodule's\n-\treference.\n+\treference.  This option overrides the more general submodule.recurse\n+\toption, for the `fetch` command.\n \n fetch.fsckObjects::\n \tIf it is set to true, git-fetch-pack will check all fetched\n@@ -3465,7 +3466,8 @@ submodule.active::\n submodule.recurse::\n \tSpecifies if commands recurse into submodules by default. This\n \tapplies to all commands that have a `--recurse-submodules` option,\n-\texcept `clone`.\n+\texcept `clone`.  Also, the `fetch` command's behaviour can be specified\n+\tindependently with the fetch.recurseSubmodules option.\n \tDefaults to false.\n \n submodule.fetchJobs::\ndiff --git a/builtin/fetch.c b/builtin/fetch.c\nindex 61bec5d213..08b8bf2741 100644\n--- a/builtin/fetch.c\n+++ b/builtin/fetch.c\n@@ -60,6 +60,7 @@ static struct transport *gsecondary;\n static const char *submodule_prefix = \"\";\n static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;\n static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;\n+static int recurse_submodules_set_explicitly = 0;\n static int shown_url = 0;\n static struct refspec refmap = REFSPEC_INIT_FETCH;\n static struct list_objects_filter_options filter_options;\n@@ -78,7 +79,8 @@ static int git_fetch_config(const char *k, const char *v, void *cb)\n \t\treturn 0;\n \t}\n \n-\tif (!strcmp(k, \"submodule.recurse\")) {\n+\tif (!strcmp(k, \"submodule.recurse\") &&\n+\t    !recurse_submodules_set_explicitly) {\n \t\tint r = git_config_bool(k, v) ?\n \t\t\tRECURSE_SUBMODULES_ON : RECURSE_SUBMODULES_OFF;\n \t\trecurse_submodules = r;\n@@ -88,6 +90,7 @@ static int git_fetch_config(const char *k, const char *v, void *cb)\n \t\tmax_children = parse_submodule_fetchjobs(k, v);\n \t\treturn 0;\n \t} else if (!strcmp(k, \"fetch.recursesubmodules\")) {\n+\t\trecurse_submodules_set_explicitly = 1;\n \t\trecurse_submodules = parse_fetch_recurse_submodules_arg(k, v);\n \t\treturn 0;\n \t}\n-- \n2.19.0.1.g5109f9487a\n\n"},{"id":"358641","messageId":"CAGZ79kabCTD9uvw+GPXxJGf8BfiqvMkhkA4Up8gC_kXjdv-o8g@mail.gmail.com","threadId":"49399","inReplyTo":"20180921185149.8670-1-marcnarc@xiplink.com","subject":"Re: [PATCH] fetch: Ensure that fetch.recurseSubmodules overrides submodule.recurse.","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-09-21T19:22:55Z","receivedAt":"2018-09-21T19:23:10Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Fri, Sep 21, 2018 at 12:00 PM Marc Branchaud <marcnarc@xiplink.com> wrote:\n>\n> Also document this fact.\n>\n> Signed-off-by: Marc Branchaud <marcnarc@xiplink.com>\n> ---\n>\n> I ran into this bug when I had both fetch.recurseSubmodules=on-demand and\n> submodule.recurse=true, and submodule.recurse was set *after*\n> fetch.recurseSubmodules in my config.\n>\n> The fix ensures that fetch.recurseSubmodules always overrides\n> submodule.recurse.  If neither is set then fetch still behaves as if\n> fetch.recurseSubmodules=on-demand (the documented default).\n\nAt least the second paragraph is valuable information in the commit\nmessage, so maybe add it there? I am not sure if the first paragraph is\na good part for the commit message, but maybe helps for writing a test?\n\n> +       reference.  This option overrides the more general submodule.recurse\n> +       option, for the `fetch` command.\n>\n>  fetch.fsckObjects::\n>         If it is set to true, git-fetch-pack will check all fetched\n> @@ -3465,7 +3466,8 @@ submodule.active::\n>  submodule.recurse::\n>         Specifies if commands recurse into submodules by default. This\n>         applies to all commands that have a `--recurse-submodules` option,\n> -       except `clone`.\n> +       except `clone`.  Also, the `fetch` command's behaviour can be specified\n> +       independently with the fetch.recurseSubmodules option.\n\nThere is also push.recurseSubmodules, which should behave similarly?\n\nThe series that introduced submodule.recurse ends with 58f4203e7db\n(builtin/fetch.c: respect 'submodule.recurse' option, 2017-05-31)\n(sb/submodule-blanket-recursive)\nseems to have overlooked this only for fetch/push, as the other\ncommands (checkout, read-tree, reset, grep) do not have their\nown specific setting to recurse.\n\n\n> @@ -88,6 +90,7 @@ static int git_fetch_config(const char *k, const char *v, void *cb)\n>                 max_children = parse_submodule_fetchjobs(k, v);\n>                 return 0;\n>         } else if (!strcmp(k, \"fetch.recursesubmodules\")) {\n> +               recurse_submodules_set_explicitly = 1;\n\nthe command line option also overried explicitely, but that\nis ensured via the program flow (parse_config happens after\ngit_config to overlay options, which itself was pre-seeded\nwith fetch_config_from_gitmodules).\n\nI briefly wondered if this overlaying approach would be better\n(i.e. first do git_config with more generic option, and then\nagain with the more detailed option) as it would save one\nglobal variable, but the downsides are terrible (way more\nwork to do, more code and such), so I think having a global\nmakes sense and gets the job done.\n\nIdeally instead of a global we'd have this flag stored in\nthe repository struct, as eventually in the long run,\nfetch_populated_submodules could happen in-process\ninstead of spawning fetch processes for each submodule\n(and their nested submodules which may be configured\ndifferently). But for now the global will do.\n\nThanks!\nStefan\n"}]}