Re: [PATCH] fetch: add new config option fetch.all
- From
Taylor Blau <me@ttaylorr.com>
- Date
- Jan 4, 2024, 17:33 UTC
- Message-ID
- <ZZbr4yAJe0dnHRcO@nand.local>
- In-Reply-To
- <20240104143656.615117-1-dev@tb6.eu>
On Thu, Jan 04, 2024 at 03:33:55PM +0100, Tamino Bauknecht wrote:
Show 5 quoted lines
> --- > Documentation/config/fetch.txt | 4 ++ > builtin/fetch.c | 18 +++++-- > t/t5514-fetch-multiple.sh | 88 ++++++++++++++++++++++++++++++++++ > 3 files changed, 105 insertions(+), 5 deletions(-)
Nice. This looks like a useful feature that folks working with more than one remote may want to take advantage of. Not that typing "git fetch --all" is all that hard, but I can see the utility of something like this for a repository with >1 remotes where the individual wants to keep all remotes up-to-date.
Show 12 quoted lines
> diff --git a/Documentation/config/fetch.txt b/Documentation/config/fetch.txt > index aea5b97477..4f12433874 100644 > --- a/Documentation/config/fetch.txt > +++ b/Documentation/config/fetch.txt > @@ -50,6 +50,10 @@ fetch.pruneTags:: > refs. See also `remote.<name>.pruneTags` and the PRUNING > section of linkgit:git-fetch[1]. > > +fetch.all:: > + If true, fetch will attempt to update all available remotes. > + This behavior can be overridden by explicitly specifying a remote. > +
Instead of "can be overridden ...", how about:
This behavior can be overridden by explicitly specifying one or more
remote(s) to fetch from.Show 15 quoted lines
> @@ -2337,11 +2344,12 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
> fetch_bundle_uri(the_repository, bundle_uri, NULL))
> warning(_("failed to fetch bundles from '%s'"), bundle_uri);
>
> - if (all) {
> - if (argc == 1)
> - die(_("fetch --all does not take a repository argument"));
> - else if (argc > 1)
> - die(_("fetch --all does not make sense with refspecs"));
> + if (all && argc == 1) {
> + die(_("fetch --all does not take a repository argument"));
> + } else if (all && argc > 1) {
> + die(_("fetch --all does not make sense with refspecs"));
> + } else if (all || (config.all > 0 && argc == 0)) {
> + /* Only use fetch.all config option if no remotes were explicitly given */To minimize the diff, let's leave the existing conditional as is, so the end state would look like:
if (all) {
if (argc == 1)
die(_("fetch --all does not take a repository argument"));
else if (argc > 1)
die(_("fetch --all does not make sense with refspecs"));
} if (all || (config.all > 0 && !argc))
(void) for_each_remote(get_one_remote_for_fetch, &list);I don't feel particularly strongly about whether or not you reorganize these if-statements, but we should change "argc == 0" to "!argc", which matches the conventions of the rest of the project.
Show 12 quoted lines
> (void) for_each_remote(get_one_remote_for_fetch, &list); > > /* do not do fetch_multiple() of one */ > diff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh > index a95841dc36..cd0aee97f9 100755 > --- a/t/t5514-fetch-multiple.sh > +++ b/t/t5514-fetch-multiple.sh > @@ -209,4 +209,92 @@ test_expect_success 'git fetch --multiple --jobs=0 picks a default' ' > git fetch --multiple --jobs=0) > ' > > +cat > expect << EOF
This should be `cat >expect <<-\EOF` (without the space between the redirect and heredoc, as well as indicating that the heredoc does not need any shell expansions).
Show 22 quoted lines
> + one/main > + one/side > + origin/HEAD -> origin/main > + origin/main > + origin/side > + three/another > + three/main > + three/side > + two/another > + two/main > + two/side > +EOF > + > +test_expect_success 'git fetch (fetch all remotes with fetch.all = true)' ' > + (git clone one test9 && > + cd test9 && > + git config fetch.all true && > + git remote add one ../one && > + git remote add two ../two && > + git remote add three ../three && > + git fetch && > + git branch -r > output &&
Same note here about the space between the redirect.
> + test_cmp ../expect output)
It looks like these tests match the existing style of the test suite, but they are somewhat out of date with respect to our more modern standards. I would probably write this like:
test_expect_success 'git fetch --all (works with fetch.all = true)' '
git clone one test10 &&
test_config -C test10 fetch.all true &&
for r in one two three
do
git -C test10 remote add $r ../$r || return 1
done &&
git -C test10 fetch --all &&
git -C test10 branch -r >actual &&
test_cmp expect actual
'While reviewing, I thought that the tests using the test9 and test10 clones were duplicates, but they are not: the earlier one uses a "git fetch", and the latter uses a "git fetch --all".
If we take just the test10 and test11 tests, I think there is some opportunity to consolidate these two, like so:
for v in true false
do
test_expect_success "git fetch --all (works with fetch.all=$v)" '
git clone one test10 &&
test_config -C test10 fetch.all $v &&
for r in one two three
do
git -C test10 remote add $r ../$r || return 1
done &&
git -C test10 fetch --all &&
git -C test10 branch -r >actual &&
test_cmp expect actual
'
doneShow 7 quoted lines
> +cat > expect << EOF > + one/main > + one/side > + origin/HEAD -> origin/main > + origin/main > + origin/side > +EOF
Same note(s) about cleaning up this heredoc.
Show 11 quoted lines
> +test_expect_success 'git fetch one (explicit remote overrides fetch.all)' ' > + (git clone one test12 && > + cd test12 && > + git config fetch.all true && > + git remote add one ../one && > + git remote add two ../two && > + git remote add three ../three && > + git fetch one && > + git branch -r > output && > + test_cmp ../expect output) > +'
I suspect that you could go further with a "setup" function that gives you a fresh clone (with fetch.all set to a specified value), and then test test would continue on from the line "git fetch one". But I think it's worth not getting too carried away with refactoring these tests ;-).
Thanks, Taylor