Skip to content

Commit c1a3c36

Browse files
jlehmanngitster
authored andcommitted
Submodules: Add the "fetchRecurseSubmodules" config option
The new boolean "fetchRecurseSubmodules" config option controls the behavior for "git fetch" and "git pull". It specifies if these commands should recurse into submodules and fetch new commits there too and can be set separately for each submodule. In the .gitmodules file "submodule.<name>.fetchRecurseSubmodules" entries are read before looking for them in .git/config. Thus settings found in .git/config will override those from .gitmodules, thereby allowing the user to ignore settings given by the remote side while also letting upstream set reasonable defaults for those users who don't have special needs. This configuration can be overridden by the command line option "--[no-]recurse-submodules" of "git fetch" and "git pull". Signed-off-by: Jens Lehmann <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent be254a0 commit c1a3c36

File tree

5 files changed

+84
-3
lines changed

5 files changed

+84
-3
lines changed

Documentation/config.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,6 +1768,13 @@ submodule.<name>.update::
17681768
URL and other values found in the `.gitmodules` file. See
17691769
linkgit:git-submodule[1] and linkgit:gitmodules[5] for details.
17701770

1771+
submodule.<name>.fetchRecurseSubmodules::
1772+
This option can be used to enable/disable recursive fetching of this
1773+
submodule. It can be overriden by using the --[no-]recurse-submodules
1774+
command line option to "git fetch" and "git pull".
1775+
This setting will override that from in the linkgit:gitmodules[5]
1776+
file.
1777+
17711778
submodule.<name>.ignore::
17721779
Defines under what circumstances "git status" and the diff family show
17731780
a submodule as modified. When set to "all", it will never be considered

Documentation/fetch-options.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ endif::git-pull[]
6262

6363
--[no-]recurse-submodules::
6464
This option controls if new commits of all populated submodules should
65-
be fetched too (see linkgit:git-config[1]).
65+
be fetched too (see linkgit:git-config[1] and linkgit:gitmodules[5]).
6666

6767
ifndef::git-pull[]
6868
--submodule-prefix=<path>::

Documentation/gitmodules.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ submodule.<name>.update::
4444
This config option is overridden if 'git submodule update' is given
4545
the '--merge' or '--rebase' options.
4646

47+
submodule.<name>.fetchRecurseSubmodules::
48+
This option can be used to enable/disable recursive fetching of this
49+
submodule. If this option is also present in the submodules entry in
50+
.git/config of the superproject, the setting there will override the
51+
one found in .gitmodules.
52+
Both settings can be overriden on the command line by using the
53+
"--[no-]recurse-submodules" option to "git fetch" and "git pull"..
54+
4755
submodule.<name>.ignore::
4856
Defines under what circumstances "git status" and the diff family show
4957
a submodule as modified. When set to "all", it will never be considered

submodule.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "string-list.h"
1111

1212
struct string_list config_name_for_path;
13+
struct string_list config_fetch_recurse_submodules_for_name;
1314
struct string_list config_ignore_for_name;
1415
static int config_fetch_recurse_submodules;
1516

@@ -105,6 +106,14 @@ int parse_submodule_config_option(const char *var, const char *value)
105106
config = string_list_append(&config_name_for_path, xstrdup(value));
106107
config->util = strbuf_detach(&submodname, NULL);
107108
strbuf_release(&submodname);
109+
} else if ((len > 23) && !strcmp(var + len - 23, ".fetchrecursesubmodules")) {
110+
strbuf_add(&submodname, var, len - 23);
111+
config = unsorted_string_list_lookup(&config_fetch_recurse_submodules_for_name, submodname.buf);
112+
if (!config)
113+
config = string_list_append(&config_fetch_recurse_submodules_for_name,
114+
strbuf_detach(&submodname, NULL));
115+
config->util = git_config_bool(var, value) ? (void *)1 : NULL;
116+
strbuf_release(&submodname);
108117
} else if ((len > 7) && !strcmp(var + len - 7, ".ignore")) {
109118
if (strcmp(value, "untracked") && strcmp(value, "dirty") &&
110119
strcmp(value, "all") && strcmp(value, "none")) {
@@ -283,8 +292,15 @@ int fetch_populated_submodules(int num_options, const char **options,
283292
name = name_for_path->util;
284293

285294
if (!ignore_config) {
286-
if (!config_fetch_recurse_submodules)
287-
continue;
295+
struct string_list_item *fetch_recurse_submodules_option;
296+
fetch_recurse_submodules_option = unsorted_string_list_lookup(&config_fetch_recurse_submodules_for_name, name);
297+
if (fetch_recurse_submodules_option) {
298+
if (!fetch_recurse_submodules_option->util)
299+
continue;
300+
} else {
301+
if (!config_fetch_recurse_submodules)
302+
continue;
303+
}
288304
}
289305

290306
strbuf_addf(&submodule_path, "%s/%s", work_tree, ce->name);

t/t5526-fetch-submodules.sh

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,56 @@ test_expect_success "fetch alone only fetches superproject" '
8181
! test -s actual.err
8282
'
8383

84+
test_expect_success "fetch --no-recurse-submodules only fetches superproject" '
85+
(
86+
cd downstream &&
87+
git fetch --no-recurse-submodules >../actual.out 2>../actual.err
88+
) &&
89+
! test -s actual.out &&
90+
! test -s actual.err
91+
'
92+
93+
test_expect_success "using fetchRecurseSubmodules=true in .gitmodules recurses into submodules" '
94+
(
95+
cd downstream &&
96+
git config -f .gitmodules submodule.submodule.fetchRecurseSubmodules true &&
97+
git fetch >../actual.out 2>../actual.err
98+
) &&
99+
test_cmp expect.out actual.out &&
100+
test_cmp expect.err actual.err
101+
'
102+
103+
test_expect_success "--no-recurse-submodules overrides .gitmodules config" '
104+
add_upstream_commit &&
105+
(
106+
cd downstream &&
107+
git fetch --no-recurse-submodules >../actual.out 2>../actual.err
108+
) &&
109+
! test -s actual.out &&
110+
! test -s actual.err
111+
'
112+
113+
test_expect_success "using fetchRecurseSubmodules=false in .git/config overrides setting in .gitmodules" '
114+
(
115+
cd downstream &&
116+
git config submodule.submodule.fetchRecurseSubmodules false &&
117+
git fetch >../actual.out 2>../actual.err
118+
) &&
119+
! test -s actual.out &&
120+
! test -s actual.err
121+
'
122+
123+
test_expect_success "--recurse-submodules overrides fetchRecurseSubmodules setting from .git/config" '
124+
(
125+
cd downstream &&
126+
git fetch --recurse-submodules >../actual.out 2>../actual.err &&
127+
git config -f --unset .gitmodules submodule.submodule.fetchRecurseSubmodules true &&
128+
git config --unset submodule.submodule.fetchRecurseSubmodules
129+
) &&
130+
test_cmp expect.out actual.out &&
131+
test_cmp expect.err actual.err
132+
'
133+
84134
test_expect_success "--quiet propagates to submodules" '
85135
(
86136
cd downstream &&

0 commit comments

Comments
 (0)