{"thread":{"id":"39871","subject":"[PATCH] fetch: add configuration for making --all default","startedAt":"2015-07-17T13:31:39Z","lastAt":"2015-07-17T16:14:52Z","messageCount":4,"participants":["Øystein Walle","Remi Galan Alfonso","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"266236","messageId":"1437139899-6210-1-git-send-email-oystwa@gmail.com","threadId":"39871","inReplyTo":null,"subject":"[PATCH] fetch: add configuration for making --all default","fromName":"Øystein Walle","fromEmail":"oystwa@gmail.com","sentAt":"2015-07-17T13:31:39Z","receivedAt":"2015-07-17T13:31:39Z","isPatch":true,"sender":{"key":"oystwa@gmail.com","avatar":"https://avatars.githubusercontent.com/u/794585?v=4"},"body":"Fetching from all remotes by default is useful if you're working on a\nrepo with few and/or fast remotes. It also lets you fetch from origin\neven if the current branch's upstream is elsewhere without specifying it\nexplicitly.\n\nSigned-off-by: Øystein Walle <oystwa@gmail.com>\n---\nThis is scratching a itch I have. Most of the time I just want to fetch\neverything, wherever it may be, and fetch's behavour of using the current\nupstream's remote sometimes doesn't read my mind as well as I'd like it to.\nIt's not particularly useful. But more \"destructive\" behaviours (--prune) can\nbe made default, so think this could be as well.\n\n Documentation/config.txt        |  5 +++++\n Documentation/fetch-options.txt |  4 +++-\n Documentation/git-fetch.txt     |  3 ++-\n builtin/fetch.c                 | 21 ++++++++++++++++-----\n t/t5514-fetch-multiple.sh       | 23 +++++++++++++++++++++++\n 5 files changed, 49 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 3e37b93..c40654f 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1170,6 +1170,11 @@ fetch.prune::\n \tIf true, fetch will automatically behave as if the `--prune`\n \toption was given on the command line.  See also `remote.<name>.prune`.\n \n+fetch.all::\n+\tIf true, fetch will automatically behave as if the `--all`\n+\toption was given on the command line uness a remote was given. The\n+\tdefault is false.\n+\n format.attach::\n \tEnable multipart/mixed attachments as the default for\n \t'format-patch'.  The value can also be a double quoted string\ndiff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt\nindex 45583d8..aa95a30 100644\n--- a/Documentation/fetch-options.txt\n+++ b/Documentation/fetch-options.txt\n@@ -1,5 +1,7 @@\n --all::\n-\tFetch all remotes.\n+\tFetch all remotes. This can be configured to be the default behaviour\n+\twhen no remotes are given explicitly. See the `fetch.all` configuration\n+\tvariable in linkgit:git-config[1].\n \n -a::\n --append::\ndiff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt\nindex e62d9a0..584f3fb 100644\n--- a/Documentation/git-fetch.txt\n+++ b/Documentation/git-fetch.txt\n@@ -36,7 +36,8 @@ there is a remotes.<group> entry in the configuration file.\n (See linkgit:git-config[1]).\n \n When no remote is specified, by default the `origin` remote will be used,\n-unless there's an upstream branch configured for the current branch.\n+unless there's an upstream branch configured for the current branch, or the\n+`fetch.all` configuration variable is set to true.\n \n The names of refs that are fetched, together with the object names\n they point at, are written to `.git/FETCH_HEAD`.  This information\ndiff --git a/builtin/fetch.c b/builtin/fetch.c\nindex 8d5b2db..715ea82 100644\n--- a/builtin/fetch.c\n+++ b/builtin/fetch.c\n@@ -30,10 +30,12 @@ enum {\n };\n \n static int fetch_prune_config = -1; /* unspecified */\n+static int fetch_all_config = -1; /* unspecified */\n static int prune = -1; /* unspecified */\n+static int all = -1; /* unspecified */\n #define PRUNE_BY_DEFAULT 0 /* do we prune by default? */\n \n-static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity;\n+static int append, dry_run, force, keep, multiple, update_head_ok, verbosity;\n static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;\n static int tags = TAGS_DEFAULT, unshallow, update_shallow;\n static const char *depth;\n@@ -67,6 +69,10 @@ static int git_fetch_config(const char *k, const char *v, void *cb)\n \t\tfetch_prune_config = git_config_bool(k, v);\n \t\treturn 0;\n \t}\n+\tif (!strcmp(k, \"fetch.all\")) {\n+\t\tfetch_all_config = git_config_bool(k, v);\n+\t\treturn 0;\n+\t}\n \treturn git_default_config(k, v, cb);\n }\n \n@@ -1168,7 +1174,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n \t\tgit_config(submodule_config, NULL);\n \t}\n \n-\tif (all) {\n+\tif (all == 1) {\n \t\tif (argc == 1)\n \t\t\tdie(_(\"fetch --all does not take a repository argument\"));\n \t\telse if (argc > 1)\n@@ -1176,9 +1182,14 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n \t\t(void) for_each_remote(get_one_remote_for_fetch, &list);\n \t\tresult = fetch_multiple(&list);\n \t} else if (argc == 0) {\n-\t\t/* No arguments -- use default remote */\n-\t\tremote = remote_get(NULL);\n-\t\tresult = fetch_one(remote, argc, argv);\n+\t\tif (fetch_all_config && all != 0) {\n+\t\t\t(void) for_each_remote(get_one_remote_for_fetch, &list);\n+\t\t\tresult = fetch_multiple(&list);\n+\t\t} else {\n+\t\t\t/* No arguments and no --all -- use default remote */\n+\t\t\tremote = remote_get(NULL);\n+\t\t\tresult = fetch_one(remote, argc, argv);\n+\t\t}\n \t} else if (multiple) {\n \t\t/* All arguments are assumed to be remotes or groups */\n \t\tfor (i = 0; i < argc; i++)\ndiff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh\nindex 4b4b667..4e773ee 100755\n--- a/t/t5514-fetch-multiple.sh\n+++ b/t/t5514-fetch-multiple.sh\n@@ -55,6 +55,18 @@ test_expect_success 'git fetch --all' '\n \t test_cmp expect output)\n '\n \n+test_expect_success 'git fetch (fetch.all = true)' '\n+\t(git clone one test9 &&\n+\t cd test9 &&\n+\t git config fetch.all true &&\n+\t git remote add one ../one &&\n+\t git remote add two ../two &&\n+\t git remote add three ../three &&\n+\t git fetch &&\n+\t git branch -r > output &&\n+\t test_cmp ../test/expect output)\n+'\n+\n test_expect_success 'git fetch --all should continue if a remote has errors' '\n \t(git clone one test2 &&\n \t cd test2 &&\n@@ -91,6 +103,17 @@ test_expect_success 'git fetch --multiple (but only one remote)' '\n \t test_cmp ../expect output)\n '\n \n+test_expect_success 'git fetch one (fetch.all = true)' '\n+\t(cd test3 &&\n+\t git config fetch.all true &&\n+\t git fetch three &&\n+\t git branch -r > output &&\n+\t test_cmp ../expect output &&\n+\t git fetch --no-all &&\n+\t git branch -r > output &&\n+\t test_cmp ../expect output)\n+'\n+\n cat > expect << EOF\n   one/master\n   one/side\n-- \n2.2.0\n"},{"id":"266239","messageId":"1674906250.515624.1437145366822.JavaMail.zimbra@ensimag.grenoble-inp.fr","threadId":"39871","inReplyTo":"1437139899-6210-1-git-send-email-oystwa@gmail.com","subject":"Re: [PATCH] fetch: add configuration for making --all default","fromName":"Remi Galan Alfonso","fromEmail":"remi.galan-alfonso@ensimag.grenoble-inp.fr","sentAt":"2015-07-17T15:02:46Z","receivedAt":"2015-07-17T15:02:46Z","isPatch":true,"sender":{"key":"remi.galan-alfonso@ensimag.grenoble-inp.fr","avatar":"https://avatars.githubusercontent.com/u/12509162?v=4"},"body":"Hi,\n\nØystein Walle <oystwa@gmail.com> writes:\n> +fetch.all::\n> +        If true, fetch will automatically behave as if the `--all`\n> +        option was given on the command line uness a remote was given. The\n> +        default is false.\n\ns/uness/unless\n\n> +test_expect_success 'git fetch (fetch.all = true)' '\n> +        (git clone one test9 &&\n> +         cd test9 &&\n> +         git config fetch.all true &&\n> +         git remote add one ../one &&\n> +         git remote add two ../two &&\n> +         git remote add three ../three &&\n> +         git fetch &&\n> +         git branch -r > output &&\n\nNo space after redirection ('>').\nIt should be:\n         git branch -r >output &&\n\n> +test_expect_success 'git fetch one (fetch.all = true)' '\n> +        (cd test3 &&\n> +         git config fetch.all true &&\n> +         git fetch three &&\n> +         git branch -r > output &&\n\nSame here\n\n> +         test_cmp ../expect output &&\n> +         git fetch --no-all &&\n> +         git branch -r > output &&\n\nAnd here.\n\n> +         test_cmp ../expect output)\n> +'\n\nThanks,\nRémi\n"},{"id":"266243","messageId":"xmqqk2ty3gxj.fsf@gitster.dls.corp.google.com","threadId":"39871","inReplyTo":"1437139899-6210-1-git-send-email-oystwa@gmail.com","subject":"Re: [PATCH] fetch: add configuration for making --all default","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-07-17T16:08:40Z","receivedAt":"2015-07-17T16:08:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Øystein Walle <oystwa@gmail.com> writes:\n\n> Fetching from all remotes by default is useful if you're working on a\n> repo with few and/or fast remotes.\n\nThat part is sensible.\n\n> It also lets you fetch from origin\n> even if the current branch's upstream is elsewhere without specifying it\n> explicitly.\n\nI do not think this description is necessary or even beneficial.\nThe users can already do that with 'fetch --all', so there is\nno value added by having a new configuration.\n\nThe only thing a new configuration gives the users is a convenience\nof not having to say `--all` from the command line.\n\n> diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt\n> index e62d9a0..584f3fb 100644\n> --- a/Documentation/git-fetch.txt\n> +++ b/Documentation/git-fetch.txt\n> @@ -36,7 +36,8 @@ there is a remotes.<group> entry in the configuration file.\n>  (See linkgit:git-config[1]).\n>  \n>  When no remote is specified, by default the `origin` remote will be used,\n> -unless there's an upstream branch configured for the current branch.\n> +unless there's an upstream branch configured for the current branch, or the\n> +`fetch.all` configuration variable is set to true.\n\nThis sounds a bit strange.  Other places talk about fetch.all being\nthe same as giving `--all`, but neither the original description nor\nthe resulting text with this patch says anything about what would\nhappen 'when no remote is given but the --all option is given', which\nmakes it sound as if fetch.all and `--all` behave differently here.\n\n> diff --git a/builtin/fetch.c b/builtin/fetch.c\n> ...\n> @@ -1168,7 +1174,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n>  \t\tgit_config(submodule_config, NULL);\n>  \t}\n>  \n> -\tif (all) {\n> +\tif (all == 1) {\n>  \t\tif (argc == 1)\n>  \t\t\tdie(_(\"fetch --all does not take a repository argument\"));\n>  \t\telse if (argc > 1)\n> @@ -1176,9 +1182,14 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n>  \t\t(void) for_each_remote(get_one_remote_for_fetch, &list);\n>  \t\tresult = fetch_multiple(&list);\n>  \t} else if (argc == 0) {\n> -\t\t/* No arguments -- use default remote */\n> -\t\tremote = remote_get(NULL);\n> -\t\tresult = fetch_one(remote, argc, argv);\n> +\t\tif (fetch_all_config && all != 0) {\n> +\t\t\t(void) for_each_remote(get_one_remote_for_fetch, &list);\n> +\t\t\tresult = fetch_multiple(&list);\n\nCan't you rearrange if/else cascade around here, so that these two\nlines do not have to be duplicated?\n\n> +\t\t} else {\n> +\t\t\t/* No arguments and no --all -- use default remote */\n> +\t\t\tremote = remote_get(NULL);\n> +\t\t\tresult = fetch_one(remote, argc, argv);\n> +\t\t}\n>  \t} else if (multiple) {\n>  \t\t/* All arguments are assumed to be remotes or groups */\n>  \t\tfor (i = 0; i < argc; i++)\n> diff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh\n> index 4b4b667..4e773ee 100755\n> --- a/t/t5514-fetch-multiple.sh\n> +++ b/t/t5514-fetch-multiple.sh\n> @@ -55,6 +55,18 @@ test_expect_success 'git fetch --all' '\n>  \t test_cmp expect output)\n>  '\n>  \n> +test_expect_success 'git fetch (fetch.all = true)' '\n> +\t(git clone one test9 &&\n> +\t cd test9 &&\n> +\t git config fetch.all true &&\n> +\t git remote add one ../one &&\n> +\t git remote add two ../two &&\n> +\t git remote add three ../three &&\n> +\t git fetch &&\n> +\t git branch -r > output &&\n> +\t test_cmp ../test/expect output)\n> +'\n> +\n>  test_expect_success 'git fetch --all should continue if a remote has errors' '\n>  \t(git clone one test2 &&\n>  \t cd test2 &&\n> @@ -91,6 +103,17 @@ test_expect_success 'git fetch --multiple (but only one remote)' '\n>  \t test_cmp ../expect output)\n>  '\n>  \n> +test_expect_success 'git fetch one (fetch.all = true)' '\n> +\t(cd test3 &&\n\nThis means that this test piece will break if the previous one did\nnot succeed, which is not a very good idea.\n\n> +\t git config fetch.all true &&\n> +\t git fetch three &&\n> +\t git branch -r > output &&\n> +\t test_cmp ../expect output &&\n\nWhat future errors will this catch?\n\nYou have only \"three\" and \"origin\" and the expected output wants to\nsee tracking from both.  Does the test break when in some future\nsomebody broke the resulting code after applying this patch in such\na way that \"fetch from only 'three'\" from the command line gets\nignored and fetch.all went ahead and fetched from everybody?\n\n> +\t git fetch --no-all &&\n> +\t git branch -r > output &&\n> +\t test_cmp ../expect output)\n\nSame question.\n\n> +'\n> +\n>  cat > expect << EOF\n>    one/master\n>    one/side\n"},{"id":"266244","messageId":"1437149692-10154-1-git-send-email-oystwa@gmail.com","threadId":"39871","inReplyTo":"1674906250.515624.1437145366822.JavaMail.zimbra@ensimag.grenoble-inp.fr","subject":"[PATCH v2] fetch: add configuration for making --all default","fromName":"Øystein Walle","fromEmail":"oystwa@gmail.com","sentAt":"2015-07-17T16:14:52Z","receivedAt":"2015-07-17T16:14:52Z","isPatch":true,"sender":{"key":"oystwa@gmail.com","avatar":"https://avatars.githubusercontent.com/u/794585?v=4"},"body":"Fetching from all remotes by default is useful if you're working on a\nrepo with few and/or fast remotes. It also lets you fetch from origin\neven if the current branch's upstream is elsewhere without specifying it\nexplicitly.\n\nSigned-off-by: Øystein Walle <oystwa@gmail.com>\n---\nThanks for the quick feedback, Remi. There's a fixed version.\n\n Documentation/config.txt        |  5 +++++\n Documentation/fetch-options.txt |  4 +++-\n Documentation/git-fetch.txt     |  3 ++-\n builtin/fetch.c                 | 21 ++++++++++++++++-----\n t/t5514-fetch-multiple.sh       | 23 +++++++++++++++++++++++\n 5 files changed, 49 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 3e37b93..997a8d9 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1170,6 +1170,11 @@ fetch.prune::\n \tIf true, fetch will automatically behave as if the `--prune`\n \toption was given on the command line.  See also `remote.<name>.prune`.\n \n+fetch.all::\n+\tIf true, fetch will automatically behave as if the `--all`\n+\toption was given on the command line unless a remote was given. The\n+\tdefault is false.\n+\n format.attach::\n \tEnable multipart/mixed attachments as the default for\n \t'format-patch'.  The value can also be a double quoted string\ndiff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt\nindex 45583d8..aa95a30 100644\n--- a/Documentation/fetch-options.txt\n+++ b/Documentation/fetch-options.txt\n@@ -1,5 +1,7 @@\n --all::\n-\tFetch all remotes.\n+\tFetch all remotes. This can be configured to be the default behaviour\n+\twhen no remotes are given explicitly. See the `fetch.all` configuration\n+\tvariable in linkgit:git-config[1].\n \n -a::\n --append::\ndiff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt\nindex e62d9a0..584f3fb 100644\n--- a/Documentation/git-fetch.txt\n+++ b/Documentation/git-fetch.txt\n@@ -36,7 +36,8 @@ there is a remotes.<group> entry in the configuration file.\n (See linkgit:git-config[1]).\n \n When no remote is specified, by default the `origin` remote will be used,\n-unless there's an upstream branch configured for the current branch.\n+unless there's an upstream branch configured for the current branch, or the\n+`fetch.all` configuration variable is set to true.\n \n The names of refs that are fetched, together with the object names\n they point at, are written to `.git/FETCH_HEAD`.  This information\ndiff --git a/builtin/fetch.c b/builtin/fetch.c\nindex 8d5b2db..715ea82 100644\n--- a/builtin/fetch.c\n+++ b/builtin/fetch.c\n@@ -30,10 +30,12 @@ enum {\n };\n \n static int fetch_prune_config = -1; /* unspecified */\n+static int fetch_all_config = -1; /* unspecified */\n static int prune = -1; /* unspecified */\n+static int all = -1; /* unspecified */\n #define PRUNE_BY_DEFAULT 0 /* do we prune by default? */\n \n-static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity;\n+static int append, dry_run, force, keep, multiple, update_head_ok, verbosity;\n static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;\n static int tags = TAGS_DEFAULT, unshallow, update_shallow;\n static const char *depth;\n@@ -67,6 +69,10 @@ static int git_fetch_config(const char *k, const char *v, void *cb)\n \t\tfetch_prune_config = git_config_bool(k, v);\n \t\treturn 0;\n \t}\n+\tif (!strcmp(k, \"fetch.all\")) {\n+\t\tfetch_all_config = git_config_bool(k, v);\n+\t\treturn 0;\n+\t}\n \treturn git_default_config(k, v, cb);\n }\n \n@@ -1168,7 +1174,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n \t\tgit_config(submodule_config, NULL);\n \t}\n \n-\tif (all) {\n+\tif (all == 1) {\n \t\tif (argc == 1)\n \t\t\tdie(_(\"fetch --all does not take a repository argument\"));\n \t\telse if (argc > 1)\n@@ -1176,9 +1182,14 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n \t\t(void) for_each_remote(get_one_remote_for_fetch, &list);\n \t\tresult = fetch_multiple(&list);\n \t} else if (argc == 0) {\n-\t\t/* No arguments -- use default remote */\n-\t\tremote = remote_get(NULL);\n-\t\tresult = fetch_one(remote, argc, argv);\n+\t\tif (fetch_all_config && all != 0) {\n+\t\t\t(void) for_each_remote(get_one_remote_for_fetch, &list);\n+\t\t\tresult = fetch_multiple(&list);\n+\t\t} else {\n+\t\t\t/* No arguments and no --all -- use default remote */\n+\t\t\tremote = remote_get(NULL);\n+\t\t\tresult = fetch_one(remote, argc, argv);\n+\t\t}\n \t} else if (multiple) {\n \t\t/* All arguments are assumed to be remotes or groups */\n \t\tfor (i = 0; i < argc; i++)\ndiff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh\nindex 4b4b667..e0fb744 100755\n--- a/t/t5514-fetch-multiple.sh\n+++ b/t/t5514-fetch-multiple.sh\n@@ -55,6 +55,18 @@ test_expect_success 'git fetch --all' '\n \t test_cmp expect output)\n '\n \n+test_expect_success 'git fetch (fetch.all = true)' '\n+\t(git clone one test9 &&\n+\t cd test9 &&\n+\t git config fetch.all true &&\n+\t git remote add one ../one &&\n+\t git remote add two ../two &&\n+\t git remote add three ../three &&\n+\t git fetch &&\n+\t git branch -r >output &&\n+\t test_cmp ../test/expect output)\n+'\n+\n test_expect_success 'git fetch --all should continue if a remote has errors' '\n \t(git clone one test2 &&\n \t cd test2 &&\n@@ -91,6 +103,17 @@ test_expect_success 'git fetch --multiple (but only one remote)' '\n \t test_cmp ../expect output)\n '\n \n+test_expect_success 'git fetch one (fetch.all = true)' '\n+\t(cd test3 &&\n+\t git config fetch.all true &&\n+\t git fetch three &&\n+\t git branch -r >output &&\n+\t test_cmp ../expect output &&\n+\t git fetch --no-all &&\n+\t git branch -r >output &&\n+\t test_cmp ../expect output)\n+'\n+\n cat > expect << EOF\n   one/master\n   one/side\n-- \n2.2.0\n"}]}