Skip to content

Commit 2071fb0

Browse files
committed
Merge branch 'jl/submodule-fetch-on-demand'
* jl/submodule-fetch-on-demand: fetch/pull: Describe --recurse-submodule restrictions in the BUGS section submodule update: Don't fetch when the submodule commit is already present fetch/pull: Don't recurse into a submodule when commits are already present Submodules: Add 'on-demand' value for the 'fetchRecurseSubmodule' option config: teach the fetch.recurseSubmodules option the 'on-demand' value fetch/pull: Add the 'on-demand' value to the --recurse-submodules option fetch/pull: recurse into submodules when necessary Conflicts: builtin/fetch.c submodule.c
2 parents 2c320e7 + 794a359 commit 2071fb0

13 files changed

+520
-37
lines changed

Documentation/config.txt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -897,9 +897,13 @@ diff.wordRegex::
897897
characters are *ignorable* whitespace.
898898

899899
fetch.recurseSubmodules::
900-
A boolean value which changes the behavior for fetch and pull, the
901-
default is to not recursively fetch populated submodules unless
902-
configured otherwise.
900+
This option can be either set to a boolean value or to 'on-demand'.
901+
Setting it to a boolean changes the behavior of fetch and pull to
902+
unconditionally recurse into submodules when set to true or to not
903+
recurse at all when set to false. When set to 'on-demand' (the default
904+
value), fetch and pull will only recurse into a populated submodule
905+
when its superproject retrieves a commit that updates the submodule's
906+
reference.
903907

904908
fetch.unpackLimit::
905909
If the number of objects fetched over the git native
@@ -1823,7 +1827,7 @@ submodule.<name>.update::
18231827
linkgit:git-submodule[1] and linkgit:gitmodules[5] for details.
18241828

18251829
submodule.<name>.fetchRecurseSubmodules::
1826-
This option can be used to enable/disable recursive fetching of this
1830+
This option can be used to control recursive fetching of this
18271831
submodule. It can be overridden by using the --[no-]recurse-submodules
18281832
command line option to "git fetch" and "git pull".
18291833
This setting will override that from in the linkgit:gitmodules[5]

Documentation/fetch-options.txt

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,33 @@ ifndef::git-pull[]
6565
specified with the remote.<name>.tagopt setting. See
6666
linkgit:git-config[1].
6767

68-
--[no-]recurse-submodules::
69-
This option controls if new commits of all populated submodules should
70-
be fetched too (see linkgit:git-config[1] and linkgit:gitmodules[5]).
68+
--recurse-submodules[=yes|on-demand|no]::
69+
This option controls if and under what conditions new commits of
70+
populated submodules should be fetched too. It can be used as a
71+
boolean option to completely disable recursion when set to 'no' or to
72+
unconditionally recurse into all populated submodules when set to
73+
'yes', which is the default when this option is used without any
74+
value. Use 'on-demand' to only recurse into a populated submodule
75+
when the superproject retrieves a commit that updates the submodule's
76+
reference to a commit that isn't already in the local submodule
77+
clone.
78+
79+
--no-recurse-submodules::
80+
Disable recursive fetching of submodules (this has the same effect as
81+
using the '--recurse-submodules=no' option).
7182

7283
--submodule-prefix=<path>::
7384
Prepend <path> to paths printed in informative messages
7485
such as "Fetching submodule foo". This option is used
7586
internally when recursing over submodules.
87+
88+
--recurse-submodules-default=[yes|on-demand]::
89+
This option is used internally to temporarily provide a
90+
non-negative default value for the --recurse-submodules
91+
option. All other methods of configuring fetch's submodule
92+
recursion (such as settings in linkgit:gitmodules[5] and
93+
linkgit:git-config[1]) override this option, as does
94+
specifying --[no-]recurse-submodules directly.
7695
endif::git-pull[]
7796

7897
-u::

Documentation/git-fetch.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,15 @@ The `pu` branch will be updated even if it is does not fast-forward,
7676
because it is prefixed with a plus sign; `tmp` will not be.
7777

7878

