Teach fetch and pull to recursively fetch submodules
v3 cover Teach fetch and pull to recursively fetch submodules
So here is the third iteration of the recursive fetch/pull series.
Changes since v2:
* The default now is to not recurse into submodules (also see "Still to do")
* The command line option has been renamed to "--recurse-submodules" as proposed at the GitTogether
* The config options are named "submodule.<name>.fetchRecurseSubmodules" and "fetch.recurseSubmodules" now
* Switched the order of the two patches adding the config options
Question:
* Should the "--submodule-prefix" option - which is only used internally now - be a hidden option to "git fetch"?
Still to do:
* Add a mode to only fetch those submodules where new recorded commits are fetched in the superproject (and maybe later even fetch only those commits in the submodule which are referenced in the superprojects fetch). This could be a sane default - especially for projects having lots of submodules - and could be enabled by using then to be added "--recurse-submodules=changed" and "fetch[.]recurseSubmodules=changed" options where the configuration uses other defaults (I'm not really convinced yet 'changed' is a very good name but couldn't come up with a better one yet. So suggestions for alternatives are very welcome :-)
* Boost performance by concurrently fetching submodules (after my first experiments this must be configurable, e.g. how many fetch commands to run at the same time, as some git servers barf on too many fetches run at the same time)
But nonetheless I think this patch series is ok for inclusion as it does not change default behavior and gives people the opportunity to play with recursive fetch/pull by enabling one of the introduced config options.
Jens Lehmann (3):
fetch/pull: Add the --recurse-submodules option Add the 'fetch.recurseSubmodules' config setting
Submodules: Add the "fetchRecurseSubmodules" config option
Documentation/config.txt | 12 +++ Documentation/fetch-options.txt | 13 +++ Documentation/gitmodules.txt | 8 ++ builtin/fetch.c | 64 ++++++++++--- git-pull.sh | 10 ++- submodule.c | 98 +++++++++++++++++++- submodule.h | 5 + t/t5526-fetch-submodules.sh | 195 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 388 insertions(+), 17 deletions(-) create mode 100755 t/t5526-fetch-submodules.sh
Signature · 1 line
1.7.3.2.337.g9376c
Quoted 2 lines · Jens Lehmann
* Should the "--submodule-prefix" option - which is only used internally now - be a hidden option to "git fetch"?
Yes. (Any option that is useless outside scripts should be, imho.)
Quoted 3 lines
But nonetheless I think this patch series is ok for inclusion as it does not change default behavior and gives people the opportunity to play with recursive fetch/pull by enabling one of the introduced config options.
Except for the .gitmodules detail I mentioned, it looks good to me. Looking forward to trying it out.
Thanks,
Jonathan
Am 11.11.2010 01:05, schrieb Jonathan Nieder:
Quoted 6 lines
Quoted 2 lines · Jens Lehmann
* Should the "--submodule-prefix" option - which is only used internally now - be a hidden option to "git fetch"?
Yes. (Any option that is useless outside scripts should be, imho.)
Ok, I will change that.
Quoted 6 lines
Quoted 3 lines
But nonetheless I think this patch series is ok for inclusion as it does not change default behavior and gives people the opportunity to play with recursive fetch/pull by enabling one of the introduced config options.
Except for the .gitmodules detail I mentioned, it looks good to me. Looking forward to trying it out.
Thanks!
PATCH v4 1/3 fetch/pull: Add the --recurse-submodules option
In reply to Jonathan NiederUntil now you had to call "git submodule update" (without -N|--no-fetch option) or something like "git submodule foreach git fetch" to fetch new commits in populated submodules from their remote.
This could lead to "(commits not present)" messages in the output of "git diff --submodule" (which is used by "git gui" and "gitk") after fetching or pulling new commits in the superproject and is an obstacle for implementing recursive checkout of submodules. Also "git submodule update" cannot fetch changes when disconnected, so it was very easy to forget to fetch the submodule changes before disconnecting only to discover later that they are needed.
This patch adds the "--recurse-submodules" option to recursively fetch each populated submodule from the url configured in the .git/config of the submodule at the end of each "git fetch" or during "git pull" in the superproject. The submodule paths are taken from the index.
The hidden option "--submodule-prefix" is added to "git fetch" to be able to print out the full paths of nested submodules.
---
Am 11.11.2010 01:05, schrieb Jonathan Nieder:
Quoted 6 lines
Quoted 2 lines · Jens Lehmann
* Should the "--submodule-prefix" option - which is only used internally now - be a hidden option to "git fetch"?
Yes. (Any option that is useless outside scripts should be, imho.)
Ok, here is the updated version of patch 1/3 making "--submodule-prefix" a hidden option which is not documented in Documentation/fetch-options.txt .
Documentation/fetch-options.txt | 3 + builtin/fetch.c | 53 ++++++++++++++----- git-pull.sh | 7 ++- submodule.c | 66 +++++++++++++++++++++++- submodule.h | 3 + t/t5526-fetch-submodules.sh | 109 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 224 insertions(+), 17 deletions(-) create mode 100755 t/t5526-fetch-submodules.sh
Documentation/fetch-options.txt +3 -0
@@ -66,6 +66,9 @@ ifndef::git-pull[] linkgit:git-config[1]. endif::git-pull[] +--recurse-submodules:: + Use this option to fetch new commits of all populated submodules too. + -u:: --update-head-ok:: By default 'git fetch' refuses to update the head which
builtin/fetch.c +39 -14
103 lines not on this page · raw message
git-pull.sh +5 -2
@@ -38,7 +38,7 @@ test -z "$(git ls-files -u)" || die_conflict test -f "$GIT_DIR/MERGE_HEAD" && die_merge strategy_args= diffstat= no_commit= squash= no_ff= ff_only= -log_arg= verbosity= progress= +log_arg= verbosity= progress= recurse_submodules= merge_args= curr_branch=$(git symbolic-ref -q HEAD) curr_branch_short="${curr_branch#refs/heads/}"
@@ -105,6 +105,9 @@ do --no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase) rebase=false ;; + --recurse-submodules) + recurse_submodules=--recurse-submodules + ;; --d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run) dry_run=--dry-run ;;
@@ -220,7 +223,7 @@ test true = "$rebase" && { done } orig_head=$(git rev-parse -q --verify HEAD) -git fetch $verbosity $progress $dry_run --update-head-ok "$@" || exit 1 +git fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok "$@" || exit 1 test -z "$dry_run" || exit 0 curr_head=$(git rev-parse -q --verify HEAD)
submodule.c +65 -1
78 lines not on this page · raw message
submodule.h +3 -0
@@ -5,6 +5,7 @@ struct diff_options;void set_diffopt_flags_from_submodule_config (struct diff_options *diffopt,const char *path); +int submodule_config (const char *var,const char *value,void *cb);void gitmodules_config ();int parse_submodule_config_option (const char *var,const char *value);void handle_ignore_submodules_arg (struct diff_options *diffopt,const char *);
@@ -12,6 +13,8 @@ void show_submodule_summary(FILE *f, const char *path, unsigned char one[20], unsigned char two[20], unsigned dirty_submodule, const char *del, const char *add, const char *reset); +int fetch_populated_submodules (int num_options,const char **options, +const char *prefix,int quiet);unsigned is_submodule_modified (const char *path,int ignore_untracked);int merge_submodule (unsigned char result[20 ],const char *path,const unsigned char base[20 ],const unsigned char a[20 ],const unsigned char b[20 ]);
t/t5526-fetch-submodules.sh new file +109 -0
109 lines not on this page · raw message
Signature · 1 line
1.7.3.2.335.g2e3006
Re: [PATCH v4 1/3] fetch/pull: Add the --recurse-submodules option
Quoted 2 lines · Jens Lehmann
Ok, here is the updated version of patch 1/3 making "--submodule-prefix" a hidden option which is not documented in
Documentation/fetch-options.txt.
Oh, I missed that you were proposing leaving it undocumented. On one hand, it is nice when debugging if all options are documented; but on the other hand, there is precedent in --rebasing for hiding implementation details like this. Unlike -h output, the manual is not so space-constrainted, so...
Quoted 15 lines
t/t5526-fetch-submodules.sh new file +12
-0@@ -0,0 +1,109 @@ +#!/bin/sh +# Copyright (c) 2010, Jens Lehmann + +test_description='Recursive "git fetch" for submodules' + +. ./test-lib.sh + +pwd=$(pwd) + +add_upstream_commit() { + ( + cd submodule &&
t/t5526-fetch-submodules.sh line 22
Quoted 10 lines
t/t5526-fetch-submodules.sh new file +10
-0+ head1=$(git rev-parse --short HEAD) && + echo new >> subfile && + test_tick && + git add subfile && + git commit -m new subfile && + head2=$(git rev-parse --short HEAD) && + echo "From $pwd/submodule" > ../expect.err && + echo " $head1..$head2 master -> origin/master" >> ../expect.err + ) + (
Missing &&?
Hope that helps. These are just tiny nitpicks; I am happy with the patch with or without them.
Documentation/fetch-options.txt +7 -0
@@ -67,6 +67,13 @@ endif::git-pull[] --recurse-submodules:: Use this option to fetch new commits of all populated submodules too. +ifndef::git-pull[] +--submodule-prefix=<path>:: + Prepend <path> to paths printed in informative messages + such as "Fetching submodule foo". This option is used + internally when recursing over submodules. +endif::git-pull[] + -u:: --update-head-ok:: By default 'git fetch' refuses to update the head which
t/t5526-fetch-submodules.sh +1 -1
@@ -18,7 +18,7 @@ add_upstream_commit() { head2=$(git rev-parse --short HEAD) && echo "From $pwd/submodule" > ../expect.err && echo " $head1..$head2 master -> origin/master" >> ../expect.err - ) + ) && ( cd deepsubmodule && head1=$(git rev-parse --short HEAD) &&
Re: [PATCH v4 1/3] fetch/pull: Add the --recurse-submodules option
Am 12.11.2010 20:54, schrieb Jonathan Nieder:
Quoted 9 lines
Quoted 2 lines · Jens Lehmann
Ok, here is the updated version of patch 1/3 making "--submodule-prefix" a hidden option which is not documented in
Documentation/fetch-options.txt.Oh, I missed that you were proposing leaving it undocumented. On one hand, it is nice when debugging if all options are documented; but on the other hand, there is precedent in --rebasing for hiding implementation details like this. Unlike -h output, the manual is not so space-constrainted, so...
Whoops, my question was about hiding the option and so I have been a bit overeager to remove the documentation too ...
Quoted 19 lines
Quoted 19 lines
t/t5526-fetch-submodules.sh new file +16
-0@@ -0,0 +1,109 @@ +#!/bin/sh +# Copyright (c) 2010, Jens Lehmann + +test_description='Recursive "git fetch" for submodules' + +. ./test-lib.sh + +pwd=$(pwd) + +add_upstream_commit() { + ( + cd submodule && + head1=$(git rev-parse --short HEAD) && + echo new >> subfile && + test_tick && + git add subfile &&
Quoted 8 lines
t/t5526-fetch-submodules.sh line 22
Quoted 6 lines
t/t5526-fetch-submodules.sh new file +6
-0+ git commit -m new subfile && + head2=$(git rev-parse --short HEAD) && + echo "From $pwd/submodule" > ../expect.err && + echo " $head1..$head2 master -> origin/master" >> ../expect.err + ) + (Missing &&?
Good eyes!
Quoted 2 lines
Hope that helps. These are just tiny nitpicks; I am happy with the patch with or without them.
Thanks!
Junio, do you want me to send an updated version of this patch or are you ok with squashing this in?
Quoted 32 lines
Documentation/fetch-options.txt +7
-0@@ -67,6 +67,13 @@ endif::git-pull[] --recurse-submodules:: Use this option to fetch new commits of all populated submodules too. +ifndef::git-pull[] +--submodule-prefix=<path>:: + Prepend <path> to paths printed in informative messages + such as "Fetching submodule foo". This option is used + internally when recursing over submodules. +endif::git-pull[] + -u:: --update-head-ok:: By default 'git fetch' refuses to update the head whicht/t5526-fetch-submodules.sh +1
-1@@ -18,7 +18,7 @@ add_upstream_commit() { head2=$(git rev-parse --short HEAD) && echo "From $pwd/submodule" > ../expect.err && echo " $head1..$head2 master -> origin/master" >> ../expect.err - ) + ) && ( cd deepsubmodule && head1=$(git rev-parse --short HEAD) &&
Re: [PATCH v4 1/3] fetch/pull: Add the --recurse-submodules option
In reply to Jens LehmannQuoted 13 lines · Jens Lehmann
Until now you had to call "git submodule update" (without -N|--no-fetch option) or something like "git submodule foreach git fetch" to fetch new commits in populated submodules from their remote.
...builtin/fetch.c +0
-0@@ -784,28 +790,36 @@ static int add_remote_or_group(const char *name, struct string_list *list)return 1 ; }
builtin/fetch.c static int add_remote_or_group(const char *name, struct string_list *list) · line 798
Quoted 10 lines
builtin/fetch.c +5
-4-static int fetch_multiple (struct string_list *list) +static void add_options_to_argv (int *argc,const char **argv) { -int i, result =0 ; -const char *argv[11 ] = {"fetch" ,"--append" }; -... +static int fetch_multiple (struct string_list *list) +{ +int i, result =0 ; +const char *argv[12 ] = {"fetch" ,"--append" };
This used to be 11; are we adding something new? Ahh, possibly "--recurse_submodules".
Quoted 23 lines
submodule.c +7
-1@@ -63,7 +63,7 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt, } } -static int submodule_config (const char *var,const char *value,void *cb) +int submodule_config (const char *var,const char *value,void *cb) {if (!prefixcmp (var,"submodule." ))return parse_submodule_config_option (var, value);@@ -229,6 +229,70 @@ void show_submodule_summary(FILE *f, const char *path,strbuf_release (&sb); } +int fetch_populated_submodules (int num_options,const char **options, +const char *prefix,int quiet) +{ +int i, result =0 , argc =0 ; +struct child_process cp; +const char **argv;
submodule.c void show_submodule_summary(FILE *f, const char *path, · line 247
Quoted 10 lines
submodule.c +10
-0+struct string_list_item *name_for_path; +const char *work_tree =get_git_work_tree (); +if (!work_tree) +return 0 ; + +if (!the_index.initialized) +if (read_cache () <0 ) +die ("index file corrupt" ); + + argv =xcalloc (num_options +5 ,sizeof (const char *));
Where is this '5' coming from? "fetch" "--submodule-prefix", the prefix, and the terminating NULL? What did I miss?
Re: [PATCH v4 1/3] fetch/pull: Add the --recurse-submodules option
Am 09.12.2010 22:16, schrieb Junio C Hamano:
Quoted 15 lines
Quoted 13 lines · Jens Lehmann
Until now you had to call "git submodule update" (without -N|--no-fetch option) or something like "git submodule foreach git fetch" to fetch new commits in populated submodules from their remote.
...builtin/fetch.c +0
-0@@ -784,28 +790,36 @@ static int add_remote_or_group(const char *name, struct string_list *list)return 1 ; }
Quoted 13 lines
builtin/fetch.c static int add_remote_or_group(const char *name, struct string_list *list) · line 819
Quoted 10 lines
builtin/fetch.c +5
-4-static int fetch_multiple (struct string_list *list) +static void add_options_to_argv (int *argc,const char **argv) { -int i, result =0 ; -const char *argv[11 ] = {"fetch" ,"--append" }; -... +static int fetch_multiple (struct string_list *list) +{ +int i, result =0 ; +const char *argv[12 ] = {"fetch" ,"--append" };This used to be 11; are we adding something new? Ahh, possibly "--recurse_submodules".
Yup, that's why! (see a few lines down between "--keep" and "-v").
Quoted 28 lines
Quoted 28 lines
submodule.c +12
-1@@ -63,7 +63,7 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt, } } -static int submodule_config (const char *var,const char *value,void *cb) +int submodule_config (const char *var,const char *value,void *cb) {if (!prefixcmp (var,"submodule." ))return parse_submodule_config_option (var, value);@@ -229,6 +229,70 @@ void show_submodule_summary(FILE *f, const char *path,strbuf_release (&sb); } +int fetch_populated_submodules (int num_options,const char **options, +const char *prefix,int quiet) +{ +int i, result =0 , argc =0 ; +struct child_process cp; +const char **argv; +struct string_list_item *name_for_path; +const char *work_tree =get_git_work_tree (); +if (!work_tree) +return 0 ; +
Quoted 8 lines
submodule.c void show_submodule_summary(FILE *f, const char *path, · line 247
Quoted 5 lines
submodule.c +5
-0+if (!the_index.initialized) +if (read_cache () <0 ) +die ("index file corrupt" ); + + argv =xcalloc (num_options +5 ,sizeof (const char *));Where is this '5' coming from? "fetch" "--submodule-prefix", the prefix, and the terminating NULL? What did I miss?
No, you didn't miss anything but I have been off by one ... '4' is sufficient here.
Re: [PATCH v4 1/3] fetch/pull: Add the --recurse-submodules option
Quoted 22 lines · Jens Lehmann
Am 09.12.2010 22:16, schrieb Junio C Hamano:
...Quoted 11 lines
Quoted 11 lines
(quoted diff) +11
-0+int fetch_populated_submodules(int num_options, const char **options, + const char *prefix, int quiet) +{ + int i, result = 0, argc = 0; + struct child_process cp; + const char **argv; + struct string_list_item *name_for_path; + const char *work_tree = get_git_work_tree(); + if (!work_tree) + return 0; +Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ if (!the_index.initialized) + if (read_cache() < 0) + die("index file corrupt"); + + argv = xcalloc(num_options + 5, sizeof(const char *));Where is this '5' coming from? "fetch" "--submodule-prefix", the prefix, and the terminating NULL? What did I miss?
Quoted 2 lines
No, you didn't miss anything but I have been off by one ... '4' is sufficient here.
Ok, thanks for double checking.
-- >8 --
Subject: [PATCH] fetch_populated_submodules(): document dynamic allocation size
... while fixing a miscounting.
--- submodule.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
submodule.c +2 -1
@@ -264,7 +264,8 @@ int fetch_populated_submodules(int num_options, const char **options,if (read_cache () <0 )die ("index file corrupt" ); - argv =xcalloc (num_options +5 ,sizeof (const char *)); +/* 4: "fetch" (options) "--submodule-prefix" prefix NULL */ + argv =xcalloc (num_options +4 ,sizeof (const char *)); argv[argc++] ="fetch" ;for (i =0 ; i < num_options; i++) argv[argc++] = options[i];
Re: [PATCH v4 1/3] fetch/pull: Add the --recurse-submodules option
Am 10.12.2010 18:30, schrieb Junio C Hamano:
Quoted 8 lines
Quoted 2 lines · Jens Lehmann
No, you didn't miss anything but I have been off by one ... '4' is sufficient here.
Ok, thanks for double checking.
-- >8 --
Subject: [PATCH]fetch_populated_submodules(): document dynamic allocation size
Thanks and ack.
(This was a leftover from the time the "--recurse-submodules" option had been added in this function before I moved that into add_options_to_argv())
PATCH v3 1/3 fetch/pull: Add the --recurse-submodules option
In reply to Jens LehmannUntil now you had to call "git submodule update" (without -N|--no-fetch option) or something like "git submodule foreach git fetch" to fetch new commits in populated submodules from their remote.
This could lead to "(commits not present)" messages in the output of "git diff --submodule" (which is used by "git gui" and "gitk") after fetching or pulling new commits in the superproject and is an obstacle for implementing recursive checkout of submodules. Also "git submodule update" cannot fetch changes when disconnected, so it was very easy to forget to fetch the submodule changes before disconnecting only to discover later that they are needed.
This patch adds the "--recurse-submodules" option to recursively fetch each populated submodule from the url configured in the .git/config of the submodule at the end of each "git fetch" or during "git pull" in the superproject. The submodule paths are taken from the index.
The option "--submodule-prefix" is added to "git fetch" to be able to print out the full paths of nested submodules.
--- Documentation/fetch-options.txt | 12 ++++ builtin/fetch.c | 53 ++++++++++++++----- git-pull.sh | 7 ++- submodule.c | 66 +++++++++++++++++++++++- submodule.h | 3 + t/t5526-fetch-submodules.sh | 109 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 233 insertions(+), 17 deletions(-) create mode 100755 t/t5526-fetch-submodules.sh
Documentation/fetch-options.txt +12 -0
@@ -66,6 +66,18 @@ ifndef::git-pull[] linkgit:git-config[1]. endif::git-pull[] +--recurse-submodules:: + Use this option to fetch new commits of all populated submodules too. + +ifndef::git-pull[] +--submodule-prefix:: + When recursing into nested submodules it is not sufficient to just + print out the submodule path, all directories already traversed from + the superproject have to be printed too. This option is used to provide + that information, its value is prepended to the local submodule path + before it is printed out. +endif::git-pull[] + -u:: --update-head-ok:: By default 'git fetch' refuses to update the head which
builtin/fetch.c +39 -14
103 lines not on this page · raw message
git-pull.sh +5 -2
@@ -38,7 +38,7 @@ test -z "$(git ls-files -u)" || die_conflict test -f "$GIT_DIR/MERGE_HEAD" && die_merge strategy_args= diffstat= no_commit= squash= no_ff= ff_only= -log_arg= verbosity= progress= +log_arg= verbosity= progress= recurse_submodules= merge_args= curr_branch=$(git symbolic-ref -q HEAD) curr_branch_short="${curr_branch#refs/heads/}"
@@ -105,6 +105,9 @@ do --no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase) rebase=false ;; + --recurse-submodules) + recurse_submodules=--recurse-submodules + ;; --d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run) dry_run=--dry-run ;;
@@ -220,7 +223,7 @@ test true = "$rebase" && { done } orig_head=$(git rev-parse -q --verify HEAD) -git fetch $verbosity $progress $dry_run --update-head-ok "$@" || exit 1 +git fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok "$@" || exit 1 test -z "$dry_run" || exit 0 curr_head=$(git rev-parse -q --verify HEAD)
submodule.c +65 -1
78 lines not on this page · raw message
submodule.h +3 -0
@@ -5,6 +5,7 @@ struct diff_options;void set_diffopt_flags_from_submodule_config (struct diff_options *diffopt,const char *path); +int submodule_config (const char *var,const char *value,void *cb);void gitmodules_config ();int parse_submodule_config_option (const char *var,const char *value);void handle_ignore_submodules_arg (struct diff_options *diffopt,const char *);
@@ -12,6 +13,8 @@ void show_submodule_summary(FILE *f, const char *path, unsigned char one[20], unsigned char two[20], unsigned dirty_submodule, const char *del, const char *add, const char *reset); +int fetch_populated_submodules (int num_options,const char **options, +const char *prefix,int quiet);unsigned is_submodule_modified (const char *path,int ignore_untracked);int merge_submodule (unsigned char result[20 ],const char *path,const unsigned char base[20 ],const unsigned char a[20 ],const unsigned char b[20 ]);
t/t5526-fetch-submodules.sh new file +109 -0
109 lines not on this page · raw message
Signature · 1 line
1.7.3.2.337.g9376c
PATCH v3 2/3 Add the 'fetch.recurseSubmodules' config setting
In reply to Jens LehmannThis 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.
--- Documentation/config.txt | 5 +++++ Documentation/fetch-options.txt | 5 +++-- builtin/fetch.c | 21 ++++++++++++++++----- git-pull.sh | 3 +++ submodule.c | 18 +++++++++++++++++- submodule.h | 4 +++- t/t5526-fetch-submodules.sh | 36 ++++++++++++++++++++++++++++++++++++ 7 files changed, 83 insertions(+), 9 deletions(-)
Documentation/config.txt +5 -0
@@ -879,6 +879,11 @@ diff.wordRegex:: sequences that match the regular expression are "words", all other characters are *ignorable* whitespace. +fetch.recurseSubmodules:: + A boolean value which changes the behavior for fetch and pull, the + default is to not recursively fetch populated sumodules unless + configured otherwise. + fetch.unpackLimit:: If the number of objects fetched over the git native transfer is below this
Documentation/fetch-options.txt +3 -2
@@ -66,8 +66,9 @@ ifndef::git-pull[] linkgit:git-config[1]. endif::git-pull[] ---recurse-submodules:: - Use this option to fetch new commits of all populated submodules too. +--[no-]recurse-submodules:: + This option controls if new commits of all populated submodules should + be fetched too (see linkgit:git-config[1]). ifndef::git-pull[] --submodule-prefix::
builtin/fetch.c +16 -5
@@ -28,8 +28,14 @@ enum { TAGS_SET = 2 }; +enum { +RECURSE_SUBMODULES_OFF =0 , +RECURSE_SUBMODULES_DEFAULT =1 , +RECURSE_SUBMODULES_ON =2 +}; +static int all, append, dry_run, force, keep, multiple, prune, update_head_ok, verbosity; -static int progress, recurse_submodules; +static int progress, recurse_submodules =RECURSE_SUBMODULES_DEFAULT ;static int tags =TAGS_DEFAULT ;static const char *depth;static const char *upload_pack;
@@ -55,8 +61,9 @@ static struct option builtin_fetch_options[] = { "do not fetch all tags (--no-tags)", TAGS_UNSET),OPT_BOOLEAN ('p' ,"prune" , &prune,"prune tracking branches no longer on remote" ), -OPT_BOOLEAN (0 ,"recurse-submodules" , &recurse_submodules, -"control recursive fetching of submodules" ), +OPT_SET_INT (0 ,"recurse-submodules" , &recurse_submodules, +"control recursive fetching of submodules" , +RECURSE_SUBMODULES_ON ),OPT_BOOLEAN (0 ,"dry-run" , &dry_run,"dry run" ), OPT_BOOLEAN('k', "keep", &keep, "keep downloaded pack"),
@@ -802,7 +809,7 @@ static void add_options_to_argv(int *argc, const char **argv) argv[(*argc)++] ="--force" ;if (keep) argv[(*argc)++] ="--keep" ; -if (recurse_submodules) +if (recurse_submodules ==RECURSE_SUBMODULES_ON ) argv[(*argc)++] ="--recurse-submodules" ;if (verbosity >=2 ) argv[(*argc)++] ="-v" ;
@@ -940,14 +947,18 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) } } -if (!result && recurse_submodules) { +if (!result && (recurse_submodules !=RECURSE_SUBMODULES_OFF )) {const char *options[10 ];int num_options =0 ; +/* Set recursion as default when we already are recursing */ +if (submodule_prefix[0 ]) +set_config_fetch_recurse_submodules (1 );gitmodules_config ();git_config (submodule_config,NULL );add_options_to_argv (&num_options, options); result =fetch_populated_submodules (num_options, options, submodule_prefix, + recurse_submodules ==RECURSE_SUBMODULES_ON , verbosity <0 ); }
git-pull.sh +3 -0
@@ -108,6 +108,9 @@ do --recurse-submodules) recurse_submodules=--recurse-submodules ;; + --no-recurse-submodules) + recurse_submodules=--no-recurse-submodules + ;; --d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run) dry_run=--dry-run ;;
submodule.c +17 -1
@@ -11,6 +11,7 @@struct string_list config_name_for_path;struct string_list config_ignore_for_name; +static int config_fetch_recurse_submodules;static int add_submodule_odb (const char *path) {
@@ -67,6 +68,10 @@ int submodule_config(const char *var, const char *value, void *cb) {if (!prefixcmp (var,"submodule." ))return parse_submodule_config_option (var, value); +else if (!strcmp (var,"fetch.recursesubmodules" )) { + config_fetch_recurse_submodules =git_config_bool (var, value); +return 0 ; + }return 0 ; }
@@ -229,8 +234,14 @@ void show_submodule_summary(FILE *f, const char *path,strbuf_release (&sb); } +void set_config_fetch_recurse_submodules (int value) +{ + config_fetch_recurse_submodules = value; +} +int fetch_populated_submodules (int num_options,const char **options, -const char *prefix,int quiet) +const char *prefix,int ignore_config, +int quiet) {int i, result =0 , argc =0 ;struct child_process cp;
@@ -271,6 +282,11 @@ int fetch_populated_submodules(int num_options, const char **options,if (name_for_path) name = name_for_path->util; +if (!ignore_config) { +if (!config_fetch_recurse_submodules) +continue ; + } +strbuf_addf (&submodule_path,"%s/%s" , work_tree, ce->name);strbuf_addf (&submodule_git_dir,"%s/.git" , submodule_path.buf);strbuf_addf (&submodule_prefix,"%s%s/" , prefix, ce->name);
submodule.h +3 -1
@@ -13,8 +13,10 @@ void show_submodule_summary(FILE *f, const char *path, unsigned char one[20], unsigned char two[20], unsigned dirty_submodule, const char *del, const char *add, const char *reset); +void set_config_fetch_recurse_submodules (int value);int fetch_populated_submodules (int num_options,const char **options, -const char *prefix,int quiet); +const char *prefix,int ignore_config, +int quiet);unsigned is_submodule_modified (const char *path,int ignore_untracked);int merge_submodule (unsigned char result[20 ],const char *path,const unsigned char base[20 ],const unsigned char a[20 ],const unsigned char b[20 ]);
t/t5526-fetch-submodules.sh +36 -0
@@ -106,4 +106,40 @@ test_expect_success "--dry-run propagates to submodules" ' test_cmp expect.err actual.err ' +test_expect_success "recurseSubmodules=true propagates into submodules" ' + add_upstream_commit && + ( + cd downstream && + git config fetch.recurseSubmodules true + git fetch >../actual.out 2>../actual.err + ) && + test_cmp expect.out actual.out && + test_cmp expect.err actual.err +' + +test_expect_success "--recurse-submodules overrides config in submodule" ' + add_upstream_commit && + ( + cd downstream && + ( + cd submodule && + git config fetch.recurseSubmodules false + ) && + git fetch --recurse-submodules >../actual.out 2>../actual.err + ) && + test_cmp expect.out actual.out && + test_cmp expect.err actual.err +' + +test_expect_success "--no-recurse-submodules overrides config setting" ' + add_upstream_commit && + ( + cd downstream && + git config fetch.recurseSubmodules true + git fetch --no-recurse-submodules >../actual.out 2>../actual.err + ) && + ! test -s actual.out && + ! test -s actual.err +' + test_done
Signature · 1 line
1.7.3.2.337.g9376c
Re: [PATCH v3 2/3] Add the 'fetch.recurseSubmodules' config setting
Quoted 6 lines · Jens Lehmann
t/t5526-fetch-submodules.sh +0
-0@@ -106,4 +106,40 @@ test_expect_success "--dry-run propagates to submodules" ' test_cmp expect.err actual.err '
t/t5526-fetch-submodules.sh test_expect_success "--dry-run propagates to submodules" ' · line 118
Quoted 10 lines
t/t5526-fetch-submodules.sh +10
-0+test_expect_success "recurseSubmodules=true propagates into submodules" ' + add_upstream_commit && + ( + cd downstream && + git config fetch.recurseSubmodules true + git fetch >../actual.out 2>../actual.err + ) && + test_cmp expect.out actual.out && + test_cmp expect.err actual.err +'
This configuration item is read from .gitmodules, too, right? Would it be easy (or desirable) to make it not read from there? Either way, it would be nice to have a test so the behavior doesn't change without anyone noticing.
Re: [PATCH v3 2/3] Add the 'fetch.recurseSubmodules' config setting
Am 11.11.2010 01:02, schrieb Jonathan Nieder:
Quoted 8 lines
Quoted 6 lines · Jens Lehmann
t/t5526-fetch-submodules.sh +0
-0@@ -106,4 +106,40 @@ test_expect_success "--dry-run propagates to submodules" ' test_cmp expect.err actual.err '
Quoted 15 lines
t/t5526-fetch-submodules.sh test_expect_success "--dry-run propagates to submodules" ' · line 118
Quoted 10 lines
t/t5526-fetch-submodules.sh +10
-0+test_expect_success "recurseSubmodules=true propagates into submodules" ' + add_upstream_commit && + ( + cd downstream && + git config fetch.recurseSubmodules true + git fetch >../actual.out 2>../actual.err + ) && + test_cmp expect.out actual.out && + test_cmp expect.err actual.err +'This configuration item is read from .gitmodules, too, right? Would it be easy (or desirable) to make it not read from there? Either way, it would be nice to have a test so the behavior doesn't change without anyone noticing.
"fetch.recurseSubmodules" is only read from .git/config. The one read first from .gitmodules and then from .git/config is the per-submodule setting "submodule.<name>.fetchRecurseSubmodules" added in 3/3. But maybe I should add a test that "fetch.recurseSubmodules" also works when set in the global config ...
Re: [PATCH v3 2/3] Add the 'fetch.recurseSubmodules' config setting
Quoted 10 lines · Jens Lehmann
Am 11.11.2010 01:02, schrieb Jonathan Nieder:
Quoted 4 lines
This configuration item is read from .gitmodules, too, right? Would it be easy (or desirable) to make it not read from there? Either way, it would be nice to have a test so the behavior doesn't change without anyone noticing.
"fetch.recurseSubmodules" is only read from .git/config. The one read first from .gitmodules and then from .git/config is the per-submodule setting "submodule.<name>.fetchRecurseSubmodules" added in 3/3.
Sorry for the nonsense. Would it be easy (or desirable) to make _that_ one not be read from .gitmodules?
Quoted 3 lines
But
maybe I should add a test that "fetch.recurseSubmodules" also works when set in the global config ...
Yes, I agree that such a test would be good (though less important than a test for the behavior with no configuration set at all, say). A test to demonstrate that configuration aside from submodule.* is not read from .gitmodules would also be good imho, but I don't think it's a blocker for anything. :)
Re: [PATCH v3 2/3] Add the 'fetch.recurseSubmodules' config setting
Quoted 6 lines · Jonathan Nieder
Quoted 3 lines
"fetch.recurseSubmodules" is only read from .git/config. The one read first from .gitmodules and then from .git/config is the per-submodule setting "submodule.<name>.fetchRecurseSubmodules" added in 3/3.
Sorry for the nonsense. Would it be easy (or desirable) to make _that_ one not be read from .gitmodules?
I think the motivation behind having a way to read it from .gitmodules is so that project can suggest the default for convenience (e.g. "almost everybody who interacts with this project wants these submodules checked out and kept updated").
Traditionally the suggestions kept in .gitmodules were propagated to the config when the submodule was initialized, and at runtime we read only from the config from then on without reading from .gitmodules, so that once the user decides to follow what the project suggests (or customize that away), the preference would stick to the repository.
That arrangement does not cater well to people who want to follow along whatever the project's suggestion of the day, so we might want to change things so that we if we find it in the config, we stop there and use what we found, otherwise we use what is in the in-tree gitmodules; I suspect we might require some changes to "submodule init" not to copy certain things to the config for that to work, though...
Re: [PATCH v3 2/3] Add the 'fetch.recurseSubmodules' config setting
Quoted 4 lines · Junio C Hamano
I think the motivation behind having a way to read it from .gitmodules is so that project can suggest the default for convenience (e.g. "almost everybody who interacts with this project wants these submodules checked out and kept updated").
Yes, that makes some sense to me. Except wouldn't it be a single configuration item? "These submodules should be checked out in all but unusual situations, so check them out automatically and keep them updated."
Maybe a person setting this to false actually means "This submodule has its url set to a repository that is updated very frequently, and most updates are not relevant to the superproject." Unfortunately, I think the result would be a poor user experience: when an update comes that _is_ important to the superproject, what happens?
$ git fetch
... go on plane ...
$ git merge @{u} && git submodule update --no-fetch --recursive
[...]
fatal: reference is not a tree: f1c596a3895643d0969a15b8e945bf0c0072e470Hmm. I think in that scenario a better solution would be to point the submodule url point to a project-specific clone that is updated less frequently.
What am I missing?
Jonathan
Re: [PATCH v3 2/3] Add the 'fetch.recurseSubmodules' config setting
Am 11.11.2010 20:00, schrieb Jonathan Nieder:
Quoted 11 lines
Quoted 4 lines · Junio C Hamano
I think the motivation behind having a way to read it from .gitmodules is so that project can suggest the default for convenience (e.g. "almost everybody who interacts with this project wants these submodules checked out and kept updated").
Yes, that makes some sense to me. Except wouldn't it be a single configuration item? "These submodules should be checked out in all but unusual situations, so check them out automatically and keep them updated."
Hmm, but we have at least three modes of how to update them:
1) Never fetch the submodule (to get new commits the user has to run "git fetch --recurse-submodules" by hand)
2) Fetch the submodule each time you fetch the superproject (Which is really handy when you do development in the submodule too but can be really inconvenient when you don't)
3) Update submodules only when new recorded commits are fetched in the superproject (This mode is not added with the current patch series but will be in one of the next)
So you would need a config option for that anyway, no? And that is why I'd rather like to have a separate fetch option to control that behavior instead of an implicit "if-it's-to-be-checked-out-fetch-it-too" approach.
Quoted 12 lines
Maybe a person setting this to false actually means "This submodule has its url set to a repository that is updated very frequently, and most updates are not relevant to the superproject." Unfortunately, I think the result would be a poor user experience: when an update comes that _is_ important to the superproject, what happens?
$ git fetch ... go on plane ... $ git merge @{u} && git submodule update --no-fetch --recursive [...] fatal: reference is not a tree: f1c596a3895643d0969a15b8e945bf0c0072e470
Quoted 5 lines
Hmm. I think in that scenario a better solution would be to point the submodule url point to a project-specific clone that is updated less frequently.
What am I missing?
That situation should be handled by method 3) above which was proposed for such a use case.
Re: [PATCH v3 2/3] Add the 'fetch.recurseSubmodules' config setting
Quoted 16 lines · Jens Lehmann
Am 11.11.2010 20:00, schrieb Jonathan Nieder:
Quoted 4 lines
Yes, that makes some sense to me. Except wouldn't it be a single configuration item? "These submodules should be checked out in all but unusual situations, so check them out automatically and keep them updated."
Hmm, but we have at least three modes of how to update them:
1) Never fetch the submodule (to get new commits the user has to run "git fetch --recurse-submodules" by hand)
2) Fetch the submodule each time you fetch the superproject (Which is really handy when you do development in the submodule too but can be really inconvenient when you don't)
Quoted 7 lines
3) Update submodules only when new recorded commits are fetched in the superproject (This mode is not added with the current patch series but will be in one of the next)
So you would need a config option for that anyway, no? And that is why I'd rather like to have a separate fetch option to control that behavior instead of an implicit "if-it's-to-be-checked-out-fetch-it-too" approach.
I still think I am missing something.
Traditionally, git has been a _content_ tracker. The configuration that gets transmitted (.gitignore, .gitattributes, .gitmodules) would only represent basic information needed for that content to remain usable and sensible.
In the case of .gitmodules, it seems that two concepts are being conflated:
A. Configuration based on the user's preferences. Absolutely, a person
deserves to be able to easily choose between (1), (2), and (3) as described above.
B. Metadata about the content that should be shared. For example, "this
submodule would be checked out in all but unusual circumstances" is a useful thing to be able to declare.
Probably I am missing something big, but fetchsubmodules as currently defined seem like something in category A and not in category B. Partially because if we ever implement option (3), that is what almost _every_ casual consumer will want. So why should they be stuck with these configuration files specifying (1) and (2) when they check out old revisions?
All that said, I do not think it is unreasonable in some situations for a project to want to share configuration of type (A) between members of a project; for example, lots of projects share hooks and that's great. I just don't think git should set it up automatically --- better to require an explicit user action like "sh useprojectconfiguration.sh" (an action more explicit than "please initialize and checkout all relevant submodules") for such cases.
Hoping that is clearer,
Jonathan
Re: [PATCH v3 2/3] Add the 'fetch.recurseSubmodules' config setting
Am 12.11.2010 16:52, schrieb Jonathan Nieder:
Quoted 21 lines
Quoted 20 lines · Jens Lehmann
Am 11.11.2010 20:00, schrieb Jonathan Nieder:
Quoted 4 lines
Yes, that makes some sense to me. Except wouldn't it be a single configuration item? "These submodules should be checked out in all but unusual situations, so check them out automatically and keep them updated."
Hmm, but we have at least three modes of how to update them:
1) Never fetch the submodule (to get new commits the user has to run "git fetch --recurse-submodules" by hand)
2) Fetch the submodule each time you fetch the superproject (Which is really handy when you do development in the submodule too but can be really inconvenient when you don't)
3) Update submodules only when new recorded commits are fetched in the superproject (This mode is not added with the current patch series but will be in one of the next)
Quoted 5 lines
Quoted 3 lines
So you would need a config option for that anyway, no? And that is why I'd rather like to have a separate fetch option to control that behavior instead of an implicit "if-it's-to-be-checked-out-fetch-it-too" approach.
I still think I am missing something.
Ok, I'll try harder to explain my view ;-)
Quoted 4 lines
Traditionally, git has been a _content_ tracker. The configuration that gets transmitted (.gitignore, .gitattributes, .gitmodules) would only represent basic information needed for that content to remain usable and sensible.
Ack.
Quoted 10 lines
In the case of .gitmodules, it seems that two concepts are being conflated:
A. Configuration based on the user's preferences. Absolutely, a person
deserves to be able to easily choose between (1), (2), and (3) as described above.B. Metadata about the content that should be shared. For example, "this
submodule would be checked out in all but unusual circumstances" is a useful thing to be able to declare.
No, I think these concepts aren't conflated at all:
- Category A is handled by .git/config
- Category B is handled by the .gitmodules file
Category A should not be handled by a file in the work tree while category B stuff belongs there to be able to share it. That is why git searches all new options in both files with the values from .git/config overriding those from .gitmodules: to provide useful defaults and let the user choose otherwise if he wants to.
Quoted 6 lines
Probably I am missing something big, but fetchsubmodules as currently defined seem like something in category A and not in category B. Partially because if we ever implement option (3), that is what almost _every_ casual consumer will want. So why should they be stuck with these configuration files specifying (1) and (2) when they check out old revisions?
With submodules there never is a one-size-fits-all solution :-) (And we are currently working on option (3), so it will exist rather sooner than later)
There are people putting lots of large files in submodules for better performance and they almost always never want to fetch (or even stat) them, so (1) is for them and it's cool that their upstream can configure that, avoiding to have every developer to repeat their "obvious" choice after each clone again (and that might only be needed for some submodules, so a repo-wide config doesn't necessarily help them).
And when you are on a superproject branch actively developing inside a submodule, you may want to increase fetch-activity to fetch all new commits in the submodule even if they aren't referenced in the superproject (yet), as that might be just what your fellow developers are about to do. And the person setting up that branch could do that once for all users so they don't have to repeat it in every clone. And when switching away from that branch all those developers cannot forget to reconfigure to fetch-on-demand, so not having that in .git/config is a plus here too.
And right, "almost _every_ casual consumer" should start with (3), and that is why it will be the default. So most people will get along without having ever to configure fetch behavior in .gitmodules because git does The Right Thing for them. But in my opinion we should allow that for those other users ...
Quoted 7 lines
All that said, I do not think it is unreasonable in some situations for a project to want to share configuration of type (A) between members of a project; for example, lots of projects share hooks and that's great. I just don't think git should set it up automatically --- better to require an explicit user action like "sh
useprojectconfiguration.sh" (an action more explicit than "please initialize and checkout all relevant submodules") for such cases.
You have no other choice for hooks because of security concerns. But I can't see any downsides in leaving upstream *the choice* to configure default submodule behavior. Lots of people - including me - want that for clone and checkout. And to be consistent the same configuration abilities should be available for fetch too, and if only to follow the principle of least surprise.
Thanks
Jens
Re: [PATCH v3 2/3] Add the 'fetch.recurseSubmodules' config setting
Quoted 5 lines · Jens Lehmann
No, I think these concepts aren't conflated at all:
- Category A is handled by .git/config
- Category B is handled by the .gitmodules file
I meant that the two files currently support the same submodule.* options.
Quoted 6 lines
There are people putting lots of large files in submodules for better performance and they almost always never want to fetch (or even stat) them, so (1) is for them and it's cool that their upstream can configure that, avoiding to have every developer to repeat their "obvious" choice after each clone again (and that might only be needed for some submodules, so a repo-wide config doesn't necessarily help them).
Wouldn't (3) work for these people, too?
I think we are getting closer to an explanation. I can look into adding documentation for this on top when finished.
Quoted 6 lines
And when you are on a superproject branch actively developing inside a submodule, you may want to increase fetch-activity to fetch all new commits in the submodule even if they aren't referenced in the superproject (yet), as that might be just what your fellow developers are about to do. And the person setting up that branch could do that once for all users so they don't have to repeat it in every clone.
This one seems less reasonable to me. It seems like a way to remotely help developers get a nice setup, rather than a declaration about the content.
Let me take an unrelated example to illustrate what I mean. Some projects might want all their developers to use branch.autosetuprebase, to avoid confusion since the update hook is going to reject mergy history anyway. That seems like a perfectly reasonable desire to me, and I'd encourage them to add a script that sets everything up following the policies of their project.
Now git could even learn to read a .gitconfig file including settings like that one that do not have a security impact. It would make lots of people happy, and individuals could override settings they really dislike in ~/.gitconfig. Should we do it?
I think no, for reasons of intuitiveness and predictability.
On the other hand, scenarios like (1) might mean we have to support such things despite that downside.
Quoted 4 lines
And
when switching away from that branch all those developers cannot forget to reconfigure to fetch-on-demand, so not having that in .git/config is a plus here too.
Yes, the "read .gitmodules first and then .git/config" is a very nice enhancement --- thanks!
Quoted 4 lines
You have no other choice for hooks because of security concerns. But I can't see any downsides in leaving upstream *the choice* to configure default submodule behavior. Lots of people - including me - want that for clone and checkout.
There is one setting that it is obvious to me for upstream should be able to set:
"these submodules are a necessary part of the project;
always (at clone time, fetch time, checkout, etc) make sure they are available"
I could easily be convinced about others, but there ought to be a use case to outweigh the "subtle behavior changing behind my back" syndrome.
And again: thanks for doing all this work. It's inspiring. (Next step recursive push?)
Jonathan
Re: [PATCH v3 2/3] Add the 'fetch.recurseSubmodules' config setting
Am 12.11.2010 21:16, schrieb Jonathan Nieder:
Quoted 9 lines
Quoted 6 lines · Jens Lehmann
There are people putting lots of large files in submodules for better performance and they almost always never want to fetch (or even stat) them, so (1) is for them and it's cool that their upstream can configure that, avoiding to have every developer to repeat their "obvious" choice after each clone again (and that might only be needed for some submodules, so a repo-wide config doesn't necessarily help them).
Wouldn't (3) work for these people, too?
As I understand there are people who use submodules as something rather unrelated to the superproject line of development and thus recursive on demand fetch (and recursive checkout) would not be what they want (and could take considerable time they don't want to spend).
Quoted 2 lines
I think we are getting closer to an explanation. I can look into adding documentation for this on top when finished.
That would be great! I had the same thing in mind so I would be happy to help you with that if you want.
Quoted 10 lines
Quoted 6 lines
And when you are on a superproject branch actively developing inside a submodule, you may want to increase fetch-activity to fetch all new commits in the submodule even if they aren't referenced in the superproject (yet), as that might be just what your fellow developers are about to do. And the person setting up that branch could do that once for all users so they don't have to repeat it in every clone.
This one seems less reasonable to me. It seems like a way to remotely help developers get a nice setup, rather than a declaration about the content.
Yeah, I know this example is not as convincing as (1). But it was the best I could come up with trying to illustrate the "treat-submodules- as-if-everything-were-in-one-tree" model which some people use. (And we use this model at my dayjob, but we would be fine setting the global config option once on every developers computer. But hey, adding that to the .gitmodules file would get rid of that too ;-)
Quoted 11 lines
Let me take an unrelated example to illustrate what I mean. Some projects might want all their developers to use branch.autosetuprebase, to avoid confusion since the update hook is going to reject mergy history anyway. That seems like a perfectly reasonable desire to me, and I'd encourage them to add a script that sets everything up following the policies of their project.
Now git could even learn to read a .gitconfig file including settings like that one that do not have a security impact. It would make lots of people happy, and individuals could override settings they really dislike in ~/.gitconfig. Should we do it?
Hmm, I never thought of that. But you are right, this is the same principle I'm using for .gitmodules.
Quoted 4 lines
I think no, for reasons of intuitiveness and predictability.
On the other hand, scenarios like (1) might mean we have to support such things despite that downside.
Yup.
Quoted 7 lines
Quoted 4 lines
And
when switching away from that branch all those developers cannot forget to reconfigure to fetch-on-demand, so not having that in .git/config is a plus here too.Yes, the "read .gitmodules first and then .git/config" is a very nice enhancement --- thanks!
You are welcome!
Quoted 8 lines
Quoted 4 lines
You have no other choice for hooks because of security concerns. But I can't see any downsides in leaving upstream *the choice* to configure default submodule behavior. Lots of people - including me - want that for clone and checkout.
There is one setting that it is obvious to me for upstream should be able to set:
Quoted 6 lines
"these submodules are a necessary part of the project;
always (at clone time, fetch time, checkout, etc) make sure they are available"I could easily be convinced about others, but there ought to be a use case to outweigh the "subtle behavior changing behind my back" syndrome.
I don't have a problem with dropping 3/3 from this series if use case (1) doesn't convince people. I added it to be consistent with the behavior of the 'ignore' flag I added earlier and because I it is needed to support more than one use case for submodules in the same superproject. But we could wait if someone complains and add it if that happens ... I dunno.
Quoted 2 lines
And again: thanks for doing all this work. It's inspiring. (Next step recursive push?)
Thanks a lot! (And nope, it's recursive checkout - thats why I started recursive fetch, so that I do have something to check out ;-).
Jens
Re: [PATCH v3 2/3] Add the 'fetch.recurseSubmodules' config setting
In reply to Junio C HamanoAm 11.11.2010 19:31, schrieb Junio C Hamano:
Quoted 6 lines
Quoted 4 lines · Jonathan Nieder
Quoted 3 lines
"fetch.recurseSubmodules" is only read from .git/config. The one read first from .gitmodules and then from .git/config is the per-submodule setting "submodule.<name>.fetchRecurseSubmodules" added in 3/3.
Quoted 7 lines
Quoted 2 lines
Sorry for the nonsense. Would it be easy (or desirable) to make _that_ one not be read from .gitmodules?
I think the motivation behind having a way to read it from .gitmodules is so that project can suggest the default for convenience (e.g. "almost everybody who interacts with this project wants these submodules checked out and kept updated").
Yes, and to achieve that it should /not/ be necessary to run a "git submodule sync" manually afterwards to activate those changes.
Jonathan, I think when we allow upstream to configure which submodules are to be cloned and checked out by default (which seems an option almost everyone likes to have), doesn't it make sense to let upstream set a default which submodules should be fetched too (so that new commits there can be checked out recursively later)? I would rather not like to do that implicitly just because a submodule is configured for recursive checkout
...
Quoted 6 lines
Traditionally the suggestions kept in .gitmodules were propagated to the config when the submodule was initialized, and at runtime we read only from the config from then on without reading from .gitmodules, so that once the user decides to follow what the project suggests (or customize that away), the preference would stick to the repository.
Quoted 6 lines
That arrangement does not cater well to people who want to follow along whatever the project's suggestion of the day, so we might want to change things so that we if we find it in the config, we stop there and use what we found, otherwise we use what is in the in-tree gitmodules; I suspect we might require some changes to "submodule init" not to copy certain things to the config for that to work, though...
Right. But this would enable you to have branches where different sets of submodules are fetched, checked out and/or considered to make the superproject dirty depending on the topic the branch is for.
PATCH v3 3/3 Submodules: Add the "fetchRecurseSubmodules" config option
In reply to Jens LehmannThe 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".
--- Documentation/config.txt | 7 +++++ Documentation/fetch-options.txt | 2 +- Documentation/gitmodules.txt | 8 ++++++ submodule.c | 20 ++++++++++++++- t/t5526-fetch-submodules.sh | 50 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 3 deletions(-)
Documentation/config.txt +7 -0
@@ -1796,6 +1796,13 @@ submodule.<name>.update:: URL and other values found in the `.gitmodules` file. See linkgit:git-submodule[1] and linkgit:gitmodules[5] for details. +submodule.<name>.fetchRecurseSubmodules:: + This option can be used to enable/disable recursive fetching of this + submodule. It can be overriden by using the --[no-]recurse-submodules + command line option to "git fetch" and "git pull". + This setting will override that from in the linkgit:gitmodules[5] + file. + submodule.<name>.ignore:: Defines under what circumstances "git status" and the diff family show a submodule as modified. When set to "all", it will never be considered
Documentation/fetch-options.txt +1 -1
@@ -68,7 +68,7 @@ endif::git-pull[] --[no-]recurse-submodules:: This option controls if new commits of all populated submodules should - be fetched too (see linkgit:git-config[1]). + be fetched too (see linkgit:git-config[1] and linkgit:gitmodules[5]). ifndef::git-pull[] --submodule-prefix::
Documentation/gitmodules.txt +8 -0
@@ -44,6 +44,14 @@ submodule.<name>.update:: This config option is overridden if 'git submodule update' is given the '--merge' or '--rebase' options. +submodule.<name>.fetchRecurseSubmodules:: + This option can be used to enable/disable recursive fetching of this + submodule. If this option is also present in the submodules entry in + .git/config of the superproject, the setting there will override the + one found in .gitmodules. + Both settings can be overriden on the command line by using the + "--[no-]recurse-submodules" option to "git fetch" and "git pull".. + submodule.<name>.ignore:: Defines under what circumstances "git status" and the diff family show a submodule as modified. When set to "all", it will never be considered
submodule.c +18 -2
@@ -10,6 +10,7 @@#include "string-list.h" struct string_list config_name_for_path; +struct string_list config_fetch_recurse_submodules_for_name;struct string_list config_ignore_for_name;static int config_fetch_recurse_submodules;
@@ -105,6 +106,14 @@ int parse_submodule_config_option(const char *var, const char *value) config =string_list_append (&config_name_for_path,xstrdup (value)); config->util =strbuf_detach (&submodname,NULL );strbuf_release (&submodname); + }else if ((len >23 ) && !strcmp (var + len -23 ,".fetchrecursesubmodules" )) { +strbuf_add (&submodname, var, len -23 ); + config =unsorted_string_list_lookup (&config_fetch_recurse_submodules_for_name, submodname.buf); +if (!config) + config =string_list_append (&config_fetch_recurse_submodules_for_name, +strbuf_detach (&submodname,NULL )); + config->util =git_config_bool (var, value) ? (void *)1 :NULL ; +strbuf_release (&submodname); }else if ((len >7 ) && !strcmp (var + len -7 ,".ignore" )) {if (strcmp (value,"untracked" ) &&strcmp (value,"dirty" ) &&strcmp (value,"all" ) &&strcmp (value,"none" )) {
@@ -283,8 +292,15 @@ int fetch_populated_submodules(int num_options, const char **options, name = name_for_path->util;if (!ignore_config) { -if (!config_fetch_recurse_submodules) -continue ; +struct string_list_item *fetch_recurse_submodules_option; + fetch_recurse_submodules_option =unsorted_string_list_lookup (&config_fetch_recurse_submodules_for_name, name); +if (fetch_recurse_submodules_option) { +if (!fetch_recurse_submodules_option->util) +continue ; + }else { +if (!config_fetch_recurse_submodules) +continue ; + } }strbuf_addf (&submodule_path,"%s/%s" , work_tree, ce->name);
t/t5526-fetch-submodules.sh +50 -0
56 lines not on this page · raw message
Signature · 1 line
1.7.3.2.337.g9376c