Skip to content

Commit be254a0

Browse files
jlehmanngitster
authored andcommitted
Add the 'fetch.recurseSubmodules' config setting
This new boolean option can be used to override the default for "git fetch" and "git pull", which is to not recurse into populated submodules and fetch all new commits there too. Signed-off-by: Jens Lehmann <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7dce19d commit be254a0

File tree

7 files changed

+83
-9
lines changed

7 files changed

+83
-9
lines changed

Documentation/config.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,11 @@ diff.wordRegex::
862862
sequences that match the regular expression are "words", all other
863863
characters are *ignorable* whitespace.
864864

865+
fetch.recurseSubmodules::
866+
A boolean value which changes the behavior for fetch and pull, the
867+
default is to not recursively fetch populated sumodules unless
868+
configured otherwise.
869+
865870
fetch.unpackLimit::
866871
If the number of objects fetched over the git native
867872
transfer is below this

Documentation/fetch-options.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ endif::git-pull[]
6060
flag lets all tags and their associated objects be
6161
downloaded.
6262

63-
--recurse-submodules::
64-
Use this option to fetch new commits of all populated submodules too.
63+
--[no-]recurse-submodules::
64+
This option controls if new commits of all populated submodules should
65+
be fetched too (see linkgit:git-config[1]).
6566

6667
ifndef::git-pull[]
6768
--submodule-prefix=<path>::

builtin/fetch.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,14 @@ enum {
2828
TAGS_SET = 2
2929
};
3030

31+
enum {
32+
RECURSE_SUBMODULES_OFF = 0,
33+
RECURSE_SUBMODULES_DEFAULT = 1,
34+
RECURSE_SUBMODULES_ON = 2
35+
};
36+
3137
static int all, append, dry_run, force, keep, multiple, prune, update_head_ok, verbosity;
32-
static int progress, recurse_submodules;
38+
static int progress, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
3339
static int tags = TAGS_DEFAULT;
3440
static const char *depth;
3541
static const char *upload_pack;
@@ -55,8 +61,9 @@ static struct option builtin_fetch_options[] = {
5561
"do not fetch all tags (--no-tags)", TAGS_UNSET),
5662
OPT_BOOLEAN('p', "prune", &prune,
5763
"prune tracking branches no longer on remote"),
58-
OPT_BOOLEAN(0, "recurse-submodules", &recurse_submodules,
59-
"control recursive fetching of submodules"),
64+
OPT_SET_INT(0, "recurse-submodules", &recurse_submodules,
65+
"control recursive fetching of submodules",
66+
RECURSE_SUBMODULES_ON),
6067
OPT_BOOLEAN(0, "dry-run", &dry_run,
6168
"dry run"),
6269
OPT_BOOLEAN('k', "keep", &keep, "keep downloaded pack"),
@@ -795,7 +802,7 @@ static void add_options_to_argv(int *argc, const char **argv)
795802
argv[(*argc)++] = "--force";
796803
if (keep)
797804
argv[(*argc)++] = "--keep";
798-
if (recurse_submodules)
805+
if (recurse_submodules == RECURSE_SUBMODULES_ON)
799806
argv[(*argc)++] = "--recurse-submodules";
800807
if (verbosity >= 2)
801808
argv[(*argc)++] = "-v";
@@ -933,14 +940,18 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
933940
}
934941
}
935942

936-
if (!result && recurse_submodules) {
943+
if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF)) {
937944
const char *options[10];
938945
int num_options = 0;
946+
/* Set recursion as default when we already are recursing */
947+
if (submodule_prefix[0])
948+
set_config_fetch_recurse_submodules(1);
939949
gitmodules_config();
940950
git_config(submodule_config, NULL);
941951
add_options_to_argv(&num_options, options);
942952
result = fetch_populated_submodules(num_options, options,
943953
submodule_prefix,
954+
recurse_submodules == RECURSE_SUBMODULES_ON,
944955
verbosity < 0);
945956
}
946957

