{"thread":{"id":"38010","subject":"[RFC] [PATCH] remote: add new --fetch option for set-url","startedAt":"2014-11-19T15:18:02Z","lastAt":"2014-12-02T23:50:44Z","messageCount":27,"participants":["Peter Wu","Jeff King","Junio C Hamano","Philip Oakley"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"252183","messageId":"6997784.RuzRO1AFsK@al","threadId":"38010","inReplyTo":null,"subject":"[RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Peter Wu","fromEmail":"peter@lekensteyn.nl","sentAt":"2014-11-19T15:18:02Z","receivedAt":"2014-11-19T15:18:02Z","isPatch":true,"sender":{"key":"peter@lekensteyn.nl","avatar":"https://gravatar.com/avatar/efcf30db53f30b15e7c905ef37bd4dc44d87573bd92baf97cd707115d3fcd0c0?d=mp&s=160"},"body":"git remote set-url knew about the '--push' option to update just the\npushurl, but it does not have a similar option for \"update fetch URL and\nleave whatever was in place for the push URL\".\n\nThis patch adds support for a '--fetch' option which implements that use\ncase in a backwards compatible way: if neither --push nor --fetch are\ngiven, then the push URL is modified too if it was not set before. This\nis the case since the push URL is implicitly based on the fetch URL.\n\nThe documentation has also been updated and a missing '--push' option\nis added to the 'git remote -h' command.\n\nTests are also added to verify the documented behavior.\n\nSigned-off-by: Peter Wu <peter@lekensteyn.nl>\n---\n(please cc me, I am not subscribed)\n\nHi,\n\nNow and then I hit this issue where I want to change the remote where\nsources are fetched from without having to touch the push URL. Example:\n\n    git remote add gh git@github.com:Lekensteyn/git.git\n    # Avoid needing SSH for pulling from a repo, so change fetch URL\n    git remote set-url https://github.com/Lekensteyn/git.git\n    # Hmm, the fetch URL got changed too, let's fix that.\n    git remote add --push gh git@github.com:Lekensteyn/git.git\n\nAfter this patch, I can use:\n\n    git remote add gh git@github.com:Lekensteyn/git.git\n    git remote set-url --fetch https://github.com/Lekensteyn/git.git\n\nrather than being forced into a specific order:\n\n    git remote add gh https://github.com/Lekensteyn/git.git\n    git remote set-url --push gh git@github.com:Lekensteyn/git.git\n\nThe functionality is implemented, but it might need a refactoring to\nreduce duplicate code. Translation strings also need to be updated (the\ncurrent 'git remote set-url' strings are also not up to date).\n\nKind regards.\nPeter\n---\n Documentation/git-remote.txt |  12 +++--\n builtin/remote.c             | 106 +++++++++++++++++++++++++++++--------------\n t/t5505-remote.sh            |  53 ++++++++++++++++++++++\n 3 files changed, 133 insertions(+), 38 deletions(-)\n\ndiff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt\nindex cb103c8..7bb21a2 100644\n--- a/Documentation/git-remote.txt\n+++ b/Documentation/git-remote.txt\n@@ -15,9 +15,9 @@ SYNOPSIS\n 'git remote remove' <name>\n 'git remote set-head' <name> (-a | --auto | -d | --delete | <branch>)\n 'git remote set-branches' [--add] <name> <branch>...\n-'git remote set-url' [--push] <name> <newurl> [<oldurl>]\n-'git remote set-url --add' [--push] <name> <newurl>\n-'git remote set-url --delete' [--push] <name> <url>\n+'git remote set-url' [--fetch] [--push] <name> <newurl> [<oldurl>]\n+'git remote set-url' [--fetch] [--push] '--add' <name> <newurl>\n+'git remote set-url' [--fetch] [--push] '--delete' <name> <url>\n 'git remote' [-v | --verbose] 'show' [-n] <name>...\n 'git remote prune' [-n | --dry-run] <name>...\n 'git remote' [-v | --verbose] 'update' [-p | --prune] [(<group> | <remote>)...]\n@@ -134,7 +134,11 @@ Changes URL remote points to. Sets first URL remote points to matching\n regex <oldurl> (first URL if no <oldurl> is given) to <newurl>. If\n <oldurl> doesn't match any URL, error occurs and nothing is changed.\n +\n-With '--push', push URLs are manipulated instead of fetch URLs.\n+With '--push', push URLs are manipulated.\n++\n+With '--fetch', fetch URLs are manipulated. If neither '--push' nor '--fetch'\n+are given, then (1) '--fetch' is assumed if no push URL is set in the\n+configuration or (2) '--fetch --push' otherwise.\n +\n With '--add', instead of changing some URL, new URL is added.\n +\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 7f28f92..26caa6f 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -18,9 +18,9 @@ static const char * const builtin_remote_usage[] = {\n \tN_(\"git remote prune [-n | --dry-run] <name>\"),\n \tN_(\"git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]\"),\n \tN_(\"git remote set-branches [--add] <name> <branch>...\"),\n-\tN_(\"git remote set-url [--push] <name> <newurl> [<oldurl>]\"),\n-\tN_(\"git remote set-url --add <name> <newurl>\"),\n-\tN_(\"git remote set-url --delete <name> <url>\"),\n+\tN_(\"git remote set-url [--fetch] [--push] <name> <newurl> [<oldurl>]\"),\n+\tN_(\"git remote set-url [--fetch] [--push] --add <name> <newurl>\"),\n+\tN_(\"git remote set-url [--fetch] [--push] --delete <name> <url>\"),\n \tNULL\n };\n \n@@ -66,9 +66,9 @@ static const char * const builtin_remote_update_usage[] = {\n };\n \n static const char * const builtin_remote_seturl_usage[] = {\n-\tN_(\"git remote set-url [--push] <name> <newurl> [<oldurl>]\"),\n-\tN_(\"git remote set-url --add <name> <newurl>\"),\n-\tN_(\"git remote set-url --delete <name> <url>\"),\n+\tN_(\"git remote set-url [--fetch] [--push] <name> <newurl> [<oldurl>]\"),\n+\tN_(\"git remote set-url [--fetch] [--push] --add <name> <newurl>\"),\n+\tN_(\"git remote set-url [--fetch] [--push] --delete <name> <url>\"),\n \tNULL\n };\n \n@@ -1505,18 +1505,19 @@ static int set_branches(int argc, const char **argv)\n \n static int set_url(int argc, const char **argv)\n {\n-\tint i, push_mode = 0, add_mode = 0, delete_mode = 0;\n+\tint i, fetch_only = 0, push_only = 0, add_mode = 0, delete_mode = 0;\n \tint matches = 0, negative_matches = 0;\n \tconst char *remotename = NULL;\n \tconst char *newurl = NULL;\n \tconst char *oldurl = NULL;\n \tstruct remote *remote;\n \tregex_t old_regex;\n-\tconst char **urlset;\n-\tint urlset_nr;\n-\tstruct strbuf name_buf = STRBUF_INIT;\n+\tstruct strbuf name_buf_fetch = STRBUF_INIT;\n+\tstruct strbuf name_buf_push = STRBUF_INIT;\n \tstruct option options[] = {\n-\t\tOPT_BOOL('\\0', \"push\", &push_mode,\n+\t\tOPT_BOOL('\\0', \"fetch\", &fetch_only,\n+\t\t\t N_(\"manipulate fetch URLs\")),\n+\t\tOPT_BOOL('\\0', \"push\", &push_only,\n \t\t\t N_(\"manipulate push URLs\")),\n \t\tOPT_BOOL('\\0', \"add\", &add_mode,\n \t\t\t N_(\"add URL\")),\n@@ -1545,24 +1546,39 @@ static int set_url(int argc, const char **argv)\n \t\tdie(_(\"No such remote '%s'\"), remotename);\n \tremote = remote_get(remotename);\n \n-\tif (push_mode) {\n-\t\tstrbuf_addf(&name_buf, \"remote.%s.pushurl\", remotename);\n-\t\turlset = remote->pushurl;\n-\t\turlset_nr = remote->pushurl_nr;\n-\t} else {\n-\t\tstrbuf_addf(&name_buf, \"remote.%s.url\", remotename);\n-\t\turlset = remote->url;\n-\t\turlset_nr = remote->url_nr;\n-\t}\n+\tstrbuf_addf(&name_buf_fetch, \"remote.%s.url\", remotename);\n+\tstrbuf_addf(&name_buf_push, \"remote.%s.pushurl\", remotename);\n+\n+\t/* Backwards compatibility: do not copy fetch URL to push URL if push\n+\t * URL is unset and --fetch and --push re missing */\n+\tif (!fetch_only && !push_only)\n+\t\tfetch_only = -1;\n \n \t/* Special cases that add new entry. */\n \tif ((!oldurl && !delete_mode) || add_mode) {\n-\t\tif (add_mode)\n-\t\t\tgit_config_set_multivar(name_buf.buf, newurl,\n-\t\t\t\t\"^$\", 0);\n-\t\telse\n-\t\t\tgit_config_set(name_buf.buf, newurl);\n-\t\tstrbuf_release(&name_buf);\n+\t\t/* If --fetch was explicitly given, then ensure that the value\n+\t\t * of push URL does not change by copying the fetch URL. */\n+\t\tif (fetch_only == 1 && !push_only &&\n+\t\t\t\tremote->pushurl_nr == 0 && remote->url_nr > 0)\n+\t\t\tfor (i = 0; i < remote->url_nr; i++)\n+\t\t\t\tgit_config_set_multivar(name_buf_push.buf,\n+\t\t\t\t\tremote->url[i], \"^$\", 0);\n+\n+\t\tif (add_mode) {\n+\t\t\tif (fetch_only)\n+\t\t\t\tgit_config_set_multivar(name_buf_fetch.buf,\n+\t\t\t\t\tnewurl, \"^$\", 0);\n+\t\t\tif (push_only)\n+\t\t\t\tgit_config_set_multivar(name_buf_push.buf,\n+\t\t\t\t\tnewurl, \"^$\", 0);\n+\t\t} else {\n+\t\t\tif (fetch_only)\n+\t\t\t\tgit_config_set(name_buf_fetch.buf, newurl);\n+\t\t\tif (push_only)\n+\t\t\t\tgit_config_set(name_buf_push.buf, newurl);\n+\t\t}\n+\t\tstrbuf_release(&name_buf_fetch);\n+\t\tstrbuf_release(&name_buf_push);\n \t\treturn 0;\n \t}\n \n@@ -1570,22 +1586,44 @@ static int set_url(int argc, const char **argv)\n \tif (regcomp(&old_regex, oldurl, REG_EXTENDED))\n \t\tdie(_(\"Invalid old URL pattern: %s\"), oldurl);\n \n-\tfor (i = 0; i < urlset_nr; i++)\n-\t\tif (!regexec(&old_regex, urlset[i], 0, NULL, 0))\n+\tfor (i = 0; fetch_only && i < remote->url_nr; i++)\n+\t\tif (!regexec(&old_regex, remote->url[i], 0, NULL, 0))\n+\t\t\tmatches++;\n+\t\telse\n+\t\t\tnegative_matches++;\n+\tif (delete_mode && !negative_matches && fetch_only)\n+\t\tdie(_(\"Will not delete all non-push URLs\"));\n+\tfor (i = 0; push_only && i < remote->pushurl_nr; i++)\n+\t\tif (!regexec(&old_regex, remote->pushurl[i], 0, NULL, 0))\n \t\t\tmatches++;\n \t\telse\n \t\t\tnegative_matches++;\n \tif (!delete_mode && !matches)\n \t\tdie(_(\"No such URL found: %s\"), oldurl);\n-\tif (delete_mode && !negative_matches && !push_mode)\n-\t\tdie(_(\"Will not delete all non-push URLs\"));\n \n \tregfree(&old_regex);\n \n-\tif (!delete_mode)\n-\t\tgit_config_set_multivar(name_buf.buf, newurl, oldurl, 0);\n-\telse\n-\t\tgit_config_set_multivar(name_buf.buf, NULL, oldurl, 1);\n+\t/* If --fetch was explicitly given, then ensure that the value\n+\t * of push URL does not change by copying the fetch URL. */\n+\tif (fetch_only == 1 && !push_only &&\n+\t\t\tremote->pushurl_nr == 0 && remote->url_nr > 0)\n+\t\tfor (i = 0; i < remote->url_nr; i++)\n+\t\t\tgit_config_set_multivar(name_buf_push.buf,\n+\t\t\t\tremote->url[i], \"^$\", 0);\n+\n+\tif (!delete_mode) {\n+\t\tif (fetch_only)\n+\t\t\tgit_config_set_multivar(name_buf_fetch.buf, newurl, oldurl, 0);\n+\t\tif (push_only)\n+\t\t\tgit_config_set_multivar(name_buf_push.buf, newurl, oldurl, 0);\n+\t} else {\n+\t\tif (fetch_only)\n+\t\t\tgit_config_set_multivar(name_buf_fetch.buf, NULL, oldurl, 1);\n+\t\tif (push_only)\n+\t\t\tgit_config_set_multivar(name_buf_push.buf, NULL, oldurl, 1);\n+\t}\n+\tstrbuf_release(&name_buf_fetch);\n+\tstrbuf_release(&name_buf_push);\n \treturn 0;\n }\n \ndiff --git a/t/t5505-remote.sh b/t/t5505-remote.sh\nindex ac79dd9..a00e1cb 100755\n--- a/t/t5505-remote.sh\n+++ b/t/t5505-remote.sh\n@@ -961,6 +961,59 @@ test_expect_success 'remote set-url --push zot' '\n \tcmp expect actual\n '\n \n+test_expect_success 'remote set-url --fetch zox' '\n+\tgit remote set-url --fetch someremote zox &&\n+\techo zox >expect &&\n+\techo \"YYY\" >>expect &&\n+\techo zot >>expect &&\n+\tgit config --get-all remote.someremote.url >actual &&\n+\techo \"YYY\" >>actual &&\n+\tgit config --get-all remote.someremote.pushurl >>actual &&\n+\tcmp expect actual\n+'\n+\n+test_expect_success 'remote set-url --fetch --push foo' '\n+\tgit remote set-url --fetch --push someremote foo &&\n+\techo foo >expect &&\n+\techo \"YYY\" >>expect &&\n+\techo foo >>expect &&\n+\tgit config --get-all remote.someremote.pushurl >actual &&\n+\techo \"YYY\" >>actual &&\n+\tgit config --get-all remote.someremote.url >>actual &&\n+\tcmp expect actual\n+'\n+\n+test_expect_success 'remote set-url --delete --push foo' '\n+\tgit remote set-url --delete --push someremote foo &&\n+\techo \"YYY\" >expect &&\n+\techo foo >>expect &&\n+\ttest_must_fail git config --get-all remote.someremote.pushurl >actual &&\n+\techo \"YYY\" >actual &&\n+\tgit config --get-all remote.someremote.url >>actual &&\n+\tcmp expect actual\n+'\n+\n+test_expect_success 'remote set-url zot foo' '\n+\tgit remote set-url someremote zot foo &&\n+\techo \"YYY\" >expect &&\n+\techo zot >>expect &&\n+\ttest_must_fail git config --get-all remote.someremote.pushurl >actual &&\n+\techo \"YYY\" >>actual &&\n+\tgit config --get-all remote.someremote.url >>actual &&\n+\tcmp expect actual\n+'\n+\n+test_expect_success 'remote set-url --push baz' '\n+\tgit remote set-url --push someremote baz &&\n+\techo baz >expect &&\n+\techo \"YYY\" >>expect &&\n+\techo zot >>expect &&\n+\tgit config --get-all remote.someremote.pushurl >actual &&\n+\techo \"YYY\" >>actual &&\n+\tgit config --get-all remote.someremote.url >>actual &&\n+\tcmp expect actual\n+'\n+\n test_expect_success 'remote set-url --push qux zot' '\n \tgit remote set-url --push someremote qux zot &&\n \techo qux >expect &&\n-- \n2.1.2\n"},{"id":"252196","messageId":"20141119190800.GB9908@peff.net","threadId":"38010","inReplyTo":"6997784.RuzRO1AFsK@al","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-11-19T19:08:00Z","receivedAt":"2014-11-19T19:08:00Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Nov 19, 2014 at 04:18:02PM +0100, Peter Wu wrote:\n\n> git remote set-url knew about the '--push' option to update just the\n> pushurl, but it does not have a similar option for \"update fetch URL and\n> leave whatever was in place for the push URL\".\n\nIsn't that what:\n\n  git remote set-url foo new-fetch-url\n\ndoes already? It affects only the \"url\" setting, which is the de-facto\nfetch setting (it is _also_ the push setting if there is no pushurl\ndefined).\n\nYou gave this example:\n\n>     git remote add gh git@github.com:Lekensteyn/git.git\n>     # Avoid needing SSH for pulling from a repo, so change fetch URL\n>     git remote set-url https://github.com/Lekensteyn/git.git\n>     # Hmm, the fetch URL got changed too, let's fix that.\n>     git remote add --push gh git@github.com:Lekensteyn/git.git\n\nBut here you do not have a pushurl defined in the first place. So I\nguess this is really just a shortcut for swapping the two, like:\n\n  git remote set-url --push gh $(git config remote.gh.url)\n  git remote set-url gh new-fetch-url\n\nI dunno. I guess that is more convenient, but it seems like a lot of\ncode for a very marginal use case. But more importantly, I'm a little\nworried that the presence of --fetch creates confusion about what\nset-url without a --fetch or --push does. That is, it implies to me\nthat:\n\n  git remote add gh old-url\n  git remote set-url gh --push push-url\n  git remote set-url gh new-url\n\nwould replace both the \"url\" _and_ \"pushurl\" values in the third step,\nsince we did not specify --fetch.  But it is in fact identical whether\nyou run it with \"--fetch\" or not.  That is, it creates a weirdly\nnon-orthogonal interface.\n\n-Peff\n"},{"id":"252198","messageId":"1456931.yaNzKr1t0X@al","threadId":"38010","inReplyTo":"20141119190800.GB9908@peff.net","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Peter Wu","fromEmail":"peter@lekensteyn.nl","sentAt":"2014-11-19T19:42:19Z","receivedAt":"2014-11-19T19:42:19Z","isPatch":true,"sender":{"key":"peter@lekensteyn.nl","avatar":"https://gravatar.com/avatar/efcf30db53f30b15e7c905ef37bd4dc44d87573bd92baf97cd707115d3fcd0c0?d=mp&s=160"},"body":"On Wednesday 19 November 2014 14:08:00 Jeff King wrote:\n> On Wed, Nov 19, 2014 at 04:18:02PM +0100, Peter Wu wrote:\n> \n> > git remote set-url knew about the '--push' option to update just the\n> > pushurl, but it does not have a similar option for \"update fetch URL and\n> > leave whatever was in place for the push URL\".\n> \n> Isn't that what:\n> \n>   git remote set-url foo new-fetch-url\n> \n> does already? It affects only the \"url\" setting, which is the de-facto\n> fetch setting (it is _also_ the push setting if there is no pushurl\n> defined).\n\nIf pushurl is not set, then this will implicitly change the fetch URL\nwhich is unwanted and fixed in this patch by introducing a --fetch\noption.\n\n> You gave this example:\n> \n> >     git remote add gh git@github.com:Lekensteyn/git.git\n> >     # Avoid needing SSH for pulling from a repo, so change fetch URL\n> >     git remote set-url https://github.com/Lekensteyn/git.git\n> >     # Hmm, the fetch URL got changed too, let's fix that.\n> >     git remote add --push gh git@github.com:Lekensteyn/git.git\n> \n> But here you do not have a pushurl defined in the first place. So I\n> guess this is really just a shortcut for swapping the two, like:\n> \n>   git remote set-url --push gh $(git config remote.gh.url)\n>   git remote set-url gh new-fetch-url\n\nIndeed, and not having a push URL is not uncommon (that is, always the\ncase when a new remote is added or just cloned). Compare the above\nagainst this one:\n\n    git remote set-url --fetch new-fetch-url\n\nThis is less verbose and is much more intuitive.\n\n> I dunno. I guess that is more convenient, but it seems like a lot of\n> code for a very marginal use case. But more importantly, I'm a little\n> worried that the presence of --fetch creates confusion about what\n> set-url without a --fetch or --push does. That is, it implies to me\n> that:\n> \n>   git remote add gh old-url\n>   git remote set-url gh --push push-url\n>   git remote set-url gh new-url\n> \n> would replace both the \"url\" _and_ \"pushurl\" values in the third step,\n> since we did not specify --fetch.  But it is in fact identical whether\n> you run it with \"--fetch\" or not.  That is, it creates a weirdly\n> non-orthogonal interface.\n\nStep three currently only replaces the fetch URL as an explicit push URL\n(remote.gh.pushurl) is set in step two (and therefore remote.gh.url does\nnot become the implicit push URL).\n\nThis might be a bug, but since it has been so long this way I was\nworried that people actually rely on this behavior. The following sets\nboth url and pushurl (even if the URLs are equal):\n\n    git remote set-url --push --fetch gh pushurl\n\nThe patch is not tiny, but also not overly large either even if it has\nsimilar pieces of code duplicated. Care has been taken of to keep\nbackwards compatibility which has also increased the size.\n\nBy the way, in the old code there was a memleak as strbuf was not\nreleased at the end of the function, isn't it? A new patch can be found\non the bottom, it fixes an issue in the tests (no change in other\nparts).\n-- \nKind regards,\nPeter\nhttps://lekensteyn.nl\n\n\n>From 6be164f68b4f625ac90f998ae4073e031ebed8ba Mon Sep 17 00:00:00 2001\nFrom: Peter Wu <peter@lekensteyn.nl>\nDate: Wed, 19 Nov 2014 15:57:40 +0100\nSubject: [PATCHv2] remote: add new --fetch option for set-url\n\ngit remote set-url knew about the '--push' option to update just the\npushurl, but it does not have a similar option for \"update fetch URL and\nleave whatever was in place for the push URL\".\n\nThis patch adds support for a '--fetch' option which implements that use\ncase in a backwards compatible way: if neither --push nor --fetch are\ngiven, then the push URL is modified too if it was not set before. This\nis the case since the push URL is implicitly based on the fetch URL.\n\nThe documentation has also been updated and a missing '--push' option\nis added to the 'git remote -h' command.\n\nTests are also added to verify the documented behavior.\n\nSigned-off-by: Peter Wu <peter@lekensteyn.nl>\n---\n Documentation/git-remote.txt |  12 +++--\n builtin/remote.c             | 106 +++++++++++++++++++++++++++++--------------\n t/t5505-remote.sh            |  54 ++++++++++++++++++++++\n 3 files changed, 134 insertions(+), 38 deletions(-)\n\ndiff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt\nindex cb103c8..7bb21a2 100644\n--- a/Documentation/git-remote.txt\n+++ b/Documentation/git-remote.txt\n@@ -15,9 +15,9 @@ SYNOPSIS\n 'git remote remove' <name>\n 'git remote set-head' <name> (-a | --auto | -d | --delete | <branch>)\n 'git remote set-branches' [--add] <name> <branch>...\n-'git remote set-url' [--push] <name> <newurl> [<oldurl>]\n-'git remote set-url --add' [--push] <name> <newurl>\n-'git remote set-url --delete' [--push] <name> <url>\n+'git remote set-url' [--fetch] [--push] <name> <newurl> [<oldurl>]\n+'git remote set-url' [--fetch] [--push] '--add' <name> <newurl>\n+'git remote set-url' [--fetch] [--push] '--delete' <name> <url>\n 'git remote' [-v | --verbose] 'show' [-n] <name>...\n 'git remote prune' [-n | --dry-run] <name>...\n 'git remote' [-v | --verbose] 'update' [-p | --prune] [(<group> | <remote>)...]\n@@ -134,7 +134,11 @@ Changes URL remote points to. Sets first URL remote points to matching\n regex <oldurl> (first URL if no <oldurl> is given) to <newurl>. If\n <oldurl> doesn't match any URL, error occurs and nothing is changed.\n +\n-With '--push', push URLs are manipulated instead of fetch URLs.\n+With '--push', push URLs are manipulated.\n++\n+With '--fetch', fetch URLs are manipulated. If neither '--push' nor '--fetch'\n+are given, then (1) '--fetch' is assumed if no push URL is set in the\n+configuration or (2) '--fetch --push' otherwise.\n +\n With '--add', instead of changing some URL, new URL is added.\n +\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 7f28f92..26caa6f 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -18,9 +18,9 @@ static const char * const builtin_remote_usage[] = {\n \tN_(\"git remote prune [-n | --dry-run] <name>\"),\n \tN_(\"git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]\"),\n \tN_(\"git remote set-branches [--add] <name> <branch>...\"),\n-\tN_(\"git remote set-url [--push] <name> <newurl> [<oldurl>]\"),\n-\tN_(\"git remote set-url --add <name> <newurl>\"),\n-\tN_(\"git remote set-url --delete <name> <url>\"),\n+\tN_(\"git remote set-url [--fetch] [--push] <name> <newurl> [<oldurl>]\"),\n+\tN_(\"git remote set-url [--fetch] [--push] --add <name> <newurl>\"),\n+\tN_(\"git remote set-url [--fetch] [--push] --delete <name> <url>\"),\n \tNULL\n };\n \n@@ -66,9 +66,9 @@ static const char * const builtin_remote_update_usage[] = {\n };\n \n static const char * const builtin_remote_seturl_usage[] = {\n-\tN_(\"git remote set-url [--push] <name> <newurl> [<oldurl>]\"),\n-\tN_(\"git remote set-url --add <name> <newurl>\"),\n-\tN_(\"git remote set-url --delete <name> <url>\"),\n+\tN_(\"git remote set-url [--fetch] [--push] <name> <newurl> [<oldurl>]\"),\n+\tN_(\"git remote set-url [--fetch] [--push] --add <name> <newurl>\"),\n+\tN_(\"git remote set-url [--fetch] [--push] --delete <name> <url>\"),\n \tNULL\n };\n \n@@ -1505,18 +1505,19 @@ static int set_branches(int argc, const char **argv)\n \n static int set_url(int argc, const char **argv)\n {\n-\tint i, push_mode = 0, add_mode = 0, delete_mode = 0;\n+\tint i, fetch_only = 0, push_only = 0, add_mode = 0, delete_mode = 0;\n \tint matches = 0, negative_matches = 0;\n \tconst char *remotename = NULL;\n \tconst char *newurl = NULL;\n \tconst char *oldurl = NULL;\n \tstruct remote *remote;\n \tregex_t old_regex;\n-\tconst char **urlset;\n-\tint urlset_nr;\n-\tstruct strbuf name_buf = STRBUF_INIT;\n+\tstruct strbuf name_buf_fetch = STRBUF_INIT;\n+\tstruct strbuf name_buf_push = STRBUF_INIT;\n \tstruct option options[] = {\n-\t\tOPT_BOOL('\\0', \"push\", &push_mode,\n+\t\tOPT_BOOL('\\0', \"fetch\", &fetch_only,\n+\t\t\t N_(\"manipulate fetch URLs\")),\n+\t\tOPT_BOOL('\\0', \"push\", &push_only,\n \t\t\t N_(\"manipulate push URLs\")),\n \t\tOPT_BOOL('\\0', \"add\", &add_mode,\n \t\t\t N_(\"add URL\")),\n@@ -1545,24 +1546,39 @@ static int set_url(int argc, const char **argv)\n \t\tdie(_(\"No such remote '%s'\"), remotename);\n \tremote = remote_get(remotename);\n \n-\tif (push_mode) {\n-\t\tstrbuf_addf(&name_buf, \"remote.%s.pushurl\", remotename);\n-\t\turlset = remote->pushurl;\n-\t\turlset_nr = remote->pushurl_nr;\n-\t} else {\n-\t\tstrbuf_addf(&name_buf, \"remote.%s.url\", remotename);\n-\t\turlset = remote->url;\n-\t\turlset_nr = remote->url_nr;\n-\t}\n+\tstrbuf_addf(&name_buf_fetch, \"remote.%s.url\", remotename);\n+\tstrbuf_addf(&name_buf_push, \"remote.%s.pushurl\", remotename);\n+\n+\t/* Backwards compatibility: do not copy fetch URL to push URL if push\n+\t * URL is unset and --fetch and --push re missing */\n+\tif (!fetch_only && !push_only)\n+\t\tfetch_only = -1;\n \n \t/* Special cases that add new entry. */\n \tif ((!oldurl && !delete_mode) || add_mode) {\n-\t\tif (add_mode)\n-\t\t\tgit_config_set_multivar(name_buf.buf, newurl,\n-\t\t\t\t\"^$\", 0);\n-\t\telse\n-\t\t\tgit_config_set(name_buf.buf, newurl);\n-\t\tstrbuf_release(&name_buf);\n+\t\t/* If --fetch was explicitly given, then ensure that the value\n+\t\t * of push URL does not change by copying the fetch URL. */\n+\t\tif (fetch_only == 1 && !push_only &&\n+\t\t\t\tremote->pushurl_nr == 0 && remote->url_nr > 0)\n+\t\t\tfor (i = 0; i < remote->url_nr; i++)\n+\t\t\t\tgit_config_set_multivar(name_buf_push.buf,\n+\t\t\t\t\tremote->url[i], \"^$\", 0);\n+\n+\t\tif (add_mode) {\n+\t\t\tif (fetch_only)\n+\t\t\t\tgit_config_set_multivar(name_buf_fetch.buf,\n+\t\t\t\t\tnewurl, \"^$\", 0);\n+\t\t\tif (push_only)\n+\t\t\t\tgit_config_set_multivar(name_buf_push.buf,\n+\t\t\t\t\tnewurl, \"^$\", 0);\n+\t\t} else {\n+\t\t\tif (fetch_only)\n+\t\t\t\tgit_config_set(name_buf_fetch.buf, newurl);\n+\t\t\tif (push_only)\n+\t\t\t\tgit_config_set(name_buf_push.buf, newurl);\n+\t\t}\n+\t\tstrbuf_release(&name_buf_fetch);\n+\t\tstrbuf_release(&name_buf_push);\n \t\treturn 0;\n \t}\n \n@@ -1570,22 +1586,44 @@ static int set_url(int argc, const char **argv)\n \tif (regcomp(&old_regex, oldurl, REG_EXTENDED))\n \t\tdie(_(\"Invalid old URL pattern: %s\"), oldurl);\n \n-\tfor (i = 0; i < urlset_nr; i++)\n-\t\tif (!regexec(&old_regex, urlset[i], 0, NULL, 0))\n+\tfor (i = 0; fetch_only && i < remote->url_nr; i++)\n+\t\tif (!regexec(&old_regex, remote->url[i], 0, NULL, 0))\n+\t\t\tmatches++;\n+\t\telse\n+\t\t\tnegative_matches++;\n+\tif (delete_mode && !negative_matches && fetch_only)\n+\t\tdie(_(\"Will not delete all non-push URLs\"));\n+\tfor (i = 0; push_only && i < remote->pushurl_nr; i++)\n+\t\tif (!regexec(&old_regex, remote->pushurl[i], 0, NULL, 0))\n \t\t\tmatches++;\n \t\telse\n \t\t\tnegative_matches++;\n \tif (!delete_mode && !matches)\n \t\tdie(_(\"No such URL found: %s\"), oldurl);\n-\tif (delete_mode && !negative_matches && !push_mode)\n-\t\tdie(_(\"Will not delete all non-push URLs\"));\n \n \tregfree(&old_regex);\n \n-\tif (!delete_mode)\n-\t\tgit_config_set_multivar(name_buf.buf, newurl, oldurl, 0);\n-\telse\n-\t\tgit_config_set_multivar(name_buf.buf, NULL, oldurl, 1);\n+\t/* If --fetch was explicitly given, then ensure that the value\n+\t * of push URL does not change by copying the fetch URL. */\n+\tif (fetch_only == 1 && !push_only &&\n+\t\t\tremote->pushurl_nr == 0 && remote->url_nr > 0)\n+\t\tfor (i = 0; i < remote->url_nr; i++)\n+\t\t\tgit_config_set_multivar(name_buf_push.buf,\n+\t\t\t\tremote->url[i], \"^$\", 0);\n+\n+\tif (!delete_mode) {\n+\t\tif (fetch_only)\n+\t\t\tgit_config_set_multivar(name_buf_fetch.buf, newurl, oldurl, 0);\n+\t\tif (push_only)\n+\t\t\tgit_config_set_multivar(name_buf_push.buf, newurl, oldurl, 0);\n+\t} else {\n+\t\tif (fetch_only)\n+\t\t\tgit_config_set_multivar(name_buf_fetch.buf, NULL, oldurl, 1);\n+\t\tif (push_only)\n+\t\t\tgit_config_set_multivar(name_buf_push.buf, NULL, oldurl, 1);\n+\t}\n+\tstrbuf_release(&name_buf_fetch);\n+\tstrbuf_release(&name_buf_push);\n \treturn 0;\n }\n \ndiff --git a/t/t5505-remote.sh b/t/t5505-remote.sh\nindex ac79dd9..a1bd383 100755\n--- a/t/t5505-remote.sh\n+++ b/t/t5505-remote.sh\n@@ -961,6 +961,60 @@ test_expect_success 'remote set-url --push zot' '\n \tcmp expect actual\n '\n \n+test_expect_success 'remote set-url --fetch zox' '\n+\tgit remote set-url --fetch someremote zox &&\n+\techo zox >expect &&\n+\techo \"YYY\" >>expect &&\n+\techo zot >>expect &&\n+\tgit config --get-all remote.someremote.url >actual &&\n+\techo \"YYY\" >>actual &&\n+\tgit config --get-all remote.someremote.pushurl >>actual &&\n+\tcmp expect actual\n+'\n+\n+test_expect_success 'remote set-url --fetch --push foo' '\n+\tgit remote set-url --fetch --push someremote foo &&\n+\techo foo >expect &&\n+\techo \"YYY\" >>expect &&\n+\techo foo >>expect &&\n+\tgit config --get-all remote.someremote.pushurl >actual &&\n+\techo \"YYY\" >>actual &&\n+\tgit config --get-all remote.someremote.url >>actual &&\n+\tcmp expect actual\n+'\n+\n+test_expect_success 'remote set-url --delete --push foo' '\n+\tgit remote set-url --delete --push someremote foo &&\n+\techo \"YYY\" >expect &&\n+\techo foo >>expect &&\n+\ttest_must_fail git config --get-all remote.someremote.pushurl >actual &&\n+\techo \"YYY\" >actual &&\n+\tgit config --get-all remote.someremote.url >>actual &&\n+\tcmp expect actual\n+'\n+\n+test_expect_success 'remote set-url --push zot' '\n+\tgit remote set-url --push someremote zot &&\n+\techo zot >expect &&\n+\techo \"YYY\" >>expect &&\n+\techo foo >>expect &&\n+\tgit config --get-all remote.someremote.pushurl >actual &&\n+\techo \"YYY\" >>actual &&\n+\tgit config --get-all remote.someremote.url >>actual &&\n+\tcmp expect actual\n+'\n+\n+test_expect_success 'remote set-url --fetch baz foo' '\n+\tgit remote set-url --fetch someremote baz foo &&\n+\techo zot >expect &&\n+\techo \"YYY\" >>expect &&\n+\techo baz >>expect &&\n+\tgit config --get-all remote.someremote.pushurl >actual &&\n+\techo \"YYY\" >>actual &&\n+\tgit config --get-all remote.someremote.url >>actual &&\n+\tcmp expect actual\n+'\n+\n test_expect_success 'remote set-url --push qux zot' '\n \tgit remote set-url --push someremote qux zot &&\n \techo qux >expect &&\n-- \n2.1.2\n\n"},{"id":"252199","messageId":"20141119201721.GC10361@peff.net","threadId":"38010","inReplyTo":"1456931.yaNzKr1t0X@al","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-11-19T20:17:21Z","receivedAt":"2014-11-19T20:17:21Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Nov 19, 2014 at 08:42:19PM +0100, Peter Wu wrote:\n\n> >   git remote set-url --push gh $(git config remote.gh.url)\n> >   git remote set-url gh new-fetch-url\n> \n> Indeed, and not having a push URL is not uncommon (that is, always the\n> case when a new remote is added or just cloned). Compare the above\n> against this one:\n> \n>     git remote set-url --fetch new-fetch-url\n> \n> This is less verbose and is much more intuitive.\n\nI agree your suggestion is a nicer way to do this. I'm just not sure\nthat this swapping is all that common an operation. If there were no\ncost, I wouldn't mind. But I'm mostly concerned about the funny,\nnon-intuitive behavior of \"git remote set-url foo\" that is created by\nthis.\n\n> > would replace both the \"url\" _and_ \"pushurl\" values in the third step,\n> > since we did not specify --fetch.  But it is in fact identical whether\n> > you run it with \"--fetch\" or not.  That is, it creates a weirdly\n> > non-orthogonal interface.\n> \n> Step three currently only replaces the fetch URL as an explicit push URL\n> (remote.gh.pushurl) is set in step two (and therefore remote.gh.url does\n> not become the implicit push URL).\n> \n> This might be a bug, but since it has been so long this way I was\n> worried that people actually rely on this behavior.\n\nI don't think this is a bug. I think that \"git fetch set-url\" without\n\"--push\" is a de-facto \"--fetch\" already. Which makes sense, as there\nisn't a \"--fetch\" now (and the \"--push\" variant and \"pushurl\" grew after\nthe fact, so the \"url\" option serves double-duty as both the single url\nand the \"fetch\" half).\n\nAnd that's what makes the proposed interface funny. Omitting \"--fetch\"\nis already a de-facto \"--fetch\", and sometimes the two behave the same,\nand sometimes differently. Calling the option \"--keep-push\" would be a\nmore accurate description, but that is rather clunky.\n\n> The patch is not tiny, but also not overly large either even if it has\n> similar pieces of code duplicated. Care has been taken of to keep\n> backwards compatibility which has also increased the size.\n\nYeah, sorry, I shouldn't have even mentioned patch size. I appreciate\nyour attention to backwards-compatibility, and the patch should be as\nlarge as it needs to safely implement the desired behavior. It's really\nthe resulting interface that I'm a bit negative on (which can be related\nto code size, in the sense that a simple interface can often be\nimplemented simply, but here we have to deal with historical corner\ncases).\n\nSo I dunno. I do not think what you are proposing is the end of the\nworld, but it would be nice to resolve the inconsistency I mentioned.\nPerhaps we can see what others think.\n\n> By the way, in the old code there was a memleak as strbuf was not\n> released at the end of the function, isn't it?\n\nYes. We are often quite lazy about such leaks in functions that are\nknown to return straight to the program exit, but it does not hurt to\nclean up here.\n\n-Peff\n"},{"id":"252201","messageId":"xmqq61ebrl1g.fsf@gitster.dls.corp.google.com","threadId":"38010","inReplyTo":"20141119190800.GB9908@peff.net","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-19T20:29:47Z","receivedAt":"2014-11-19T20:29:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> I dunno. I guess that is more convenient, but it seems like a lot of\n> code for a very marginal use case. But more importantly, I'm a little\n> worried that the presence of --fetch creates confusion about what\n> set-url without a --fetch or --push does. That is, it implies to me\n> that:\n>\n>   git remote add gh old-url\n>   git remote set-url gh --push push-url\n>   git remote set-url gh new-url\n>\n> would replace both the \"url\" _and_ \"pushurl\" values in the third step,\n> since we did not specify --fetch.  But it is in fact identical whether\n> you run it with \"--fetch\" or not.  That is, it creates a weirdly\n> non-orthogonal interface.\n\nYes, the semantics the updated code gives feel very strange.  I\nwouldn't be able to write a three-line summary in the release notes\nto advertise what good this new feature brings to users myself.\n"},{"id":"252204","messageId":"1615472.VQOo6NAl26@al","threadId":"38010","inReplyTo":"20141119201721.GC10361@peff.net","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Peter Wu","fromEmail":"peter@lekensteyn.nl","sentAt":"2014-11-19T20:48:21Z","receivedAt":"2014-11-19T20:48:21Z","isPatch":true,"sender":{"key":"peter@lekensteyn.nl","avatar":"https://gravatar.com/avatar/efcf30db53f30b15e7c905ef37bd4dc44d87573bd92baf97cd707115d3fcd0c0?d=mp&s=160"},"body":"On Wednesday 19 November 2014 15:17:21 Jeff King wrote:\n> On Wed, Nov 19, 2014 at 08:42:19PM +0100, Peter Wu wrote:\n> >     git remote set-url --fetch new-fetch-url\n> > \n> > This is less verbose and is much more intuitive.\n> \n> I agree your suggestion is a nicer way to do this. I'm just not sure\n> that this swapping is all that common an operation. If there were no\n> cost, I wouldn't mind. But I'm mostly concerned about the funny,\n> non-intuitive behavior of \"git remote set-url foo\" that is created by\n> this.\n\nIt is not about swapping, but setting a new fetch while keeping the push\nURL intact. Likely not common, but nice to have for the times it is\nneeded. I am sure there are other features which are not used a lot, but\nstill exist ;)\n\n> > > would replace both the \"url\" _and_ \"pushurl\" values in the third step,\n> > > since we did not specify --fetch.  But it is in fact identical whether\n> > > you run it with \"--fetch\" or not.  That is, it creates a weirdly\n> > > non-orthogonal interface.\n> > \n> > Step three currently only replaces the fetch URL as an explicit push URL\n> > (remote.gh.pushurl) is set in step two (and therefore remote.gh.url does\n> > not become the implicit push URL).\n> > \n> > This might be a bug, but since it has been so long this way I was\n> > worried that people actually rely on this behavior.\n> \n> I don't think this is a bug. I think that \"git fetch set-url\" without\n> \"--push\" is a de-facto \"--fetch\" already. Which makes sense, as there\n> isn't a \"--fetch\" now (and the \"--push\" variant and \"pushurl\" grew after\n> the fact, so the \"url\" option serves double-duty as both the single url\n> and the \"fetch\" half).\n> \n> And that's what makes the proposed interface funny. Omitting \"--fetch\"\n> is already a de-facto \"--fetch\", and sometimes the two behave the same,\n> and sometimes differently. Calling the option \"--keep-push\" would be a\n> more accurate description, but that is rather clunky.\n \nBefore this patch I did not even know that \"git remote set-url name url\"\nwould have different user-visible behavior depending on whether a\npushurl is set or not. In my opinion, the proposed functionality does\nnot make the interface more confusing. Instead, the new option establish\na behavior which is consistent with the existing '--push' name.\n\n(Aside, I intended to name this option \"--pull\" which seemed more\nnatural given the opposite direction \"--push\", but decided to stay\nconsistent with the \"git remote show\" terminology.)\n\nI think that your confusion is caused by the meaning of '--push' and\n'--fetch'. These options form a group and are not as independent as\n\"--add\". Something like \"--change=[push|fetch|all]\" would describe the\nfunctionality better:\n\n    git remote set-url --change=fetch gh fetchurl\n\nBut then the \"--push\" option becomes redundant.\n-- \nKind regards,\nPeter\nhttps://lekensteyn.nl\n"},{"id":"252205","messageId":"1588976.dNB1P7S71u@al","threadId":"38010","inReplyTo":"xmqq61ebrl1g.fsf@gitster.dls.corp.google.com","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Peter Wu","fromEmail":"peter@lekensteyn.nl","sentAt":"2014-11-19T20:52:49Z","receivedAt":"2014-11-19T20:52:49Z","isPatch":true,"sender":{"key":"peter@lekensteyn.nl","avatar":"https://gravatar.com/avatar/efcf30db53f30b15e7c905ef37bd4dc44d87573bd92baf97cd707115d3fcd0c0?d=mp&s=160"},"body":"On Wednesday 19 November 2014 12:29:47 Junio C Hamano wrote:\n> Jeff King <peff@peff.net> writes:\n> \n> > I dunno. I guess that is more convenient, but it seems like a lot of\n> > code for a very marginal use case. But more importantly, I'm a little\n> > worried that the presence of --fetch creates confusion about what\n> > set-url without a --fetch or --push does. That is, it implies to me\n> > that:\n> >\n> >   git remote add gh old-url\n> >   git remote set-url gh --push push-url\n> >   git remote set-url gh new-url\n> >\n> > would replace both the \"url\" _and_ \"pushurl\" values in the third step,\n> > since we did not specify --fetch.  But it is in fact identical whether\n> > you run it with \"--fetch\" or not.  That is, it creates a weirdly\n> > non-orthogonal interface.\n> \n> Yes, the semantics the updated code gives feel very strange.  I\n> wouldn't be able to write a three-line summary in the release notes\n> to advertise what good this new feature brings to users myself.\n\nWhat about:\n\n    \"git remote set-url\" learned a new \"--fetch\" option which can be\n    used to change the fetch URL while leaving the push URL intact.\n    Useful to keep a ssh URL for push and change the fetch URL to https.\n\nwhich is effectively the functionality I am using it for.\n-- \nKind regards,\nPeter\nhttps://lekensteyn.nl\n"},{"id":"252206","messageId":"xmqq1toysyak.fsf@gitster.dls.corp.google.com","threadId":"38010","inReplyTo":"20141119190800.GB9908@peff.net","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-19T20:58:11Z","receivedAt":"2014-11-19T20:58:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> But here you do not have a pushurl defined in the first place. So I\n> guess this is really just a shortcut for swapping the two, like:\n>\n>   git remote set-url --push gh $(git config remote.gh.url)\n>   git remote set-url gh new-fetch-url\n\nIt seems that this swapping is only necessary because the repository\nis set up in this way:\n\n    $ browser github.com\n    ... fork upstream to your own publishing repository ...\n    $ git clone <your publish repo>\n    ... oops, I am set up to fetch from myself ...\n    $ git remote set-url --push mine <url for your publish repo>\n    $ git remote set-url <url for your upstream repo>\n\nIf you are fetching from somebody else and then pushing into your\nown publishing repository (i.e. fork of that upstream), why isn't\nthe sequence of event like this, instead?\n\n    $ git clone $upstream\n    $ browser github.com\n    ... fork upstream to your own publishing repository ...\n    $ git remote set-url --push mine <url for your publish repo>\n\nIsn't this one of those bad workflows encouraged by GitHub, for\nwhich you guys have to be punished ;-)?\n"},{"id":"252207","messageId":"xmqqwq6qrjmi.fsf@gitster.dls.corp.google.com","threadId":"38010","inReplyTo":"1588976.dNB1P7S71u@al","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-19T21:00:21Z","receivedAt":"2014-11-19T21:00:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Peter Wu <peter@lekensteyn.nl> writes:\n\n> On Wednesday 19 November 2014 12:29:47 Junio C Hamano wrote:\n> ...\n>> Yes, the semantics the updated code gives feel very strange.  I\n>> wouldn't be able to write a three-line summary in the release notes\n>> to advertise what good this new feature brings to users myself.\n>\n> What about:\n>\n>     \"git remote set-url\" learned a new \"--fetch\" option which can be\n>     used to change the fetch URL while leaving the push URL intact.\n>     Useful to keep a ssh URL for push and change the fetch URL to https.\n>\n> which is effectively the functionality I am using it for.\n\nI do not think that clarifies the confusion-factor Peff has been\npointing out in this thread, unfortunately.  At least not to me.\n"},{"id":"252208","messageId":"xmqqsiherirj.fsf@gitster.dls.corp.google.com","threadId":"38010","inReplyTo":"xmqq1toysyak.fsf@gitster.dls.corp.google.com","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-19T21:18:56Z","receivedAt":"2014-11-19T21:18:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Jeff King <peff@peff.net> writes:\n>\n>> But here you do not have a pushurl defined in the first place. So I\n>> guess this is really just a shortcut for swapping the two, like:\n>>\n>>   git remote set-url --push gh $(git config remote.gh.url)\n>>   git remote set-url gh new-fetch-url\n>\n> It seems that this swapping is only necessary because the repository\n> is set up in this way:\n>\n>     $ browser github.com\n>     ... fork upstream to your own publishing repository ...\n>     $ git clone <your publish repo>\n>     ... oops, I am set up to fetch from myself ...\n>     $ git remote set-url --push mine <url for your publish repo>\n>     $ git remote set-url <url for your upstream repo>\n>\n> If you are fetching from somebody else and then pushing into your\n> own publishing repository (i.e. fork of that upstream), why isn't\n> the sequence of event like this, instead?\n>\n>     $ git clone $upstream\n>     $ browser github.com\n>     ... fork upstream to your own publishing repository ...\n>     $ git remote set-url --push mine <url for your publish repo>\n>\n> Isn't this one of those bad workflows encouraged by GitHub, for\n> which you guys have to be punished ;-)?\n\nI re-read the original and Peter is really accessing the same\nrepository, only over different transports.  Cloning via ssh:// but\nlater deciding to push via ssh:// but to fetch via https:// (or vice\nversa; the important point is that clone was done over a transport\nthat is \"wrong\" for future fetching).\n\nOf course, if you cloned via a wrong transport that is not suitable\nfor whatever reason for later fetching, you would need to have a way\nto \"swap\", so the observation I made in the message I am following\nup on does not apply to this thread at all.  Please scratch all of\nthe above.\n\nComing back to the topic, how common would this \"oops, I cloned via\na wrong transport\" be?  I am not opposed to giving a recovery method\nfor gotcha that does not happen very often, but if such an addition\nadds undue confusion factor for people who use \"set-url\" for more\ncommon cases, that would be a bad trade-off.\n"},{"id":"252209","messageId":"12667112.uUCmIHHWmi@al","threadId":"38010","inReplyTo":"xmqqsiherirj.fsf@gitster.dls.corp.google.com","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Peter Wu","fromEmail":"peter@lekensteyn.nl","sentAt":"2014-11-19T21:28:35Z","receivedAt":"2014-11-19T21:28:35Z","isPatch":true,"sender":{"key":"peter@lekensteyn.nl","avatar":"https://gravatar.com/avatar/efcf30db53f30b15e7c905ef37bd4dc44d87573bd92baf97cd707115d3fcd0c0?d=mp&s=160"},"body":"On Wednesday 19 November 2014 13:18:56 Junio C Hamano wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n> > Jeff King <peff@peff.net> writes:\n> > If you are fetching from somebody else and then pushing into your\n> > own publishing repository (i.e. fork of that upstream), why isn't\n> > the sequence of event like this, instead?\n> >\n> >     $ git clone $upstream\n> >     $ browser github.com\n> >     ... fork upstream to your own publishing repository ...\n> >     $ git remote set-url --push mine <url for your publish repo>\n> >\n> > Isn't this one of those bad workflows encouraged by GitHub, for\n> > which you guys have to be punished ;-)?\n\nFor \"forks\", it usually goes like this:\n\n    git clone $upstream\n    ... realizes that is has a bug which I want to fix ...\n    ... creates a new repo ...\n    git remote rename origin upstream\n    git remote add origin git@$personal_repo\n    # \"--fetch\" is what I need\n    git remote add --fetch https://$personal_repo\n\nI often start by entering/copying the ssh URL which is what I need for\npushing. Later ssh-agent forget about my key and I realize that push\nworks fine over https, so would like to set that... only to observe that\nis not possible in an straightforward way through 'git remote'.\n\n> Coming back to the topic, how common would this \"oops, I cloned via\n> a wrong transport\" be?  I am not opposed to giving a recovery method\n> for gotcha that does not happen very often, but if such an addition\n> adds undue confusion factor for people who use \"set-url\" for more\n> common cases, that would be a bad trade-off.\n\nWell, people rarely need to use 'git remote' except when, well, they\nneed to modify the remotes. Where does the confusion come from? I might\nbe biased now that I know the internals. Maybe the https/ssh case above\nneeds to be mentioned in the documentation? What do you think of the\nupdated documentation by the way?\n-- \nKind regards,\nPeter\nhttps://lekensteyn.nl\n"},{"id":"252456","messageId":"1628833.9HksdDrMW8@al","threadId":"38010","inReplyTo":"12667112.uUCmIHHWmi@al","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Peter Wu","fromEmail":"peter@lekensteyn.nl","sentAt":"2014-11-24T21:45:49Z","receivedAt":"2014-11-24T21:45:49Z","isPatch":true,"sender":{"key":"peter@lekensteyn.nl","avatar":"https://gravatar.com/avatar/efcf30db53f30b15e7c905ef37bd4dc44d87573bd92baf97cd707115d3fcd0c0?d=mp&s=160"},"body":"ping?\n\nI asked around and the people who know of `git remote` fell in these two\ncategories:\n\n - those who know of this \"bug\" and then first set the fetch URL and\n   then the push URL.\n - those who did not expect the current behavior.\n\nThe command 'git remote set-url NAME URL' reads as \"set the URL(s) for\nremote NAME to URL\". Currently it means \"set the fetch (and push) URL of\nremote NAME to URL\" (depending on whether pushurl is set).\n\nI propose to add the option --fetch next to --push with the meaning \"set\nthe fetch/push URL of remote NAME to URL\". Then --fetch --push means\n\"set the fetch and push URL of remote NAME to URL\". In a future git\nversion, this could be made the default option to avoid surprises (which\nwould be backwards incompatible though).\n\nAs for the changelog entry,\n\n    The \"git remote set-url\" command now allows you to change just the\n    fetch URL without modifying the push URL using the new --fetch\n    option. For symmetry with the --push option.\n\n(\"symmetry\" in the eyes of the user, not how it is implemented in the\ngit config.)\n\nOpinions?\n\nOn Wednesday 19 November 2014 22:28:35 Peter Wu wrote:\n> On Wednesday 19 November 2014 13:18:56 Junio C Hamano wrote:\n> > Junio C Hamano <gitster@pobox.com> writes:\n> > > Jeff King <peff@peff.net> writes:\n> > > If you are fetching from somebody else and then pushing into your\n> > > own publishing repository (i.e. fork of that upstream), why isn't\n> > > the sequence of event like this, instead?\n> > >\n> > >     $ git clone $upstream\n> > >     $ browser github.com\n> > >     ... fork upstream to your own publishing repository ...\n> > >     $ git remote set-url --push mine <url for your publish repo>\n> > >\n> > > Isn't this one of those bad workflows encouraged by GitHub, for\n> > > which you guys have to be punished ;-)?\n> \n> For \"forks\", it usually goes like this:\n> \n>     git clone $upstream\n>     ... realizes that is has a bug which I want to fix ...\n>     ... creates a new repo ...\n>     git remote rename origin upstream\n>     git remote add origin git@$personal_repo\n>     # \"--fetch\" is what I need\n>     git remote add --fetch https://$personal_repo\n> \n> I often start by entering/copying the ssh URL which is what I need for\n> pushing. Later ssh-agent forget about my key and I realize that push\n> works fine over https, so would like to set that... only to observe that\n> is not possible in an straightforward way through 'git remote'.\n> \n> > Coming back to the topic, how common would this \"oops, I cloned via\n> > a wrong transport\" be?  I am not opposed to giving a recovery method\n> > for gotcha that does not happen very often, but if such an addition\n> > adds undue confusion factor for people who use \"set-url\" for more\n> > common cases, that would be a bad trade-off.\n> \n> Well, people rarely need to use 'git remote' except when, well, they\n> need to modify the remotes. Where does the confusion come from? I might\n> be biased now that I know the internals. Maybe the https/ssh case above\n> needs to be mentioned in the documentation? What do you think of the\n> updated documentation by the way?\n"},{"id":"252459","messageId":"xmqqtx1ouug8.fsf@gitster.dls.corp.google.com","threadId":"38010","inReplyTo":"1628833.9HksdDrMW8@al","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-24T22:04:07Z","receivedAt":"2014-11-24T22:04:07Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Peter Wu <peter@lekensteyn.nl> writes:\n\n> I propose to add the option --fetch next to --push with the meaning \"set\n> the fetch/push URL of remote NAME to URL\". Then --fetch --push means\n> \"set the fetch and push URL of remote NAME to URL\". \n\nWhat would (and \"should\") the configuration look like after you did\nthis?\n\n\tgit remote set-url nick $url1\n        git remote set-url nick --push $url2\n        git remote set-url nick $url3\n\nWhatever happens without your patch after the above is what the\ncurrent users (i.e. those who do not use the --fetch option) expect,\nso if the behaviour does not change with your patch, then there is\none less incompatibilities to worry about.\n\nA new option \"--fetch\" introducing a different behaviour is\nperfectly fine; existing users who are not using it will not be\nharmed by sudden behaviour change.\n\n> In a future git\n> version, this could be made the default option to avoid surprises (which\n> would be backwards incompatible though).\n\nI am not sure what you mean \"by default\".  If you mean \"set both if\nremote.nick.pushurl does not exist but otherwise update only\nremote.nick.url\", then the sequence\n\n\tgit remote set-url nick $url1\n        git remote set-url nick --push $url2\n        git remote set-url nick $url3\n\nwould retain the current behaviour, so it probably is OK.\n\nIf you mean to always set remote.nick.url and remote.nick.pushurl\npointing at the same value when neither --fetch nor --push is given,\nThat would make the sequence behave quite different from what people\nwould expect, and you would need to devise a transition plan to\nfirst start warning when the user did something that will behave\ndifferently between the current version and the future version\nwithout changing the behaviour, then switch the behaviour but keep\nwarning and finally remove the warning, or something like that.\n\nAnd the above three-command sequence may not be the only case where\nthe change you are proposing may hurt existing users.\n"},{"id":"252460","messageId":"27811375.1kgEM3BV3q@al","threadId":"38010","inReplyTo":"xmqqtx1ouug8.fsf@gitster.dls.corp.google.com","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Peter Wu","fromEmail":"peter@lekensteyn.nl","sentAt":"2014-11-24T22:16:03Z","receivedAt":"2014-11-24T22:16:03Z","isPatch":true,"sender":{"key":"peter@lekensteyn.nl","avatar":"https://gravatar.com/avatar/efcf30db53f30b15e7c905ef37bd4dc44d87573bd92baf97cd707115d3fcd0c0?d=mp&s=160"},"body":"On Monday 24 November 2014 14:04:07 Junio C Hamano wrote:\n> Peter Wu <peter@lekensteyn.nl> writes:\n> \n> > I propose to add the option --fetch next to --push with the meaning \"set\n> > the fetch/push URL of remote NAME to URL\". Then --fetch --push means\n> > \"set the fetch and push URL of remote NAME to URL\". \n> \n> What would (and \"should\") the configuration look like after you did\n> this?\n> \n> \tgit remote set-url nick $url1\n>         git remote set-url nick --push $url2\n>         git remote set-url nick $url3\n> \n> Whatever happens without your patch after the above is what the\n> current users (i.e. those who do not use the --fetch option) expect,\n> so if the behaviour does not change with your patch, then there is\n> one less incompatibilities to worry about.\n> \n> A new option \"--fetch\" introducing a different behaviour is\n> perfectly fine; existing users who are not using it will not be\n> harmed by sudden behaviour change.\n\nAs stated before, I took care to avoid backwards incompatibilities. The\ncommand will still work as expected by the users who are aware of this\nparticular behavior. What I am suggesting (and which is independent of\nthe patch) is to make the command have a more consistent behavior.\nEither it should set the fetch URL, or both the fetch and push URL, but\nnot vary its behavior depending on whether a push URL is set or not.\nThat should make the behavior of the command more consistent.\n\n> > In a future git version, this could be made the default option to\n> > avoid surprises (which would be backwards incompatible though).\n> \n> I am not sure what you mean \"by default\".  If you mean \"set both if\n> remote.nick.pushurl does not exist but otherwise update only\n> remote.nick.url\", then the sequence\n> \n> \tgit remote set-url nick $url1\n>         git remote set-url nick --push $url2\n>         git remote set-url nick $url3\n> \n> would retain the current behaviour, so it probably is OK.\n> \n> If you mean to always set remote.nick.url and remote.nick.pushurl\n> pointing at the same value when neither --fetch nor --push is given,\n> That would make the sequence behave quite different from what people\n> would expect, and you would need to devise a transition plan to\n> first start warning when the user did something that will behave\n> differently between the current version and the future version\n> without changing the behaviour, then switch the behaviour but keep\n> warning and finally remove the warning, or something like that.\n> \n> And the above three-command sequence may not be the only case where\n> the change you are proposing may hurt existing users.\n\nThe \"default\" refers to the behavior of \"git remote set-url\" in absence\nof \"--push\" and \"--fetch\" options. A transition period is expected (if\nthis idea is put forward). Since nobody seems to be bitten by this\noption, I am not sure if it really adds much value to make this change\nthough.\n-- \nKind regards,\nPeter\nhttps://lekensteyn.nl\n"},{"id":"252461","messageId":"20141124222243.GA9055@peff.net","threadId":"38010","inReplyTo":"27811375.1kgEM3BV3q@al","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-11-24T22:22:44Z","receivedAt":"2014-11-24T22:22:44Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Nov 24, 2014 at 11:16:03PM +0100, Peter Wu wrote:\n\n> > A new option \"--fetch\" introducing a different behaviour is\n> > perfectly fine; existing users who are not using it will not be\n> > harmed by sudden behaviour change.\n> \n> As stated before, I took care to avoid backwards incompatibilities. The\n> command will still work as expected by the users who are aware of this\n> particular behavior.\n\nRight. My original complaint was only that \"--fetch\" is not as\northogonal to \"--push\" (and an optionless set-url) as it could be. I\nthink the alternatives for going forward are basically:\n\n  1. Name it something besides --fetch (but that's rather clunky).\n\n  2. Migrate to new behavior, which is what is being discussed here.\n     Probably needs a transition period?\n\n  3. Live with it. Probably address the weirdness in the documentation.\n\n  4. Do nothing, drop the patch.\n\nI think I'd be OK with (3), with an appropriate documentation update.\n\n-Peff\n"},{"id":"252463","messageId":"1660121.8PEbpzfRYH@al","threadId":"38010","inReplyTo":"20141124222243.GA9055@peff.net","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Peter Wu","fromEmail":"peter@lekensteyn.nl","sentAt":"2014-11-24T22:47:30Z","receivedAt":"2014-11-24T22:47:30Z","isPatch":true,"sender":{"key":"peter@lekensteyn.nl","avatar":"https://gravatar.com/avatar/efcf30db53f30b15e7c905ef37bd4dc44d87573bd92baf97cd707115d3fcd0c0?d=mp&s=160"},"body":"On Monday 24 November 2014 17:22:44 Jeff King wrote:\n> On Mon, Nov 24, 2014 at 11:16:03PM +0100, Peter Wu wrote:\n> \n> > > A new option \"--fetch\" introducing a different behaviour is\n> > > perfectly fine; existing users who are not using it will not be\n> > > harmed by sudden behaviour change.\n> > \n> > As stated before, I took care to avoid backwards incompatibilities. The\n> > command will still work as expected by the users who are aware of this\n> > particular behavior.\n> \n> Right. My original complaint was only that \"--fetch\" is not as\n> orthogonal to \"--push\" (and an optionless set-url) as it could be. I\n> think the alternatives for going forward are basically:\n> \n>   1. Name it something besides --fetch (but that's rather clunky).\n\nIt is not orthogonal to --push in the config, but the behavior exposed\nto the user is orthogonal unless I am missing something?\n\nI can understand that --fetch sounds a bit weird, what about this\nnatural translation:\n\n    \"git remote: set the URL (only the fetch one) for NAME to URL\"\n    git remote set-url --only=fetch NAME URL\n\n    \"git remote: set the URL (only the push one) for NAME to URL\"\n    git remote set-url --only=push NAME URL\n    (obsoletes --push)\n\n    \"git remote: set the URL (both) for NAME to URL\"\n    git remote set-url --only=both NAME URL\n    (it would be nice if --only=both (weird!) can be removed in the\n    future such that the option is more natural)\n\n    \"git remote: set the URL for NAME to URL\"\n    git remote set-url NAME URL\n    (current behavior: YOU git guru knows what I do right?)\n\n\n>   2. Migrate to new behavior, which is what is being discussed here.\n>      Probably needs a transition period?\n\nA transition period would also help to solicit feedback.\n\n>   3. Live with it. Probably address the weirdness in the documentation.\n> \n>   4. Do nothing, drop the patch.\n> \n> I think I'd be OK with (3), with an appropriate documentation update.\n\nI prefer 1 for now as it avoids the extra manual action I have to take\nwhen changing URLs.\n\nPeter\n"},{"id":"252465","messageId":"20141124225457.GA9942@peff.net","threadId":"38010","inReplyTo":"1660121.8PEbpzfRYH@al","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-11-24T22:54:57Z","receivedAt":"2014-11-24T22:54:57Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Nov 24, 2014 at 11:47:30PM +0100, Peter Wu wrote:\n\n> > Right. My original complaint was only that \"--fetch\" is not as\n> > orthogonal to \"--push\" (and an optionless set-url) as it could be. I\n> > think the alternatives for going forward are basically:\n> > \n> >   1. Name it something besides --fetch (but that's rather clunky).\n> \n> It is not orthogonal to --push in the config, but the behavior exposed\n> to the user is orthogonal unless I am missing something?\n\nMy complaint is that you have three possible options to provide: --push,\n--fetch, or no option at all. And \"--fetch\" sometimes behaves like no\noption, and sometimes not. Which is the confusing/non-orthogonal part.\n\n> I can understand that --fetch sounds a bit weird, what about this\n> natural translation:\n> \n>     \"git remote: set the URL (only the fetch one) for NAME to URL\"\n>     git remote set-url --only=fetch NAME URL\n> \n>     \"git remote: set the URL (only the push one) for NAME to URL\"\n>     git remote set-url --only=push NAME URL\n>     (obsoletes --push)\n> \n>     \"git remote: set the URL (both) for NAME to URL\"\n>     git remote set-url --only=both NAME URL\n>     (it would be nice if --only=both (weird!) can be removed in the\n>     future such that the option is more natural)\n> \n>     \"git remote: set the URL for NAME to URL\"\n>     git remote set-url NAME URL\n>     (current behavior: YOU git guru knows what I do right?)\n\nYeah, I think that addresses my concern (because it explicitly leaves\nno-option as a historical curiosity, and not as an implicit version of\n\"--both\").\n\n> >   3. Live with it. Probably address the weirdness in the documentation.\n> > \n> >   4. Do nothing, drop the patch.\n> > \n> > I think I'd be OK with (3), with an appropriate documentation update.\n> \n> I prefer 1 for now as it avoids the extra manual action I have to take\n> when changing URLs.\n\nI'm not sure if I was clear on (3), but \"live with it\" was \"live with\nyour original patch\". Which I think you would also be happy with.\n\n-Peff\n"},{"id":"252470","messageId":"xmqqbnnwurmr.fsf@gitster.dls.corp.google.com","threadId":"38010","inReplyTo":"20141124225457.GA9942@peff.net","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-24T23:05:00Z","receivedAt":"2014-11-24T23:05:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> My complaint is that you have three possible options to provide: --push,\n> --fetch, or no option at all. And \"--fetch\" sometimes behaves like no\n> option, and sometimes not. Which is the confusing/non-orthogonal part.\n>\n>> I can understand that --fetch sounds a bit weird, what about this\n>> natural translation:\n>> \n>>     \"git remote: set the URL (only the fetch one) for NAME to URL\"\n>>     git remote set-url --only=fetch NAME URL\n>> \n>>     \"git remote: set the URL (only the push one) for NAME to URL\"\n>>     git remote set-url --only=push NAME URL\n>>     (obsoletes --push)\n>> \n>>     \"git remote: set the URL (both) for NAME to URL\"\n>>     git remote set-url --only=both NAME URL\n>>     (it would be nice if --only=both (weird!) can be removed in the\n>>     future such that the option is more natural)\n>> \n>>     \"git remote: set the URL for NAME to URL\"\n>>     git remote set-url NAME URL\n>>     (current behavior: YOU git guru knows what I do right?)\n>\n> Yeah, I think that addresses my concern (because it explicitly leaves\n> no-option as a historical curiosity, and not as an implicit version of\n> \"--both\").\n\nFine by me, too.\n"},{"id":"252473","messageId":"283403992.8FOSVk7RPR@al","threadId":"38010","inReplyTo":"20141124225457.GA9942@peff.net","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Peter Wu","fromEmail":"peter@lekensteyn.nl","sentAt":"2014-11-24T23:27:31Z","receivedAt":"2014-11-24T23:27:31Z","isPatch":true,"sender":{"key":"peter@lekensteyn.nl","avatar":"https://gravatar.com/avatar/efcf30db53f30b15e7c905ef37bd4dc44d87573bd92baf97cd707115d3fcd0c0?d=mp&s=160"},"body":"On Monday 24 November 2014 17:54:57 Jeff King wrote:\n> On Mon, Nov 24, 2014 at 11:47:30PM +0100, Peter Wu wrote:\n> > I can understand that --fetch sounds a bit weird, what about this\n> > natural translation:\n> > \n> >     \"git remote: set the URL (only the fetch one) for NAME to URL\"\n> >     git remote set-url --only=fetch NAME URL\n> > \n> >     \"git remote: set the URL (only the push one) for NAME to URL\"\n> >     git remote set-url --only=push NAME URL\n> >     (obsoletes --push)\n> > \n> >     \"git remote: set the URL (both) for NAME to URL\"\n> >     git remote set-url --only=both NAME URL\n> >     (it would be nice if --only=both (weird!) can be removed in the\n> >     future such that the option is more natural)\n> > \n> >     \"git remote: set the URL for NAME to URL\"\n> >     git remote set-url NAME URL\n> >     (current behavior: YOU git guru knows what I do right?)\n> \n> Yeah, I think that addresses my concern (because it explicitly leaves\n> no-option as a historical curiosity, and not as an implicit version of\n> \"--both\").\n\nOk, I will make a clear note about the default (without --only) behavior\nhaving weird behavior for historical reasons. Are you really OK with\n--only=both? It sounds a bit odd (mathematically speaking it is correct\nas fetch and push are both partitions that form the whole set if you\nignore the historical behavior).\n\n> > >   3. Live with it. Probably address the weirdness in the documentation.\n> > > \n> > >   4. Do nothing, drop the patch.\n> > > \n> > > I think I'd be OK with (3), with an appropriate documentation update.\n> > \n> > I prefer 1 for now as it avoids the extra manual action I have to take\n> > when changing URLs.\n> \n> I'm not sure if I was clear on (3), but \"live with it\" was \"live with\n> your original patch\". Which I think you would also be happy with.\n\nOh yes, I misunderstood this one ;)\n\nWhat about the translations? Should I send a separate patch for that or\ncan I update all translations at once?\n-- \nKind regards,\nPeter\nhttps://lekensteyn.nl\n"},{"id":"252490","messageId":"20141125040826.GC19301@peff.net","threadId":"38010","inReplyTo":"283403992.8FOSVk7RPR@al","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-11-25T04:08:26Z","receivedAt":"2014-11-25T04:08:26Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Nov 25, 2014 at 12:27:31AM +0100, Peter Wu wrote:\n\n> On Monday 24 November 2014 17:54:57 Jeff King wrote:\n> > On Mon, Nov 24, 2014 at 11:47:30PM +0100, Peter Wu wrote:\n> > > I can understand that --fetch sounds a bit weird, what about this\n> > > natural translation:\n> > > \n> > >     \"git remote: set the URL (only the fetch one) for NAME to URL\"\n> > >     git remote set-url --only=fetch NAME URL\n> > > \n> > >     \"git remote: set the URL (only the push one) for NAME to URL\"\n> > >     git remote set-url --only=push NAME URL\n> > >     (obsoletes --push)\n> > > \n> > >     \"git remote: set the URL (both) for NAME to URL\"\n> > >     git remote set-url --only=both NAME URL\n> > >     (it would be nice if --only=both (weird!) can be removed in the\n> > >     future such that the option is more natural)\n> > > \n> > >     \"git remote: set the URL for NAME to URL\"\n> > >     git remote set-url NAME URL\n> > >     (current behavior: YOU git guru knows what I do right?)\n> > \n> > Yeah, I think that addresses my concern (because it explicitly leaves\n> > no-option as a historical curiosity, and not as an implicit version of\n> > \"--both\").\n> \n> Ok, I will make a clear note about the default (without --only) behavior\n> having weird behavior for historical reasons. Are you really OK with\n> --only=both? It sounds a bit odd (mathematically speaking it is correct\n> as fetch and push are both partitions that form the whole set if you\n> ignore the historical behavior).\n\nMaybe \"--operation={push,fetch,both}\" would be less odd (though\n\"--operation\" is rather clunky, I could not think of a better word). It\nis the conjunction of \"--only\" an \"both\" that makes little sense.\n\nHowever, I think what removed the confusion for me in your --only=both\nproposal was the presence of a \"both\" option, since it made it more\nclear that is not what no-option means. So what about just \"--push\",\n\"--fetch\", and \"--both\"? Explain the current behavior of no-options in\nthe documentation as a historical oddity.\n\nThat also gives us an easy path forward for changing the behavior.\nDuring the transition period, people should use --push, --fetch, or\n--both. Using no-options provides a warning. After a settling period,\nthe no-option behavior will switch to one of those (presumably --both),\nand drop the warning.\n\nYou do not have to do the migration path if you don't want to. Adding\n\"--fetch\" and \"--both\" scratches your itch and sets us up to migrate\nlater.\n\n> What about the translations? Should I send a separate patch for that or\n> can I update all translations at once?\n\nYou do not have to update the translations. When we near a release, the\nl10n coordinator will run \"make pot\" to update po/git.pot with the\nstrings marked for translation, and then the translators will write\ntranslations for the new strings. You are of course welcome to help with\nthe translation effort at that stage. :)\n\nDetails are in po/README.\n\n-Peff\n"},{"id":"252491","messageId":"xmqqy4qzubf2.fsf@gitster.dls.corp.google.com","threadId":"38010","inReplyTo":"20141125040826.GC19301@peff.net","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-25T04:55:13Z","receivedAt":"2014-11-25T04:55:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> However, I think what removed the confusion for me in your --only=both\n> proposal was the presence of a \"both\" option, since it made it more\n> clear that is not what no-option means. So what about just \"--push\",\n> \"--fetch\", and \"--both\"?\n\nI think that is the set that is most sensible, at least\nsyntactically, among the ones I heard so far in this thread.\n\nHowever, one thing still makes me wonder....\n\nAfter doing \"set-url --fetch\" and nothing else, because the user\nnever said \"--both\" or \"--push\", does the user get a configuration\nwhere \"git push\" fails?  Or does \"set-url --fetch\" still gives us\nremote.nick.url and causes \"git push\" to also go there?\n\nIf that is the case, then did addition of \"--fetch\" achieve anything\nto reduce confusion?\n\nAfter doing \"set-url --push\" and nothing else, I suspect that having\nremote.nick.pushURL alone without remote.nick.URL will make \"git fetch\"\nto fail, which would be in line with my expectation.  I just expected\nanything we do in the name of symmetry or consistency would work the\nsame/symmetric way, I cannot see how \"set-url --fetch\" would work to\nmake its effect symmetric to the \"set-url --push\" one.\n\nPuzzled...\n"},{"id":"252493","messageId":"20141125050101.GA20805@peff.net","threadId":"38010","inReplyTo":"xmqqy4qzubf2.fsf@gitster.dls.corp.google.com","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2014-11-25T05:01:01Z","receivedAt":"2014-11-25T05:01:01Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Nov 24, 2014 at 08:55:13PM -0800, Junio C Hamano wrote:\n\n> Jeff King <peff@peff.net> writes:\n> \n> > However, I think what removed the confusion for me in your --only=both\n> > proposal was the presence of a \"both\" option, since it made it more\n> > clear that is not what no-option means. So what about just \"--push\",\n> > \"--fetch\", and \"--both\"?\n> \n> I think that is the set that is most sensible, at least\n> syntactically, among the ones I heard so far in this thread.\n> \n> However, one thing still makes me wonder....\n> \n> After doing \"set-url --fetch\" and nothing else, because the user\n> never said \"--both\" or \"--push\", does the user get a configuration\n> where \"git push\" fails?  Or does \"set-url --fetch\" still gives us\n> remote.nick.url and causes \"git push\" to also go there?\n\nI think the latter. And that makes sense to me. Push falls back to fetch\nat runtime. And you never set a push url, so that's what happens.\n\nBut it is not symmetric. We do not fall back fetch to push. We _could_,\nbut that is a separate issue (one for git-fetch, and not git-remote).\nAnd I do not think it is one anybody is particularly asking for.\n\nWe could also stop making push fall back to fetch. But I think people\nwould find that irritating.\n\nI dunno. I think there has always been an implicit \"subordinate\"\nrelationship between fetch and push URLs, with fetch being the \"main\"\none. Maybe that is so ingrained in me at this point that I do not see a\nproblem with the asymmetry.\n\n-Peff\n"},{"id":"252510","messageId":"8034833.1FhY2A8KSQ@al","threadId":"38010","inReplyTo":"20141125040826.GC19301@peff.net","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Peter Wu","fromEmail":"peter@lekensteyn.nl","sentAt":"2014-11-25T11:36:43Z","receivedAt":"2014-11-25T11:36:43Z","isPatch":true,"sender":{"key":"peter@lekensteyn.nl","avatar":"https://gravatar.com/avatar/efcf30db53f30b15e7c905ef37bd4dc44d87573bd92baf97cd707115d3fcd0c0?d=mp&s=160"},"body":"On Monday 24 November 2014 23:08:26 Jeff King wrote:\n> However, I think what removed the confusion for me in your --only=both\n> proposal was the presence of a \"both\" option, since it made it more\n> clear that is not what no-option means. So what about just \"--push\",\n> \"--fetch\", and \"--both\"? Explain the current behavior of no-options in\n> the documentation as a historical oddity.\n\nOk, this sounds even better. I have dropped the --only part and made the\noptions --push, --fetch and --both disjoint (overriding each other). A\npatch will follow soon. Maybe it should warn when you try to specify\nboth options though.\n\n> That also gives us an easy path forward for changing the behavior.\n> During the transition period, people should use --push, --fetch, or\n> --both. Using no-options provides a warning. After a settling period,\n> the no-option behavior will switch to one of those (presumably --both),\n> and drop the warning.\n> \n> You do not have to do the migration path if you don't want to. Adding\n> \"--fetch\" and \"--both\" scratches your itch and sets us up to migrate\n> later.\n\nI have documented the historic behavior and mentioned that it is\n/possible/ that the option --both becomes default in the future.\n\n> > What about the translations? Should I send a separate patch for that or\n> > can I update all translations at once?\n> \n> You do not have to update the translations. When we near a release, the\n> l10n coordinator will run \"make pot\" to update po/git.pot with the\n> strings marked for translation, and then the translators will write\n> translations for the new strings. You are of course welcome to help with\n> the translation effort at that stage. \n> \n> Details are in po/README.\n\nWell, it is not necessary the translations, but the format of them. The\nformat\n\"git remote set-url --delete <name> <url>\" has changed to\n\"git remote set-url [--both | --fetch | --push] --delete <name> <url>\"\nfor example. The old strings are still usable, so I wonder whether I can\nmake it easier for the i10n maintainer to recognize this change?\n-- \nKind regards,\nPeter\nhttps://lekensteyn.nl\n"},{"id":"252512","messageId":"2050939.TNKsWtkNmu@al","threadId":"38010","inReplyTo":"CAPc5daWh4hnKsTMpaW-TvCmVDfU+rzCezrAHcLgXDG6RVvzXHA@mail.gmail.com","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Peter Wu","fromEmail":"peter@lekensteyn.nl","sentAt":"2014-11-25T11:43:36Z","receivedAt":"2014-11-25T11:43:36Z","isPatch":true,"sender":{"key":"peter@lekensteyn.nl","avatar":"https://gravatar.com/avatar/efcf30db53f30b15e7c905ef37bd4dc44d87573bd92baf97cd707115d3fcd0c0?d=mp&s=160"},"body":"On Monday 24 November 2014 21:19:16 Junio C Hamano wrote:\n> On Mon, Nov 24, 2014 at 9:01 PM, Jeff King <peff@peff.net> wrote:\n> > We could also stop making push fall back to fetch. But I think people\n> > would find that irritating.\n\nThe common case is probably having the same fetch and push URL, so I\nthink that this should not be changed.\n\n> > I dunno. I think there has always been an implicit \"subordinate\"\n> > relationship between fetch and push URLs, with fetch being the \"main\"\n> > one. Maybe that is so ingrained in me at this point that I do not see a\n> > problem with the asymmetry.\n> \n> I actually do not have problem with asymmetry/subordinate\n> relationship myself, but then why are we adding --fetch to\n> complement --push in the first place?\n> \n> Or perhaps I am misunderstanding the suggested semantics\n> of --both. That \"subordinate\" relationship really means that\n> remote.nick.URL is the one that is used for both directions\n> when pushURL is not set.\n> \n> I misunderstood that --both would add identical value to both\n> remote.nick.URL and remote.nick.pushURL, but that would\n> break the implicit subordinate relationship. Is the suggested\n> semantics of \"set-url --both\" to first delete remote.nick.pushURL\n> if exists and then to set remote.nick.URL?\n> \n> If that is what is being proposed, then I think it makes sense.\n\nYes, your last understanding is correct. For this feature, try to think\nas the user who does not know about the configuration implementation.\nThat is why the --fetch option was proposed, earlier it did not make\nsense to me why a --push option exists, but a --fetch option is missing.\n\nOption '--both' will drop the push URL and result in an implicit\nfallback to the fetch URL. It becomes slightly more hairy in the\npresence of URL sets (using --add and --delete), but I have also tried\nto make that act sensibly).\n-- \nKind regards,\nPeter\nhttps://lekensteyn.nl\n"},{"id":"252674","messageId":"D7697DE2C591421E8588920BD4FE0455@PhilipOakley","threadId":"38010","inReplyTo":"283403992.8FOSVk7RPR@al","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2014-11-28T21:39:40Z","isPatch":true,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Peter Wu\" <peter@lekensteyn.nl>\n> Ok, I will make a clear note about the default (without --only) \n> behavior\n> having weird behavior for historical reasons. Are you really OK with\n> --only=both? It sounds a bit odd (mathematically speaking it is \n> correct\n> as fetch and push are both partitions that form the whole set if you\n> ignore the historical behavior).\n>\nHow about :\n\ns/--only/--direction/\n\nor some suitable abbreviation (--dirn ?)\n--\nPhilip \n"},{"id":"252881","messageId":"4081616.27DjsMG0kb@al","threadId":"38010","inReplyTo":"D7697DE2C591421E8588920BD4FE0455@PhilipOakley","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Peter Wu","fromEmail":"peter@lekensteyn.nl","sentAt":"2014-12-02T17:45:00Z","receivedAt":"2014-12-02T17:45:00Z","isPatch":true,"sender":{"key":"peter@lekensteyn.nl","avatar":"https://gravatar.com/avatar/efcf30db53f30b15e7c905ef37bd4dc44d87573bd92baf97cd707115d3fcd0c0?d=mp&s=160"},"body":"On Saturday 29 November 2014 13:31:18 Philip Oakley wrote:\n> From: \"Peter Wu\" <peter@lekensteyn.nl>\n> > Ok, I will make a clear note about the default (without --only) \n> > behavior\n> > having weird behavior for historical reasons. Are you really OK with\n> > --only=both? It sounds a bit odd (mathematically speaking it is \n> > correct\n> > as fetch and push are both partitions that form the whole set if you\n> > ignore the historical behavior).\n> >\n> How about :\n> \n> s/--only/--direction/\n> \n> or some suitable abbreviation (--dirn ?)\n\nIn the next version of the patch I went for three separate options,\n--fetch, --push and --both:\nhttp://article.gmane.org/gmane.comp.version-control.git/260213\n(Juno, Jeff: ping?)\n\nThe option --direction=<fetch|push|both> is a bit longer and --dirn can\nbe mistaken for \"directory N\".\n-- \nKind regards,\nPeter\nhttps://lekensteyn.nl\n"},{"id":"252896","messageId":"xmqqmw75ligb.fsf@gitster.dls.corp.google.com","threadId":"38010","inReplyTo":"4081616.27DjsMG0kb@al","subject":"Re: [RFC] [PATCH] remote: add new --fetch option for set-url","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-12-02T23:50:44Z","receivedAt":"2014-12-02T23:50:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Peter Wu <peter@lekensteyn.nl> writes:\n\n> On Saturday 29 November 2014 13:31:18 Philip Oakley wrote:\n>> From: \"Peter Wu\" <peter@lekensteyn.nl>\n>> > Ok, I will make a clear note about the default (without --only) \n>> > behavior\n>> > having weird behavior for historical reasons. Are you really OK with\n>> > --only=both? It sounds a bit odd (mathematically speaking it is \n>> > correct\n>> > as fetch and push are both partitions that form the whole set if you\n>> > ignore the historical behavior).\n>> >\n>> How about :\n>> \n>> s/--only/--direction/\n>> \n>> or some suitable abbreviation (--dirn ?)\n>\n> In the next version of the patch I went for three separate options,\n> --fetch, --push and --both:\n> http://article.gmane.org/gmane.comp.version-control.git/260213\n> (Juno, Jeff: ping?)\n>\n> The option --direction=<fetch|push|both> is a bit longer and --dirn can\n> be mistaken for \"directory N\".\n\nIf we have to have three variants, --{fetch,push,both} would be the\neasiest to understand among the possibilities listed above, I would\nthink.\n"}]}