79+
BUGS
80+
----
81+
Using --recurse-submodules can only fetch new commits in already checked
82+
out submodules right now. When e.g. upstream added a new submodule in the
83+
just fetched commits of the superproject the submodule itself can not be
84+
fetched, making it impossible to check out that submodule later without
85+
having to do a fetch again. This is expected to be fixed in a future git
86+
version.
87+
7988
SEE ALSO
8089
--------
8190
linkgit:git-pull[1]

Documentation/git-pull.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ must be given before the options meant for 'git fetch'.
8484
--verbose::
8585
Pass --verbose to git-fetch and git-merge.
8686

87-
--[no-]recurse-submodules::
87+
--[no-]recurse-submodules[=yes|on-demand|no]::
8888
This option controls if new commits of all populated submodules should
8989
be fetched too (see linkgit:git-config[1] and linkgit:gitmodules[5]).
9090
That might be necessary to get the data needed for merging submodule
@@ -220,6 +220,15 @@ If you tried a pull which resulted in a complex conflicts and
220220
would want to start over, you can recover with 'git reset'.
221221

222222

223+
BUGS
224+
----
225+
Using --recurse-submodules can only fetch new commits in already checked
226+
out submodules right now. When e.g. upstream added a new submodule in the
227+
just fetched commits of the superproject the submodule itself can not be
228+
fetched, making it impossible to check out that submodule later without
229+
having to do a fetch again. This is expected to be fixed in a future git
230+
version.
231+
223232
SEE ALSO
224233
--------
225234
linkgit:git-fetch[1], linkgit:git-merge[1], linkgit:git-config[1]

Documentation/gitmodules.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ submodule.<name>.update::
4545
the '--merge' or '--rebase' options.
4646

4747
submodule.<name>.fetchRecurseSubmodules::
48-
This option can be used to enable/disable recursive fetching of this
48+
This option can be used to control recursive fetching of this
4949
submodule. If this option is also present in the submodules entry in
5050
.git/config of the superproject, the setting there will override the
5151
one found in .gitmodules.
5252
Both settings can be overridden on the command line by using the
53-
"--[no-]recurse-submodules" option to "git fetch" and "git pull"..
53+
"--[no-]recurse-submodules" option to "git fetch" and "git pull".
5454

5555
submodule.<name>.ignore::
5656
Defines under what circumstances "git status" and the diff family show

builtin/fetch.c

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,6 @@ 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-
3731
static int all, append, dry_run, force, keep, multiple, prune, update_head_ok, verbosity;
3832
static int progress, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
3933
static int tags = TAGS_DEFAULT;
@@ -42,6 +36,21 @@ static const char *upload_pack;
4236
static struct strbuf default_rla = STRBUF_INIT;
4337
static struct transport *transport;
4438
static const char *submodule_prefix = "";
39+
static const char *recurse_submodules_default;
40+
41+
static int option_parse_recurse_submodules(const struct option *opt,
42+
const char *arg, int unset)
43+
{
44+
if (unset) {
45+
recurse_submodules = RECURSE_SUBMODULES_OFF;
46+
} else {
47+
if (arg)
48+
recurse_submodules = parse_fetch_recurse_submodules_arg(opt->long_name, arg);
49+
else
50+
recurse_submodules = RECURSE_SUBMODULES_ON;
51+
}
52+
return 0;
53+
}
4554

4655
static struct option builtin_fetch_options[] = {
4756
OPT__VERBOSITY(&verbosity),
@@ -60,9 +69,9 @@ static struct option builtin_fetch_options[] = {
6069
"do not fetch all tags (--no-tags)", TAGS_UNSET),
6170
OPT_BOOLEAN('p', "prune", &prune,
6271
"prune remote-tracking branches no longer on remote"),
63-
OPT_SET_INT(0, "recurse-submodules", &recurse_submodules,
72+
{ OPTION_CALLBACK, 0, "recurse-submodules", NULL, "on-demand",
6473
"control recursive fetching of submodules",
65-
RECURSE_SUBMODULES_ON),
74+
PARSE_OPT_OPTARG, option_parse_recurse_submodules },
6675
OPT_BOOLEAN(0, "dry-run", &dry_run,
6776
"dry run"),
6877
OPT_BOOLEAN('k', "keep", &keep, "keep downloaded pack"),
@@ -73,6 +82,9 @@ static struct option builtin_fetch_options[] = {
7382
"deepen history of shallow clone"),
7483
{ OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, "dir",
7584
"prepend this to submodule path output", PARSE_OPT_HIDDEN },
85+
{ OPTION_STRING, 0, "recurse-submodules-default",
86+
&recurse_submodules_default, NULL,
87+
"default mode for recursion", PARSE_OPT_HIDDEN },
7688
OPT_END()
7789
};
7890