git-pull.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ do
108108
--recurse-submodules)
109109
recurse_submodules=--recurse-submodules
110110
;;
111+
--no-recurse-submodules)
112+
recurse_submodules=--no-recurse-submodules
113+
;;
111114
--d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run)
112115
dry_run=--dry-run
113116
;;

submodule.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
struct string_list config_name_for_path;
1313
struct string_list config_ignore_for_name;
14+
static int config_fetch_recurse_submodules;
1415

1516
static int add_submodule_odb(const char *path)
1617
{
@@ -67,6 +68,10 @@ int submodule_config(const char *var, const char *value, void *cb)
6768
{
6869
if (!prefixcmp(var, "submodule."))
6970
return parse_submodule_config_option(var, value);
71+
else if (!strcmp(var, "fetch.recursesubmodules")) {
72+
config_fetch_recurse_submodules = git_config_bool(var, value);
73+
return 0;
74+
}
7075
return 0;
7176
}
7277

@@ -229,8 +234,14 @@ void show_submodule_summary(FILE *f, const char *path,
229234
strbuf_release(&sb);
230235
}
231236

237+
void set_config_fetch_recurse_submodules(int value)
238+
{
239+
config_fetch_recurse_submodules = value;
240+
}
241+
232242
int fetch_populated_submodules(int num_options, const char **options,
233-
const char *prefix, int quiet)
243+
const char *prefix, int ignore_config,
244+
int quiet)
234245
{
235246
int i, result = 0, argc = 0;
236247
struct child_process cp;
@@ -271,6 +282,11 @@ int fetch_populated_submodules(int num_options, const char **options,
271282
if (name_for_path)
272283
name = name_for_path->util;
273284

285+
if (!ignore_config) {
286+
if (!config_fetch_recurse_submodules)
287+
continue;
288+
}
289+
274290
strbuf_addf(&submodule_path, "%s/%s", work_tree, ce->name);
275291
strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf);
276292
strbuf_addf(&submodule_prefix, "%s%s/", prefix, ce->name);

submodule.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ void show_submodule_summary(FILE *f, const char *path,
1313
unsigned char one[20], unsigned char two[20],
1414
unsigned dirty_submodule,
1515
const char *del, const char *add, const char *reset);
16+
void set_config_fetch_recurse_submodules(int value);
1617
int fetch_populated_submodules(int num_options, const char **options,
17-
const char *prefix, int quiet);
18+
const char *prefix, int ignore_config,
19+
int quiet);
1820
unsigned is_submodule_modified(const char *path, int ignore_untracked);
1921
int merge_submodule(unsigned char result[20], const char *path, const unsigned char base[20],
2022
const unsigned char a[20], const unsigned char b[20]);

t/t5526-fetch-submodules.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,40 @@ test_expect_success "--dry-run propagates to submodules" '
106106
test_cmp expect.err actual.err
107107
'
108108

109+
test_expect_success "recurseSubmodules=true propagates into submodules" '
110+
add_upstream_commit &&
111+
(
112+
cd downstream &&
113+
git config fetch.recurseSubmodules true
114+
git fetch >../actual.out 2>../actual.err
115+
) &&
116+
test_cmp expect.out actual.out &&
117+
test_cmp expect.err actual.err
118+
'
119+
120+
test_expect_success "--recurse-submodules overrides config in submodule" '
121+
add_upstream_commit &&
122+
(
123+
cd downstream &&
124+
(
125+
cd submodule &&
126+
git config fetch.recurseSubmodules false
127+
) &&
128+
git fetch --recurse-submodules >../actual.out 2>../actual.err
129+
) &&
130+
test_cmp expect.out actual.out &&
131+
test_cmp expect.err actual.err
132+
'
133+
134+
test_expect_success "--no-recurse-submodules overrides config setting" '
135+
add_upstream_commit &&
136+
(
137+
cd downstream &&
138+
git config fetch.recurseSubmodules true
139+
git fetch --no-recurse-submodules >../actual.out 2>../actual.err
140+
) &&
141+
! test -s actual.out &&
142+
! test -s actual.err
143+
'
144+
109145
test_done

0 commit comments

Comments
 (0)