{"thread":{"id":"33217","subject":"[PATCH 0/4] Support triangular workflows","startedAt":"2013-03-18T13:16:11Z","lastAt":"2013-03-18T22:23:41Z","messageCount":16,"participants":["Ramkumar Ramachandra","Jeff King","Marc Branchaud","Eric Sunshine"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"211564","messageId":"1363612575-7340-1-git-send-email-artagnon@gmail.com","threadId":"33217","inReplyTo":null,"subject":"[PATCH 0/4] Support triangular workflows","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-03-18T13:16:11Z","receivedAt":"2013-03-18T13:16:11Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Hi,\n\nThis series follows up a previous discussion with Junio and Jeff [1].\nIt attempts to support the triangular workflow, where the remote\nyou're fetching from is not the same as the remote you're pushing to.\n`remote.<name>.pushurl` has already been discussed, and deemed as a\npoor solution to the problem [2].\n\n[1/4] is a minor cleanup patch to make other patches consistent with\nthe existing style.\n\n[2/4] introduces the infrastructure needed to allow [3/4] and [4/4] to\nbe simple configuration-adding patches.\n\n[3/4] and [4/4] add the proposed configuration options.  They're very\nsimple patches, but the documentation is not so simple: I've\ndocumented all the side-effects of the other configuration option in\neach configuration option, to give the reader a comprehensive picture\nwhen reading one configuration option.\n\nI've put off implementing remote.default corresponding to\nremote.pushdefault, as Jeff suggested in [1], because it's currently\nnot an itch; apart from the obvious symmetry, I don't know what\npurpose it serves: why would anyone want to fetch from a remote other\nthan origin by default?  Why wouldn't they simply swap that remote's\nname with \"origin\"?  However, it's a nice thing to have for symmetry,\nand it should be trivial to implement: any interested person is\nwelcome to pick it up.\n\nThe series works as expected, and all tests pass.\n\nThanks for reading.\n\n[1]: http://thread.gmane.org/gmane.comp.version-control.git/215763\n[2]: http://thread.gmane.org/gmane.comp.version-control.git/215702/focus=215717\n\nRamkumar Ramachandra (4):\n  remote.c: simply a bit of code using git_config_string()\n  remote.c: introduce a way to have different remotes for fetch/ push\n  remote.c: introduce remote.pushdefault\n  remote.c: introduce branch.<name>.pushremote\n\n Documentation/config.txt | 23 ++++++++++++++++---\n builtin/push.c           |  2 +-\n remote.c                 | 60 +++++++++++++++++++++++++++++++++++-------------\n remote.h                 |  1 +\n 4 files changed, 66 insertions(+), 20 deletions(-)\n\n-- \n1.8.2\n"},{"id":"211565","messageId":"1363612575-7340-2-git-send-email-artagnon@gmail.com","threadId":"33217","inReplyTo":"1363612575-7340-1-git-send-email-artagnon@gmail.com","subject":"[PATCH 1/4] remote.c: simply a bit of code using git_config_string()","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-03-18T13:16:12Z","receivedAt":"2013-03-18T13:16:12Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"A small segment where handle_config() parses the branch.remote\nconfiguration variable can be simplified using git_config_string().\n\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\n---\n remote.c | 4 +---\n 1 file changed, 1 insertion(+), 3 deletions(-)\n\ndiff --git a/remote.c b/remote.c\nindex e53a6eb..45b69d6 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -356,9 +356,7 @@ static int handle_config(const char *key, const char *value, void *cb)\n \t\t\treturn 0;\n \t\tbranch = make_branch(name, subkey - name);\n \t\tif (!strcmp(subkey, \".remote\")) {\n-\t\t\tif (!value)\n-\t\t\t\treturn config_error_nonbool(key);\n-\t\t\tbranch->remote_name = xstrdup(value);\n+\t\t\tgit_config_string(&branch->remote_name, key, value);\n \t\t\tif (branch == current_branch) {\n \t\t\t\tdefault_remote_name = branch->remote_name;\n \t\t\t\texplicit_default_remote_name = 1;\n-- \n1.8.2\n"},{"id":"211568","messageId":"1363612575-7340-3-git-send-email-artagnon@gmail.com","threadId":"33217","inReplyTo":"1363612575-7340-1-git-send-email-artagnon@gmail.com","subject":"[PATCH 2/4] remote.c: introduce a way to have different remotes for fetch/ push","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-03-18T13:16:13Z","receivedAt":"2013-03-18T13:16:13Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Currently, do_push() in push.c calls remote_get(), which gets the\nconfigured remote for fetching and pushing.  Replace this call with a\ncall to pushremote_get() instead, a new function that will return the\nremote configured specifically for pushing.  This function tries to\nwork with the string pushremote_name, before falling back to the\ncodepath of remote_get().  This patch has no visible impact, but\nserves to enable future patches to introduce configuration variables\nto set this variable.\n\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\n---\n builtin/push.c |  2 +-\n remote.c       | 49 ++++++++++++++++++++++++++++++++++++-------------\n remote.h       |  1 +\n 3 files changed, 38 insertions(+), 14 deletions(-)\n\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 42b129d..d447a80 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -322,7 +322,7 @@ static int push_with_options(struct transport *transport, int flags)\n static int do_push(const char *repo, int flags)\n {\n \tint i, errs;\n-\tstruct remote *remote = remote_get(repo);\n+\tstruct remote *remote = pushremote_get(repo);\n \tconst char **url;\n \tint url_nr;\n \ndiff --git a/remote.c b/remote.c\nindex 45b69d6..4704404 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -48,6 +48,7 @@ static int branches_nr;\n \n static struct branch *current_branch;\n static const char *default_remote_name;\n+static const char *pushremote_name;\n static int explicit_default_remote_name;\n \n static struct rewrites rewrites;\n@@ -669,20 +670,9 @@ static int valid_remote_nick(const char *name)\n \treturn !strchr(name, '/'); /* no slash */\n }\n \n-struct remote *remote_get(const char *name)\n+static struct remote *remote_get_1(const char *name, int name_given)\n {\n-\tstruct remote *ret;\n-\tint name_given = 0;\n-\n-\tread_config();\n-\tif (name)\n-\t\tname_given = 1;\n-\telse {\n-\t\tname = default_remote_name;\n-\t\tname_given = explicit_default_remote_name;\n-\t}\n-\n-\tret = make_remote(name, 0);\n+\tstruct remote *ret = make_remote(name, 0);\n \tif (valid_remote_nick(name)) {\n \t\tif (!valid_remote(ret))\n \t\t\tread_remotes_file(ret);\n@@ -698,6 +688,39 @@ struct remote *remote_get(const char *name)\n \treturn ret;\n }\n \n+struct remote *remote_get(const char *name)\n+{\n+\tint name_given = 0;\n+\n+\tread_config();\n+\tif (name)\n+\t\tname_given = 1;\n+\telse {\n+\t\tname = default_remote_name;\n+\t\tname_given = explicit_default_remote_name;\n+\t}\n+\treturn remote_get_1(name, name_given);\n+}\n+\n+struct remote *pushremote_get(const char *name)\n+{\n+\tint name_given = 0;\n+\n+\tread_config();\n+\tif (name)\n+\t\tname_given = 1;\n+\telse {\n+\t\tif (pushremote_name) {\n+\t\t\tname = pushremote_name;\n+\t\t\tname_given = 1;\n+\t\t} else {\n+\t\t\tname = default_remote_name;\n+\t\t\tname_given = explicit_default_remote_name;\n+\t\t}\n+\t}\n+\treturn remote_get_1(name, name_given);\n+}\n+\n int remote_is_configured(const char *name)\n {\n \tint i;\ndiff --git a/remote.h b/remote.h\nindex 251d8fd..99a437f 100644\n--- a/remote.h\n+++ b/remote.h\n@@ -51,6 +51,7 @@ struct remote {\n };\n \n struct remote *remote_get(const char *name);\n+struct remote *pushremote_get(const char *name);\n int remote_is_configured(const char *name);\n \n typedef int each_remote_fn(struct remote *remote, void *priv);\n-- \n1.8.2\n"},{"id":"211566","messageId":"1363612575-7340-4-git-send-email-artagnon@gmail.com","threadId":"33217","inReplyTo":"1363612575-7340-1-git-send-email-artagnon@gmail.com","subject":"[PATCH 3/4] remote.c: introduce remote.pushdefault","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-03-18T13:16:14Z","receivedAt":"2013-03-18T13:16:14Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"This new configuration variable defines the default remote to push to,\nand overrides `branch.<name>.remote` for all branches.  It is useful\nin the typical triangular-workflow setup, where the remote you're\nfetching from is different from the remote you're pushing to.\n\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\n---\n Documentation/config.txt | 13 ++++++++++---\n remote.c                 |  4 ++++\n 2 files changed, 14 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex bbba728..8ddd0fd 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -723,9 +723,12 @@ branch.autosetuprebase::\n \tThis option defaults to never.\n \n branch.<name>.remote::\n-\tWhen in branch <name>, it tells 'git fetch' and 'git push' which\n-\tremote to fetch from/push to.  It defaults to `origin` if no remote is\n-\tconfigured. `origin` is also used if you are not on any branch.\n+\tWhen on branch <name>, it tells 'git fetch' and 'git push'\n+\twhich remote to fetch from/push to.  The remote to push to\n+\tmay be overriden with `remote.pushdefault` (for all branches).\n+\tIf no remote is configured, or if you are not on any branch,\n+\tit defaults to `origin` for fetching and `remote.pushdefault`\n+\tfor pushing.\n \n branch.<name>.merge::\n \tDefines, together with branch.<name>.remote, the upstream branch\n@@ -1894,6 +1897,10 @@ receive.updateserverinfo::\n \tIf set to true, git-receive-pack will run git-update-server-info\n \tafter receiving data from git-push and updating refs.\n \n+remote.pushdefault::\n+\tThe remote to push to by default.  Overrides\n+\t`branch.<name>.remote` for all branches.\n+\n remote.<name>.url::\n \tThe URL of a remote repository.  See linkgit:git-fetch[1] or\n \tlinkgit:git-push[1].\ndiff --git a/remote.c b/remote.c\nindex 4704404..987edc4 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -350,6 +350,10 @@ static int handle_config(const char *key, const char *value, void *cb)\n \tconst char *subkey;\n \tstruct remote *remote;\n \tstruct branch *branch;\n+\tif (!prefixcmp(key, \"remote.\")) {\n+\t\tif (!strcmp(key + 7, \"pushdefault\"))\n+\t\t\tgit_config_string(&pushremote_name, key, value);\n+\t}\n \tif (!prefixcmp(key, \"branch.\")) {\n \t\tname = key + 7;\n \t\tsubkey = strrchr(name, '.');\n-- \n1.8.2\n"},{"id":"211567","messageId":"1363612575-7340-5-git-send-email-artagnon@gmail.com","threadId":"33217","inReplyTo":"1363612575-7340-1-git-send-email-artagnon@gmail.com","subject":"[PATCH 4/4] remote.c: introduce branch.<name>.pushremote","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-03-18T13:16:15Z","receivedAt":"2013-03-18T13:16:15Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"This new configuration variable overrides `remote.pushdefault` and\n`branch.<name>.remote` for pushes.  In a typical triangular-workflow\nsetup, you would want to set `remote.pushdefault` to specify the\nremote to push to for all branches, and use this option to override it\nfor a specific branch.\n\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\n---\n Documentation/config.txt | 18 ++++++++++++++----\n remote.c                 |  3 +++\n 2 files changed, 17 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 8ddd0fd..d0e36e9 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -726,9 +726,18 @@ branch.<name>.remote::\n \tWhen on branch <name>, it tells 'git fetch' and 'git push'\n \twhich remote to fetch from/push to.  The remote to push to\n \tmay be overriden with `remote.pushdefault` (for all branches).\n-\tIf no remote is configured, or if you are not on any branch,\n-\tit defaults to `origin` for fetching and `remote.pushdefault`\n-\tfor pushing.\n+\tThe remote to push to, for the current branch, may be further\n+\toverriden by `branch.<name>.pushremote`.  If no remote is\n+\tconfigured, or if you are not on any branch, it defaults to\n+\t`origin` for fetching and `remote.pushdefault` for pushing.\n+\n+branch.<name>.pushremote::\n+\tWhen on branch <name>, it overrides `branch.<name>.remote`\n+\twhen pushing.  It also overrides `remote.pushdefault` when\n+\tpushing from branch <name>.  In a typical triangular-workflow\n+\tsetup, you would want to set `remote.pushdefault` to specify\n+\tthe remote to push to for all branches, and use this option to\n+\toverride it for a specific branch.\n \n branch.<name>.merge::\n \tDefines, together with branch.<name>.remote, the upstream branch\n@@ -1899,7 +1908,8 @@ receive.updateserverinfo::\n \n remote.pushdefault::\n \tThe remote to push to by default.  Overrides\n-\t`branch.<name>.remote` for all branches.\n+\t`branch.<name>.remote` for all branches, and is overriden by\n+\t`branch.<name>.pushremote` for specific branches.\n \n remote.<name>.url::\n \tThe URL of a remote repository.  See linkgit:git-fetch[1] or\ndiff --git a/remote.c b/remote.c\nindex 987edc4..a4d3d22 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -366,6 +366,9 @@ static int handle_config(const char *key, const char *value, void *cb)\n \t\t\t\tdefault_remote_name = branch->remote_name;\n \t\t\t\texplicit_default_remote_name = 1;\n \t\t\t}\n+\t\t} else if (!strcmp(subkey, \".pushremote\")) {\n+\t\t\tif (branch == current_branch)\n+\t\t\t\tgit_config_string(&pushremote_name, key, value);\n \t\t} else if (!strcmp(subkey, \".merge\")) {\n \t\t\tif (!value)\n \t\t\t\treturn config_error_nonbool(key);\n-- \n1.8.2\n"},{"id":"211571","messageId":"20130318142526.GA23075@sigill.intra.peff.net","threadId":"33217","inReplyTo":"1363612575-7340-1-git-send-email-artagnon@gmail.com","subject":"Re: [PATCH 0/4] Support triangular workflows","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2013-03-18T14:25:26Z","receivedAt":"2013-03-18T14:25:26Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Mar 18, 2013 at 06:46:11PM +0530, Ramkumar Ramachandra wrote:\n\n> I've put off implementing remote.default corresponding to\n> remote.pushdefault, as Jeff suggested in [1], because it's currently\n> not an itch; apart from the obvious symmetry, I don't know what\n> purpose it serves: why would anyone want to fetch from a remote other\n> than origin by default?  Why wouldn't they simply swap that remote's\n> name with \"origin\"?  However, it's a nice thing to have for symmetry,\n> and it should be trivial to implement: any interested person is\n> welcome to pick it up.\n\nYeah, I agree that it does not have much point, aside from people who\nhave an unreasonable aversion to using the word \"origin\". There was a\nseries posted last summer to add remote.default:\n\n  http://article.gmane.org/gmane.comp.version-control.git/201065\n\nIt ended up stalled and never got merged. I think the main impetus was\nthat \"git clone -o foo\" should leave \"foo\" in remote.default (of course,\nthat still leaves unanswered why anyone would really want to use \"-o\nfoo\" in the first place).\n\nI think the symmetry makes some sense, but I also think it can come\nlater if somebody wants it.\n\n>  Documentation/config.txt | 23 ++++++++++++++++---\n>  builtin/push.c           |  2 +-\n>  remote.c                 | 60 +++++++++++++++++++++++++++++++++++-------------\n>  remote.h                 |  1 +\n>  4 files changed, 66 insertions(+), 20 deletions(-)\n\nNo new tests?\n\n-Peff\n"},{"id":"211572","messageId":"CALkWK0=D6JmocJJcLJTV6z-TcyuJL35cDpozaa6t64V_W2KSRQ@mail.gmail.com","threadId":"33217","inReplyTo":"20130318142526.GA23075@sigill.intra.peff.net","subject":"Re: [PATCH 0/4] Support triangular workflows","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-03-18T14:28:23Z","receivedAt":"2013-03-18T14:28:23Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Jeff King wrote:\n> On Mon, Mar 18, 2013 at 06:46:11PM +0530, Ramkumar Ramachandra wrote:\n>>  Documentation/config.txt | 23 ++++++++++++++++---\n>>  builtin/push.c           |  2 +-\n>>  remote.c                 | 60 +++++++++++++++++++++++++++++++++++-------------\n>>  remote.h                 |  1 +\n>>  4 files changed, 66 insertions(+), 20 deletions(-)\n>\n> No new tests?\n\nHonestly, it slipped my mind.  Will write it now.\n\nThanks for the reminder.\n"},{"id":"211573","messageId":"20130318143121.GB23075@sigill.intra.peff.net","threadId":"33217","inReplyTo":"1363612575-7340-3-git-send-email-artagnon@gmail.com","subject":"Re: [PATCH 2/4] remote.c: introduce a way to have different remotes for fetch/ push","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2013-03-18T14:31:21Z","receivedAt":"2013-03-18T14:31:21Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Mar 18, 2013 at 06:46:13PM +0530, Ramkumar Ramachandra wrote:\n\n> +struct remote *remote_get(const char *name)\n> +{\n> +\tint name_given = 0;\n> +\n> +\tread_config();\n> +\tif (name)\n> +\t\tname_given = 1;\n> +\telse {\n> +\t\tname = default_remote_name;\n> +\t\tname_given = explicit_default_remote_name;\n> +\t}\n> +\treturn remote_get_1(name, name_given);\n> +}\n> +\n> +struct remote *pushremote_get(const char *name)\n> +{\n> +\tint name_given = 0;\n> +\n> +\tread_config();\n> +\tif (name)\n> +\t\tname_given = 1;\n> +\telse {\n> +\t\tif (pushremote_name) {\n> +\t\t\tname = pushremote_name;\n> +\t\t\tname_given = 1;\n> +\t\t} else {\n> +\t\t\tname = default_remote_name;\n> +\t\t\tname_given = explicit_default_remote_name;\n> +\t\t}\n> +\t}\n> +\treturn remote_get_1(name, name_given);\n> +}\n\nCan we get rid of this duplication by having remote_get_1 take a\nservice-specific default argument? And then each service calls it like:\n\n  struct remote *remote_get(const char *name)\n  {\n          read_config();\n          return remote_get_1(name, NULL);\n  }\n\n  struct remote *pushremote_get(const char *name)\n  {\n          read_config();\n          return remote_get_1(name, pushremote_name);\n  }\n\nand all of the name_given junk can stay in remote_get_1. And adding\n\"remote.default\" would just be a matter of changing that NULL in\nremote_get.\n\n-Peff\n"},{"id":"211574","messageId":"20130318143251.GC23075@sigill.intra.peff.net","threadId":"33217","inReplyTo":"CALkWK0=D6JmocJJcLJTV6z-TcyuJL35cDpozaa6t64V_W2KSRQ@mail.gmail.com","subject":"Re: [PATCH 0/4] Support triangular workflows","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2013-03-18T14:32:51Z","receivedAt":"2013-03-18T14:32:51Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Mar 18, 2013 at 07:58:23PM +0530, Ramkumar Ramachandra wrote:\n\n> Jeff King wrote:\n> > On Mon, Mar 18, 2013 at 06:46:11PM +0530, Ramkumar Ramachandra wrote:\n> >>  Documentation/config.txt | 23 ++++++++++++++++---\n> >>  builtin/push.c           |  2 +-\n> >>  remote.c                 | 60 +++++++++++++++++++++++++++++++++++-------------\n> >>  remote.h                 |  1 +\n> >>  4 files changed, 66 insertions(+), 20 deletions(-)\n> >\n> > No new tests?\n> \n> Honestly, it slipped my mind.  Will write it now.\n> \n> Thanks for the reminder.\n\nThanks. Other than the suggestion I made on 2/4, I do not see anything\nwrong with the series.\n\n-Peff\n"},{"id":"211575","messageId":"CALkWK0mc3HN4jT24QKP2Bt49fPtSd4=3wO0xFA7-4gt2n7ih-g@mail.gmail.com","threadId":"33217","inReplyTo":"20130318143121.GB23075@sigill.intra.peff.net","subject":"Re: [PATCH 2/4] remote.c: introduce a way to have different remotes for fetch/ push","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-03-18T14:56:46Z","receivedAt":"2013-03-18T14:56:46Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Jeff King wrote:\n> On Mon, Mar 18, 2013 at 06:46:13PM +0530, Ramkumar Ramachandra wrote:\n>\n>> +struct remote *remote_get(const char *name)\n>> +{\n>> +     int name_given = 0;\n>> +\n>> +     read_config();\n>> +     if (name)\n>> +             name_given = 1;\n>> +     else {\n>> +             name = default_remote_name;\n>> +             name_given = explicit_default_remote_name;\n>> +     }\n>> +     return remote_get_1(name, name_given);\n>> +}\n>> +\n>> +struct remote *pushremote_get(const char *name)\n>> +{\n>> +     int name_given = 0;\n>> +\n>> +     read_config();\n>> +     if (name)\n>> +             name_given = 1;\n>> +     else {\n>> +             if (pushremote_name) {\n>> +                     name = pushremote_name;\n>> +                     name_given = 1;\n>> +             } else {\n>> +                     name = default_remote_name;\n>> +                     name_given = explicit_default_remote_name;\n>> +             }\n>> +     }\n>> +     return remote_get_1(name, name_given);\n>> +}\n>\n> Can we get rid of this duplication by having remote_get_1 take a\n> service-specific default argument? And then each service calls it like:\n>\n>   struct remote *remote_get(const char *name)\n>   {\n>           read_config();\n>           return remote_get_1(name, NULL);\n>   }\n>\n>   struct remote *pushremote_get(const char *name)\n>   {\n>           read_config();\n>           return remote_get_1(name, pushremote_name);\n>   }\n\nThanks for the dose of sanity.  While at it, why not move\nread_config() to remote_get_1() as well?\n"},{"id":"211576","messageId":"20130318145834.GA24095@sigill.intra.peff.net","threadId":"33217","inReplyTo":"CALkWK0mc3HN4jT24QKP2Bt49fPtSd4=3wO0xFA7-4gt2n7ih-g@mail.gmail.com","subject":"Re: [PATCH 2/4] remote.c: introduce a way to have different remotes for fetch/ push","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2013-03-18T14:58:34Z","receivedAt":"2013-03-18T14:58:34Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Mar 18, 2013 at 08:26:46PM +0530, Ramkumar Ramachandra wrote:\n\n> > Can we get rid of this duplication by having remote_get_1 take a\n> > service-specific default argument? And then each service calls it like:\n> >\n> >   struct remote *remote_get(const char *name)\n> >   {\n> >           read_config();\n> >           return remote_get_1(name, NULL);\n> >   }\n> >\n> >   struct remote *pushremote_get(const char *name)\n> >   {\n> >           read_config();\n> >           return remote_get_1(name, pushremote_name);\n> >   }\n> \n> Thanks for the dose of sanity.  While at it, why not move\n> read_config() to remote_get_1() as well?\n\nBecause it sets pushremote_name, and therefore you would just be passing\nNULL if read_config has not been run yet. But if you made it:\n\n  return remote_get_1(name, &pushremote_name);\n\nthat would work.\n\n-Peff\n"},{"id":"211579","messageId":"5147390C.9060907@xiplink.com","threadId":"33217","inReplyTo":"20130318142526.GA23075@sigill.intra.peff.net","subject":"Re: [PATCH 0/4] Support triangular workflows","fromName":"Marc Branchaud","fromEmail":"mbranchaud@xiplink.com","sentAt":"2013-03-18T15:55:56Z","receivedAt":"2013-03-18T15:55:56Z","isPatch":true,"sender":{"key":"mbranchaud@xiplink.com","avatar":null},"body":"On 13-03-18 10:25 AM, Jeff King wrote:\n> On Mon, Mar 18, 2013 at 06:46:11PM +0530, Ramkumar Ramachandra wrote:\n> \n>> I've put off implementing remote.default corresponding to\n>> remote.pushdefault, as Jeff suggested in [1], because it's currently\n>> not an itch; apart from the obvious symmetry, I don't know what\n>> purpose it serves: why would anyone want to fetch from a remote other\n>> than origin by default?  Why wouldn't they simply swap that remote's\n>> name with \"origin\"?  However, it's a nice thing to have for symmetry,\n>> and it should be trivial to implement: any interested person is\n>> welcome to pick it up.\n> \n> Yeah, I agree that it does not have much point, aside from people who\n> have an unreasonable aversion to using the word \"origin\". There was a\n> series posted last summer to add remote.default:\n> \n>   http://article.gmane.org/gmane.comp.version-control.git/201065\n> \n> It ended up stalled and never got merged. I think the main impetus was\n> that \"git clone -o foo\" should leave \"foo\" in remote.default (of course,\n> that still leaves unanswered why anyone would really want to use \"-o\n> foo\" in the first place).\n\nI'm the guy who dropped the ball on that series.  I still intend to pick it\nup (honest!) but I just haven't had the time.\n\nThe impetus was originally getting relative submodule paths to work on\ndetached HEADs [1].  My patch for that doesn't work when someone does \"clone\n-o\", because various parts of git assume there's a remote named \"origin\".\nThe discussion led to the idea of using the remote name specified during the\ninitial clone, and implementing that as a remote.default config value.\n\nAs for why \"clone -o\" exists, it was added in v1.1.0:\n\n    commit e6c310fd0d7384973efc6b1d5999a5e8a5b2f3bd\n    Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n    Date:   Thu Dec 22 23:37:24 2005 +0100\n\n    git-clone: Support changing the origin branch with -o\n\n    Earlier, git-clone stored upstream's master in the branch named 'origin',\n    possibly overwriting an existing such branch.\n\n    Now you can change it by calling git-clone with '-o <other_name>'.\n\n    [jc: added ref format check, subdirectory safety, documentation\n     and usage string.]\n\n    Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n    Signed-off-by: Junio C Hamano <junkio@cox.net>\n\nIt sounds like the original need for the -o option is no longer pertinent.\nOTOH, for folks who deal with several remotes it's nice to name them, and\n\"origin\" isn't necessarily a useful or intuitive name.\n\n\t\tM.\n\n[1] http://thread.gmane.org/gmane.comp.version-control.git/200145\n"},{"id":"211612","messageId":"CAPig+cRGv9b6HVbk4pcx38-UXQu6Jgi6sfiQ+Urp4V9tv5+zUg@mail.gmail.com","threadId":"33217","inReplyTo":"1363612575-7340-2-git-send-email-artagnon@gmail.com","subject":"Re: [PATCH 1/4] remote.c: simply a bit of code using git_config_string()","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2013-03-18T22:14:48Z","receivedAt":"2013-03-18T22:14:48Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, Mar 18, 2013 at 9:16 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> remote.c: simply a bit of code using git_config_string()\n\ns/simply/simplify/\n\n> A small segment where handle_config() parses the branch.remote\n> configuration variable can be simplified using git_config_string().\n>\n> Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\n"},{"id":"211613","messageId":"CAPig+cSQPtea3AYgsMuU9RE=ecfkbArx9bFJH686eitsF7FD0Q@mail.gmail.com","threadId":"33217","inReplyTo":"1363612575-7340-3-git-send-email-artagnon@gmail.com","subject":"Re: [PATCH 2/4] remote.c: introduce a way to have different remotes for fetch/ push","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2013-03-18T22:17:15Z","receivedAt":"2013-03-18T22:17:15Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, Mar 18, 2013 at 9:16 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> remote.c: introduce a way to have different remotes for fetch/ push\n\ns/ push/push/\n\n> Currently, do_push() in push.c calls remote_get(), which gets the\n> configured remote for fetching and pushing.  Replace this call with a\n> call to pushremote_get() instead, a new function that will return the\n> remote configured specifically for pushing.  This function tries to\n> work with the string pushremote_name, before falling back to the\n> codepath of remote_get().  This patch has no visible impact, but\n> serves to enable future patches to introduce configuration variables\n> to set this variable.\n>\n> Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\n"},{"id":"211614","messageId":"CAPig+cQ8wiYffxyucRRi5jOhFjv-O6x8OBx6wz6Q_zJzQyN=_A@mail.gmail.com","threadId":"33217","inReplyTo":"1363612575-7340-4-git-send-email-artagnon@gmail.com","subject":"Re: [PATCH 3/4] remote.c: introduce remote.pushdefault","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2013-03-18T22:19:45Z","receivedAt":"2013-03-18T22:19:45Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, Mar 18, 2013 at 9:16 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n>  branch.<name>.remote::\n> -       When in branch <name>, it tells 'git fetch' and 'git push' which\n> -       remote to fetch from/push to.  It defaults to `origin` if no remote is\n> -       configured. `origin` is also used if you are not on any branch.\n> +       When on branch <name>, it tells 'git fetch' and 'git push'\n> +       which remote to fetch from/push to.  The remote to push to\n> +       may be overriden with `remote.pushdefault` (for all branches).\n\ns/overriden/overridden/\n\n> +       If no remote is configured, or if you are not on any branch,\n> +       it defaults to `origin` for fetching and `remote.pushdefault`\n> +       for pushing.\n"},{"id":"211615","messageId":"CAPig+cQ5-07+oRYCym+9wA-C020oZ3V9_ZhE8o_RU-1OGqhpmg@mail.gmail.com","threadId":"33217","inReplyTo":"1363612575-7340-5-git-send-email-artagnon@gmail.com","subject":"Re: [PATCH 4/4] remote.c: introduce branch.<name>.pushremote","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2013-03-18T22:23:41Z","receivedAt":"2013-03-18T22:23:41Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, Mar 18, 2013 at 9:16 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> -       If no remote is configured, or if you are not on any branch,\n> -       it defaults to `origin` for fetching and `remote.pushdefault`\n> -       for pushing.\n> +       The remote to push to, for the current branch, may be further\n> +       overriden by `branch.<name>.pushremote`.  If no remote is\n\ns/overriden/overridden/\n\n> +       configured, or if you are not on any branch, it defaults to\n> +       `origin` for fetching and `remote.pushdefault` for pushing.\n> +\n>  remote.pushdefault::\n>         The remote to push to by default.  Overrides\n> -       `branch.<name>.remote` for all branches.\n> +       `branch.<name>.remote` for all branches, and is overriden by\n\nDitto: s/overriden/overridden/\n\n> +       `branch.<name>.pushremote` for specific branches.\n"}]}