path: root/builtin/pull.c
diff options
authorGlen Choo <>2022-05-10 19:25:47 (GMT)
committerJunio C Hamano <>2022-05-11 22:42:30 (GMT)
commit58194173652786709ba9dd1f56df6922a92f419f (patch)
treee87709b05e4fe05a7caed99e09ca2c01a9b5e71a /builtin/pull.c
parent17083c79ae842b51d82518e2efe5281346acea0e (diff)
pull: do not let submodule.recurse override fetch.recurseSubmodules
Fix a bug in "git pull" where `submodule.recurse` is preferred over `fetch.recurseSubmodules` when performing a fetch (Documentation/config/fetch.txt says that `fetch.recurseSubmodules` should be preferred.). Do this by passing the value of the "--recurse-submodules" CLI option to the underlying fetch, instead of passing a value that combines the CLI option and config variables. In other words, this bug occurred because builtin/pull.c is conflating two similar-sounding, but different concepts: - Whether "git pull" itself should care about submodules e.g. whether it should update the submodule worktrees after performing a merge. - The value of "--recurse-submodules" to pass to the underlying "git fetch". Thus, when `submodule.recurse` is set, the underlying "git fetch" gets invoked with "--recurse-submodules[=value]", overriding the value of `fetch.recurseSubmodules`. An alternative (and more obvious) approach to fix the bug would be to teach "git pull" to understand `fetch.recurseSubmodules`, but the proposed solution works better because: - We don't maintain two identical config-parsing implementions in "git pull" and "git fetch". - It works better with other commands invoked by "git pull" e.g. "git merge" won't accidentally respect `fetch.recurseSubmodules`. Reported-by: Huang Zou <> Helped-by: Philippe Blain <> Signed-off-by: Glen Choo <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'builtin/pull.c')
1 files changed, 7 insertions, 3 deletions
diff --git a/builtin/pull.c b/builtin/pull.c
index aa56ebc..de266db 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -72,6 +72,7 @@ static const char * const pull_usage[] = {
static int opt_verbosity;
static char *opt_progress;
static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
+static int recurse_submodules_cli = RECURSE_SUBMODULES_DEFAULT;
/* Options passed to git-merge or git-rebase */
static enum rebase_type opt_rebase = -1;
@@ -119,7 +120,7 @@ static struct option pull_options[] = {
N_("force progress reporting"),
OPT_CALLBACK_F(0, "recurse-submodules",
- &recurse_submodules, N_("on-demand"),
+ &recurse_submodules_cli, N_("on-demand"),
N_("control for recursive fetching of submodules"),
PARSE_OPT_OPTARG, option_fetch_parse_recurse_submodules),
@@ -545,8 +546,8 @@ static int run_fetch(const char *repo, const char **refspecs)
strvec_push(&args, opt_tags);
if (opt_prune)
strvec_push(&args, opt_prune);
- if (recurse_submodules != RECURSE_SUBMODULES_DEFAULT)
- switch (recurse_submodules) {
+ if (recurse_submodules_cli != RECURSE_SUBMODULES_DEFAULT)
+ switch (recurse_submodules_cli) {
strvec_push(&args, "--recurse-submodules=on");
@@ -939,6 +940,9 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);
+ if (recurse_submodules_cli != RECURSE_SUBMODULES_DEFAULT)
+ recurse_submodules = recurse_submodules_cli;
if (cleanup_arg)
* this only checks the validity of cleanup_arg; we don't need