@@ -284,6 +296,9 @@ static int update_local_ref(struct ref *ref,
284296
else {
285297
msg = "storing head";
286298
what = _("[new branch]");
299+
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
300+
(recurse_submodules != RECURSE_SUBMODULES_ON))
301+
check_for_new_submodule_commits(ref->new_sha1);
287302
}
288303

289304
r = s_update_ref(msg, ref, 0);
@@ -299,6 +314,9 @@ static int update_local_ref(struct ref *ref,
299314
strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
300315
strcat(quickref, "..");
301316
strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
317+
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
318+
(recurse_submodules != RECURSE_SUBMODULES_ON))
319+
check_for_new_submodule_commits(ref->new_sha1);
302320
r = s_update_ref("fast-forward", ref, 1);
303321
sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : ' ',
304322
TRANSPORT_SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
@@ -310,6 +328,9 @@ static int update_local_ref(struct ref *ref,
310328
strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
311329
strcat(quickref, "...");
312330
strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
331+
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
332+
(recurse_submodules != RECURSE_SUBMODULES_ON))
333+
check_for_new_submodule_commits(ref->new_sha1);
313334
r = s_update_ref("forced-update", ref, 1);
314335
sprintf(display, "%c %-*s %-*s -> %s (%s)", r ? '!' : '+',
315336
TRANSPORT_SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
@@ -810,6 +831,8 @@ static void add_options_to_argv(int *argc, const char **argv)
810831
argv[(*argc)++] = "--keep";
811832
if (recurse_submodules == RECURSE_SUBMODULES_ON)
812833
argv[(*argc)++] = "--recurse-submodules";
834+
else if (recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)
835+
argv[(*argc)++] = "--recurse-submodules=on-demand";
813836
if (verbosity >= 2)
814837
argv[(*argc)++] = "-v";
815838
if (verbosity >= 1)
@@ -951,15 +974,16 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
951974
if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF)) {
952975
const char *options[10];
953976
int num_options = 0;
954-
/* Set recursion as default when we already are recursing */
955-
if (submodule_prefix[0])
956-
set_config_fetch_recurse_submodules(1);
977+
if (recurse_submodules_default) {
978+
int arg = parse_fetch_recurse_submodules_arg("--recurse-submodules-default", recurse_submodules_default);
979+
set_config_fetch_recurse_submodules(arg);
980+
}
957981
gitmodules_config();
958982
git_config(submodule_config, NULL);
959983
add_options_to_argv(&num_options, options);
960984
result = fetch_populated_submodules(num_options, options,
961985
submodule_prefix,
962-
recurse_submodules == RECURSE_SUBMODULES_ON,
986+
recurse_submodules,
963987
verbosity < 0);
964988
}
965989

git-pull.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ do
110110
--recurse-submodules)
111111
recurse_submodules=--recurse-submodules
112112
;;
113+
--recurse-submodules=*)
114+
recurse_submodules="$1"
115+
;;
113116
--no-recurse-submodules)
114117
recurse_submodules=--no-recurse-submodules
115118
;;

git-submodule.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,11 @@ cmd_update()
488488

489489
if test -z "$nofetch"
490490
then
491+
# Run fetch only if $sha1 isn't present or it
492+
# is not reachable from a ref.
491493
(clear_local_git_env; cd "$path" &&
492-
git-fetch) ||
494+
((rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) &&
495+
test -z "$rev") || git-fetch)) ||
493496
die "Unable to fetch in submodule path '$path'"
494497
fi
495498

0 commit comments

Comments
 (0)