{"thread":{"id":"33832","subject":"[RFC/PATCH 0/3] New kind of upstream branch: downstream branch","startedAt":"2013-05-16T03:43:45Z","lastAt":"2013-05-16T15:24:19Z","messageCount":28,"participants":["Felipe Contreras","Junio C Hamano","Ramkumar Ramachandra","Antoine Pelisse"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"217499","messageId":"1368675828-27418-1-git-send-email-felipe.contreras@gmail.com","threadId":"33832","inReplyTo":null,"subject":"[RFC/PATCH 0/3] New kind of upstream branch: downstream branch","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T03:43:45Z","receivedAt":"2013-05-16T03:43:45Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Hi,\n\nAfter thinking a bit more about, I think the current 'upstream' branch serves\nmost of the purposes; actually tracks an upstream branch; makes sense to rebase\nonto that, makes sense to fetch from that remote, merge, and pull.\n\nThe only job it doesn't make sense to use the 'upstream' branch for is to push,\nso here's a new notion of 'downstream' branch.\n\nThese patches are only exploratory, 'git branch -v' doesn't show these\nbranches, there's no @{downstream}, no documentation, and there isn't even a\nway to set it.\n\nIf there's no downstream branch configured, nothing changes.\n\nFelipe Contreras (3):\n  remote: don't override default if cur head remote is '.'\n  pull: trivial cleanups\n  push: add separate 'downstream' branch\n\n builtin/push.c | 65 ++++++++++++++++++++++++++++++++++++----------------------\n git-pull.sh    | 15 +++++++++-----\n remote.c       | 10 ++++++---\n remote.h       |  3 +++\n 4 files changed, 61 insertions(+), 32 deletions(-)\n\n-- \n1.8.3.rc1.579.g184e698\n"},{"id":"217500","messageId":"1368675828-27418-2-git-send-email-felipe.contreras@gmail.com","threadId":"33832","inReplyTo":"1368675828-27418-1-git-send-email-felipe.contreras@gmail.com","subject":"[RFC/PATCH 1/3] remote: don't override default if cur head remote is '.'","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T03:43:46Z","receivedAt":"2013-05-16T03:43:46Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"'git fetch .' makes no sense, so let's keep using the default ('origin')\nwhen the current branch's remote is '.'.\n\nAlso update 'git pull' so that pulling works the same way as before.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n git-pull.sh | 9 ++++++++-\n remote.c    | 2 +-\n 2 files changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/git-pull.sh b/git-pull.sh\nindex 638aabb..75297c7 100755\n--- a/git-pull.sh\n+++ b/git-pull.sh\n@@ -220,7 +220,14 @@ test true = \"$rebase\" && {\n \tdone\n }\n orig_head=$(git rev-parse -q --verify HEAD)\n-git fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok \"$@\" || exit 1\n+# get the default remote\n+remote=\"$(git config \"branch.$curr_branch_short.remote\")\"\n+if test $# == 0 && test -n \"$remote\"\n+then\n+\tgit fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok \"$remote\" || exit 1\n+else\n+\tgit fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok \"$@\" || exit 1\n+fi\n test -z \"$dry_run\" || exit 0\n \n curr_head=$(git rev-parse -q --verify HEAD)\ndiff --git a/remote.c b/remote.c\nindex 68eb99b..322a1b6 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -360,7 +360,7 @@ static int handle_config(const char *key, const char *value, void *cb)\n \t\tif (!strcmp(subkey, \".remote\")) {\n \t\t\tif (git_config_string(&branch->remote_name, key, value))\n \t\t\t\treturn -1;\n-\t\t\tif (branch == current_branch) {\n+\t\t\tif (branch == current_branch && strcmp(branch->remote_name, \".\")) {\n \t\t\t\tdefault_remote_name = branch->remote_name;\n \t\t\t\texplicit_default_remote_name = 1;\n \t\t\t}\n-- \n1.8.3.rc1.579.g184e698\n"},{"id":"217501","messageId":"1368675828-27418-3-git-send-email-felipe.contreras@gmail.com","threadId":"33832","inReplyTo":"1368675828-27418-1-git-send-email-felipe.contreras@gmail.com","subject":"[RFC/PATCH 2/3] pull: trivial cleanups","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T03:43:47Z","receivedAt":"2013-05-16T03:43:47Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n git-pull.sh | 6 ++----\n 1 file changed, 2 insertions(+), 4 deletions(-)\n\ndiff --git a/git-pull.sh b/git-pull.sh\nindex 75297c7..b207df2 100755\n--- a/git-pull.sh\n+++ b/git-pull.sh\n@@ -166,9 +166,7 @@ error_on_no_merge_candidates () {\n \t\top_prep=with\n \tfi\n \n-\tcurr_branch=${curr_branch#refs/heads/}\n-\tupstream=$(git config \"branch.$curr_branch.merge\")\n-\tremote=$(git config \"branch.$curr_branch.remote\")\n+\tupstream=$(git config \"branch.$curr_branch_short.merge\")\n \n \tif [ $# -gt 1 ]; then\n \t\tif [ \"$rebase\" = true ]; then\n@@ -183,7 +181,7 @@ error_on_no_merge_candidates () {\n \t\techo \"You asked to pull from the remote '$1', but did not specify\"\n \t\techo \"a branch. Because this is not the default configured remote\"\n \t\techo \"for your current branch, you must specify a branch on the command line.\"\n-\telif [ -z \"$curr_branch\" -o -z \"$upstream\" ]; then\n+\telif [ -z \"$curr_branch_short\" -o -z \"$upstream\" ]; then\n \t\t. git-parse-remote\n \t\terror_on_missing_default_upstream \"pull\" $op_type $op_prep \\\n \t\t\t\"git pull <remote> <branch>\"\n-- \n1.8.3.rc1.579.g184e698\n"},{"id":"217502","messageId":"1368675828-27418-4-git-send-email-felipe.contreras@gmail.com","threadId":"33832","inReplyTo":"1368675828-27418-1-git-send-email-felipe.contreras@gmail.com","subject":"[RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T03:43:48Z","receivedAt":"2013-05-16T03:43:48Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"It doesn't make sense to push to the upstream branch, so create new\nconfigurations for the notion of 'downstream' branch, which is basically\nthe branch to push to by default.\n\nThe upstream branch is remote+merge, the downstream branch is\npushremote+push.\n\n  [branch \"master\"]\n\t  remote = origin\n\t  merge = refs/heads/master\n\t  pushremote = github\n\t  push = refs/heads/master\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n builtin/push.c | 65 ++++++++++++++++++++++++++++++++++++----------------------\n remote.c       |  8 ++++++--\n remote.h       |  3 +++\n 3 files changed, 50 insertions(+), 26 deletions(-)\n\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 909c34d..c062fa5 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -76,21 +76,23 @@ static int push_url_of_remote(struct remote *remote, const char ***url_p)\n \treturn remote->url_nr;\n }\n \n-static NORETURN int die_push_simple(struct branch *branch, struct remote *remote) {\n+static NORETURN int die_push_simple(struct branch *branch, struct remote *remote,\n+\t\tconst char *kind, const char *related)\n+{\n \t/*\n \t * There's no point in using shorten_unambiguous_ref here,\n \t * as the ambiguity would be on the remote side, not what\n \t * we have locally. Plus, this is supposed to be the simple\n \t * mode. If the user is doing something crazy like setting\n-\t * upstream to a non-branch, we should probably be showing\n+\t * upstream/downstream to a non-branch, we should probably be showing\n \t * them the big ugly fully qualified ref.\n \t */\n \tconst char *advice_maybe = \"\";\n-\tconst char *short_upstream =\n-\t\tskip_prefix(branch->merge[0]->src, \"refs/heads/\");\n+\tconst char *short_upstream = skip_prefix(related, \"refs/heads/\");\n \n \tif (!short_upstream)\n-\t\tshort_upstream = branch->merge[0]->src;\n+\t\tshort_upstream = related;\n+\n \t/*\n \t * Don't show advice for people who explicitely set\n \t * push.default.\n@@ -99,8 +101,8 @@ static NORETURN int die_push_simple(struct branch *branch, struct remote *remote\n \t\tadvice_maybe = _(\"\\n\"\n \t\t\t\t \"To choose either option permanently, \"\n \t\t\t\t \"see push.default in 'git help config'.\");\n-\tdie(_(\"The upstream branch of your current branch does not match\\n\"\n-\t      \"the name of your current branch.  To push to the upstream branch\\n\"\n+\tdie(_(\"The %s branch of your current branch does not match\\n\"\n+\t      \"the name of your current branch.  To push to the %s branch\\n\"\n \t      \"on the remote, use\\n\"\n \t      \"\\n\"\n \t      \"    git push %s HEAD:%s\\n\"\n@@ -109,6 +111,7 @@ static NORETURN int die_push_simple(struct branch *branch, struct remote *remote\n \t      \"\\n\"\n \t      \"    git push %s %s\\n\"\n \t      \"%s\"),\n+\t    kind, kind,\n \t    remote->name, short_upstream,\n \t    remote->name, branch->name, advice_maybe);\n }\n@@ -117,6 +120,8 @@ static void setup_push_upstream(struct remote *remote, int simple)\n {\n \tstruct strbuf refspec = STRBUF_INIT;\n \tstruct branch *branch = branch_get(NULL);\n+\tconst char *related, *kind, *pushremote_name;\n+\n \tif (!branch)\n \t\tdie(_(\"You are not currently on a branch.\\n\"\n \t\t    \"To push the history leading to the current (detached HEAD)\\n\"\n@@ -124,26 +129,38 @@ static void setup_push_upstream(struct remote *remote, int simple)\n \t\t    \"\\n\"\n \t\t    \"    git push %s HEAD:<name-of-remote-branch>\\n\"),\n \t\t    remote->name);\n-\tif (!branch->merge_nr || !branch->merge || !branch->remote_name)\n-\t\tdie(_(\"The current branch %s has no upstream branch.\\n\"\n-\t\t    \"To push the current branch and set the remote as upstream, use\\n\"\n-\t\t    \"\\n\"\n-\t\t    \"    git push --set-upstream %s %s\\n\"),\n-\t\t    branch->name,\n-\t\t    remote->name,\n-\t\t    branch->name);\n-\tif (branch->merge_nr != 1)\n-\t\tdie(_(\"The current branch %s has multiple upstream branches, \"\n-\t\t    \"refusing to push.\"), branch->name);\n-\tif (strcmp(branch->remote_name, remote->name))\n-\t\tdie(_(\"You are pushing to remote '%s', which is not the upstream of\\n\"\n+\n+\tif (branch->push) {\n+\t\tkind = _(\"downstream\");\n+\t\trelated = branch->push;\n+\t\tpushremote_name = branch->pushremote_name;\n+\t} else {\n+\t\tif (!branch->merge_nr || !branch->merge || !branch->remote_name)\n+\t\t\tdie(_(\"The current branch %s has no upstream branch.\\n\"\n+\t\t\t    \"To push the current branch and set the remote as upstream, use\\n\"\n+\t\t\t    \"\\n\"\n+\t\t\t    \"    git push --set-upstream %s %s\\n\"),\n+\t\t\t    branch->name,\n+\t\t\t    remote->name,\n+\t\t\t    branch->name);\n+\t\tif (branch->merge_nr != 1)\n+\t\t\tdie(_(\"The current branch %s has multiple upstream branches, \"\n+\t\t\t    \"refusing to push.\"), branch->name);\n+\n+\t\tkind = _(\"upstream\");\n+\t\trelated = branch->merge[0]->src;\n+\t\tpushremote_name = branch->remote_name;\n+\t}\n+\n+\tif (strcmp(pushremote_name, remote->name))\n+\t\tdie(_(\"You are pushing to remote '%s', which is not the %s of\\n\"\n \t\t      \"your current branch '%s', without telling me what to push\\n\"\n \t\t      \"to update which remote branch.\"),\n-\t\t    remote->name, branch->name);\n-\tif (simple && strcmp(branch->refname, branch->merge[0]->src))\n-\t\tdie_push_simple(branch, remote);\n+\t\t    remote->name, kind, branch->name);\n+\tif (simple && strcmp(branch->refname, related))\n+\t\tdie_push_simple(branch, remote, kind, related);\n \n-\tstrbuf_addf(&refspec, \"%s:%s\", branch->name, branch->merge[0]->src);\n+\tstrbuf_addf(&refspec, \"%s:%s\", branch->name, related);\n \tadd_refspec(refspec.buf);\n }\n \ndiff --git a/remote.c b/remote.c\nindex 322a1b6..f057b5f 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -365,13 +365,17 @@ static int handle_config(const char *key, const char *value, void *cb)\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 (git_config_string(&branch->pushremote_name, key, value))\n+\t\t\t\treturn -1;\n \t\t\tif (branch == current_branch)\n-\t\t\t\tif (git_config_string(&pushremote_name, key, value))\n-\t\t\t\t\treturn -1;\n+\t\t\t\tpushremote_name = xstrdup(branch->pushremote_name);\n \t\t} else if (!strcmp(subkey, \".merge\")) {\n \t\t\tif (!value)\n \t\t\t\treturn config_error_nonbool(key);\n \t\t\tadd_merge(branch, xstrdup(value));\n+\t\t} else if (!strcmp(subkey, \".push\")) {\n+\t\t\tif (git_config_string(&branch->push, key, value))\n+\t\t\t\treturn -1;\n \t\t}\n \t\treturn 0;\n \t}\ndiff --git a/remote.h b/remote.h\nindex cf56724..24433af 100644\n--- a/remote.h\n+++ b/remote.h\n@@ -138,6 +138,9 @@ struct branch {\n \tstruct refspec **merge;\n \tint merge_nr;\n \tint merge_alloc;\n+\n+\tconst char *pushremote_name;\n+\tconst char *push;\n };\n \n struct branch *branch_get(const char *name);\n-- \n1.8.3.rc1.579.g184e698\n"},{"id":"217507","messageId":"7vip2j8ozu.fsf@alter.siamese.dyndns.org","threadId":"33832","inReplyTo":"1368675828-27418-4-git-send-email-felipe.contreras@gmail.com","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-16T05:36:53Z","receivedAt":"2013-05-16T05:36:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> It doesn't make sense to push to the upstream branch, so create new\n> configurations for the notion of 'downstream' branch, which is basically\n> the branch to push to by default.\n\nIt doesn't?  That depends.\n\nTo people coming from (and people who are still using) central\nshared repository workflow, pushing to anywhere other than the\nupstream makes no sense.\n\nIf qualified with something like \"When using a triangular workflow\nto pull from one place and push to another place\" in front, I can\nsee why having a separate upstream and downstream makes sense, and...\n\n> The upstream branch is remote+merge, the downstream branch is\n> pushremote+push.\n\n... this is a perfect explanation of what a downsream is.\n"},{"id":"217510","messageId":"CAMP44s2sKWCswB+wT6OiyrA5_oVqUkDptrkdZCjWCucUL3KrKA@mail.gmail.com","threadId":"33832","inReplyTo":"7vip2j8ozu.fsf@alter.siamese.dyndns.org","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T06:00:57Z","receivedAt":"2013-05-16T06:00:57Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 12:36 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n>> It doesn't make sense to push to the upstream branch, so create new\n>> configurations for the notion of 'downstream' branch, which is basically\n>> the branch to push to by default.\n>\n> It doesn't?  That depends.\n>\n> To people coming from (and people who are still using) central\n> shared repository workflow, pushing to anywhere other than the\n> upstream makes no sense.\n\nSemantics I guess; you can say they are pushing to the upstream, or\nthat they are pushing downstream, which happens to be the same as the\nupstream.\n\nMy rationale was that at some point in the future we might want to\nremove the code that pushes upstream, and only push downstream. And\neither way configure downstream when creating new branches with\ntracking. But I'm not sure that's a good idea.\n\n> If qualified with something like \"When using a triangular workflow\n> to pull from one place and push to another place\" in front, I can\n> see why having a separate upstream and downstream makes sense, and...\n>\n>> The upstream branch is remote+merge, the downstream branch is\n>> pushremote+push.\n>\n> ... this is a perfect explanation of what a downsream is.\n\nCool. I haven't decided how best to set the downstream yet, but for me\nit's more important that 'git fetch' works sanely (patch #1), and I\ndon't like the proposed patch, but I can't think of anything better.\n\n-- \nFelipe Contreras\n"},{"id":"217511","messageId":"7vehd78n9y.fsf@alter.siamese.dyndns.org","threadId":"33832","inReplyTo":"CAMP44s2sKWCswB+wT6OiyrA5_oVqUkDptrkdZCjWCucUL3KrKA@mail.gmail.com","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-16T06:14:01Z","receivedAt":"2013-05-16T06:14:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> ...for me\n> it's more important that 'git fetch' works sanely (patch #1), and I\n> don't like the proposed patch, but I can't think of anything better.\n\nI do not like that either, but I haven't formed a firm opinion on it\nyet.\n"},{"id":"217523","messageId":"CALkWK0nTS6Vh7GfnrLWAK5VeevQyGN5N7xT43c+uqBQ5oM5tww@mail.gmail.com","threadId":"33832","inReplyTo":"1368675828-27418-4-git-send-email-felipe.contreras@gmail.com","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-16T08:21:10Z","receivedAt":"2013-05-16T08:21:10Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Felipe Contreras wrote:\n>   [branch \"master\"]\n>           remote = origin\n>           merge = refs/heads/master\n>           pushremote = github\n>           push = refs/heads/master\n\nHm.  Some thoughts:\n\nfetch and push aren't symmetric.  By default fetches are batched: when\nyou say 'git fetch', it fetches all the refs and uses the\nremote.<name>.fetch refspec to update the refs on your side.  Now, I\nwould argue that this is the correct design, because I rarely want to\nfetch just one ref (and that is broken, by the way: refs on my side\naren't updated for some weird reason).  The other reason this is\ncorrect is because fetching has nothing to do with local branches: how\nyou _merge_ your remote branches to your local branches is entirely\northogonal to the issue (and that is controlled by\nbranch.<name>.merge).\n\nNow, push is a different ball game altogether.  There are people who\ndo batched pushes (push.default = matching has been the default for 8\nyears now).  However, the support for a batched push in a triangular\nworkflow is very limited: I can't say git push master hot-branch\npickaxe-doc, and expect them to go to the right remotes (this idea has\nalready been discussed and rejected).  Back to your patch: if you want\nto support batched pushes to map refs correctly, you should write a\npatch for remote.<name>.push.  It has a very valid usecase too: there\nare people who use Gerrit and they shouldn't have to do git push\n<name>:refs/for/<name> every single time.  Neither should they have to\nconfigure each branch.<name>.push.  The ref-mapping is an inherent\nproperty of the remote, not of the local branch.  And\nbranch.<name>.merge is entirely orthogonal to ref-mapping, as I\nalready explained.\n\nThat said, I think the concept of a downstream can be useful.  I have\nbranch.hot-branch.remote set to origin, and\nbranch.hot-branch.pushremote set to ram.  Now, I push some changes: my\nprompt still says > (indicating unpushed changes), and this is very\nannoying.  I would definitely like git to be able to recognize that\nI'm ahead of upstream, but in-sync with my downstream.  So, your\nbranch.<name>.push should probably be named\nbranch.<name>.downstreamref and be used only for informational\npurposes (@{d} and git status)?  Wait, why do we need it at all?  Is\nthere something that we cannot infer from a proposed\nremote.<name>.push?  Why will we ever need to override that refspec\nmapping with a local branch configuration?\n"},{"id":"217527","messageId":"CALkWK0=tP=v=3Q4dzPc=W0=j_7iFYdGnzkaV6U_MFSg=NCE49w@mail.gmail.com","threadId":"33832","inReplyTo":"1368675828-27418-3-git-send-email-felipe.contreras@gmail.com","subject":"Re: [RFC/PATCH 2/3] pull: trivial cleanups","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-16T08:29:46Z","receivedAt":"2013-05-16T08:29:46Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Felipe Contreras wrote:\n>  git-pull.sh | 6 ++----\n>  1 file changed, 2 insertions(+), 4 deletions(-)\n\nThis one obviously looks good.  I'm not sure why you sent it along\nwith the other two patches though.\n\nOn a related note, I'm interested in fixing pull.  What I have on paper so far:\n\n- pull.condition = clean-worktree | ff-update | no-local-changes |\nalways | never\n- pull.action = merge | rebase* | reset\n- pull.resetType = soft | hard | merge | keep\n- pull.autostash = true | false\n\n(ff-update is satisfied when FETCH_HEAD is directly ahead of\nrefs/remotes/<branch>, while no-local-changes is satisfied when\nFETCH_HEAD is directly ahead of refs/heads/<branch>)\n\nAny clue how to design branch-specific pull configuration?\n"},{"id":"217540","messageId":"CAMP44s0sg6zQc9=cD1X61joxSd=LK7qT1k-suej3dYDD826hgw@mail.gmail.com","threadId":"33832","inReplyTo":"CALkWK0=tP=v=3Q4dzPc=W0=j_7iFYdGnzkaV6U_MFSg=NCE49w@mail.gmail.com","subject":"Re: [RFC/PATCH 2/3] pull: trivial cleanups","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T08:56:53Z","receivedAt":"2013-05-16T08:56:53Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 3:29 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Felipe Contreras wrote:\n>>  git-pull.sh | 6 ++----\n>>  1 file changed, 2 insertions(+), 4 deletions(-)\n>\n> This one obviously looks good.  I'm not sure why you sent it along\n> with the other two patches though.\n\nBecause this patch depends on the previous one.\n\n> On a related note, I'm interested in fixing pull.  What I have on paper so far:\n>\n> - pull.condition = clean-worktree | ff-update | no-local-changes |\n> always | never\n> - pull.action = merge | rebase* | reset\n> - pull.resetType = soft | hard | merge | keep\n> - pull.autostash = true | false\n\nI don't understand that. But my only concern is that there's no way to\ndo something like:\n\n% git fetch backup 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'\n\n-- \nFelipe Contreras\n"},{"id":"217543","messageId":"CAMP44s3fPsGW_9aBbcsu8cJAagz8JEWV2HM=XRH3Rw4=SXdL7Q@mail.gmail.com","threadId":"33832","inReplyTo":"CALkWK0nTS6Vh7GfnrLWAK5VeevQyGN5N7xT43c+uqBQ5oM5tww@mail.gmail.com","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T09:05:49Z","receivedAt":"2013-05-16T09:05:49Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 3:21 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Felipe Contreras wrote:\n>>   [branch \"master\"]\n>>           remote = origin\n>>           merge = refs/heads/master\n>>           pushremote = github\n>>           push = refs/heads/master\n>\n> Hm.  Some thoughts:\n>\n> fetch and push aren't symmetric.  By default fetches are batched: when\n> you say 'git fetch', it fetches all the refs and uses the\n> remote.<name>.fetch refspec to update the refs on your side.  Now, I\n> would argue that this is the correct design, because I rarely want to\n> fetch just one ref (and that is broken, by the way: refs on my side\n> aren't updated for some weird reason).  The other reason this is\n> correct is because fetching has nothing to do with local branches: how\n> you _merge_ your remote branches to your local branches is entirely\n> orthogonal to the issue (and that is controlled by\n> branch.<name>.merge).\n>\n> Now, push is a different ball game altogether.  There are people who\n> do batched pushes (push.default = matching has been the default for 8\n> years now).\n\nAnd is going to change soon.\n\n> However, the support for a batched push in a triangular\n> workflow is very limited: I can't say git push master hot-branch\n> pickaxe-doc, and expect them to go to the right remotes (this idea has\n> already been discussed and rejected).  Back to your patch: if you want\n> to support batched pushes to map refs correctly, you should write a\n> patch for remote.<name>.push.  It has a very valid usecase too: there\n> are people who use Gerrit and they shouldn't have to do git push\n> <name>:refs/for/<name> every single time.  Neither should they have to\n> configure each branch.<name>.push.  The ref-mapping is an inherent\n> property of the remote, not of the local branch.  And\n> branch.<name>.merge is entirely orthogonal to ref-mapping, as I\n> already explained.\n>\n> That said, I think the concept of a downstream can be useful.  I have\n> branch.hot-branch.remote set to origin, and\n> branch.hot-branch.pushremote set to ram.  Now, I push some changes: my\n> prompt still says > (indicating unpushed changes), and this is very\n> annoying.  I would definitely like git to be able to recognize that\n> I'm ahead of upstream, but in-sync with my downstream.  So, your\n> branch.<name>.push should probably be named\n> branch.<name>.downstreamref and be used only for informational\n> purposes (@{d} and git status)?\n\nThat makes absolutely no sense.\n\n[branch \"master\"]\n          remote = origin\n          merge = refs/heads/master\n          pushremote = github\n          downstreamref = refs/heads/whaaa:refs/heads/master\n\nWhat is the point of 'refs/heads/whaaa'?\n\n> Wait, why do we need it at all?  Is\n> there something that we cannot infer from a proposed\n> remote.<name>.push?  Why will we ever need to override that refspec\n> mapping with a local branch configuration?\n\n[branch \"master\"]\n          remote = origin\n          merge = refs/heads/master\n          pushremote = github\n          push = refs/heads/fc/master\n\n[branch \"fc/old-remote/hg\"]\n          remote = .\n          merge = refs/heads/master\n          pushremote = github\n          push = refs/heads/fc/remote/hg\n\nTell me how you express that without 'remote.branch.push'.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"217547","messageId":"CALkWK0nOywB5BtHnKZQ_+wsJNp82zk7-YJw_S15quqH+iU=jWg@mail.gmail.com","threadId":"33832","inReplyTo":"CAMP44s3fPsGW_9aBbcsu8cJAagz8JEWV2HM=XRH3Rw4=SXdL7Q@mail.gmail.com","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-16T09:20:51Z","receivedAt":"2013-05-16T09:20:51Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Felipe Contreras wrote:\n> And is going to change soon.\n\nYour point being?  How will this patch interact with push.default = matching?\n\n>> branch.<name>.push should probably be named\n>> branch.<name>.downstreamref and be used only for informational\n>> purposes (@{d} and git status)?\n>\n> That makes absolutely no sense.\n\nI said downstreamref, not downstreamrefspec.\n\n> [branch \"master\"]\n>           remote = origin\n>           merge = refs/heads/master\n>           pushremote = github\n>           push = refs/heads/fc/master\n>\n> [branch \"fc/old-remote/hg\"]\n>           remote = .\n>           merge = refs/heads/master\n>           pushremote = github\n>           push = refs/heads/fc/remote/hg\n>\n> Tell me how you express that without 'remote.branch.push'.\n\n[remote \"origin\"]\n    push = refs/heads/master:refs/heads/fc/master\n\n[remote \".\"]\n    push = refs/heads/fc/old-remote/hg:refs/heads/fc/remote/hg\n\nAdvantage being you can do:\n\n[remote \"origin\"]\n    push = refs/heads/*:refs/for/*\n\nWhile you can't with branch.<name>.push.\n"},{"id":"217550","messageId":"CAMP44s2vsD2uwFoL5_79m05gtqyKLN9wHX8Yrhtn0kT4LVULxQ@mail.gmail.com","threadId":"33832","inReplyTo":"CALkWK0nOywB5BtHnKZQ_+wsJNp82zk7-YJw_S15quqH+iU=jWg@mail.gmail.com","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T09:33:07Z","receivedAt":"2013-05-16T09:33:07Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 4:20 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Felipe Contreras wrote:\n>> And is going to change soon.\n>\n> Your point being?  How will this patch interact with push.default = matching?\n>\n>>> branch.<name>.push should probably be named\n>>> branch.<name>.downstreamref and be used only for informational\n>>> purposes (@{d} and git status)?\n>>\n>> That makes absolutely no sense.\n>\n> I said downstreamref, not downstreamrefspec.\n\nThat's not consistent with branch.A.merge, which is not named\nbranch.A.upstreamref.\n\n>> [branch \"master\"]\n>>           remote = origin\n>>           merge = refs/heads/master\n>>           pushremote = github\n>>           push = refs/heads/fc/master\n>>\n>> [branch \"fc/old-remote/hg\"]\n>>           remote = .\n>>           merge = refs/heads/master\n>>           pushremote = github\n>>           push = refs/heads/fc/remote/hg\n>>\n>> Tell me how you express that without 'remote.branch.push'.\n>\n> [remote \"origin\"]\n>     push = refs/heads/master:refs/heads/fc/master\n>\n> [remote \".\"]\n>     push = refs/heads/fc/old-remote/hg:refs/heads/fc/remote/hg\n\nLet's see:\n\n% git checkout master\n% git push\n\nIt will try to push to 'origin/fc/master' not 'github/fc/master',\nwhich is what I intended.\n\n% git checkout fc/old-remote/hg\n% git push\n\nIt will try to push to 'fc/remote/hg' not 'github/fc/remote/hg', which\nis what I intended.\n\n> Advantage being you can do:\n>\n> [remote \"origin\"]\n>     push = refs/heads/*:refs/for/*\n>\n> While you can't with branch.<name>.push.\n\nBut I can do 'git push origin \"refs/head/*:refs/heads/for/*\"', not\nthat I've ever had the need to do something like that, so I don't\ncare.\n\n-- \nFelipe Contreras\n"},{"id":"217552","messageId":"CALkWK0=RF4cjQ4Lz4Qi2iac_NgLdzBRw5Q9uf8KjYJju8swWDQ@mail.gmail.com","threadId":"33832","inReplyTo":"CAMP44s0sg6zQc9=cD1X61joxSd=LK7qT1k-suej3dYDD826hgw@mail.gmail.com","subject":"Re: [RFC/PATCH 2/3] pull: trivial cleanups","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-16T09:34:05Z","receivedAt":"2013-05-16T09:34:05Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Felipe Contreras wrote:\n> But my only concern is that there's no way to\n> do something like:\n>\n> % git fetch backup 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'\n\n[remote \"backup\"]\n    fetch = refs/tags/*:refs/tags/*\n    fetch = refs/heads/*:refs/heads/*\n\nWhat am I missing?\n"},{"id":"217553","messageId":"CAMP44s1vMTfrSaU+0S8EOM5g4L0885780SvT_THBr7u==bJ06A@mail.gmail.com","threadId":"33832","inReplyTo":"CALkWK0=RF4cjQ4Lz4Qi2iac_NgLdzBRw5Q9uf8KjYJju8swWDQ@mail.gmail.com","subject":"Re: [RFC/PATCH 2/3] pull: trivial cleanups","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T09:36:36Z","receivedAt":"2013-05-16T09:36:36Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 4:34 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Felipe Contreras wrote:\n>> But my only concern is that there's no way to\n>> do something like:\n>>\n>> % git fetch backup 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'\n>\n> [remote \"backup\"]\n>     fetch = refs/tags/*:refs/tags/*\n>     fetch = refs/heads/*:refs/heads/*\n>\n> What am I missing?\n\nActually trying that command:\n\n% git fetch origin 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'\nfatal: Refusing to fetch into current branch\nrefs/heads/fc/fast-export/cleanup of non-bare repository\nfatal: The remote end hung up unexpectedly\n\n-- \nFelipe Contreras\n"},{"id":"217570","messageId":"CALkWK0kP1yhdhV7oLA4gYJTJ7VtU2WuhtJ_Q5UsZSS00y=FP_w@mail.gmail.com","threadId":"33832","inReplyTo":"CAMP44s1vMTfrSaU+0S8EOM5g4L0885780SvT_THBr7u==bJ06A@mail.gmail.com","subject":"Re: [RFC/PATCH 2/3] pull: trivial cleanups","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-16T09:54:59Z","receivedAt":"2013-05-16T09:54:59Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Felipe Contreras wrote:\n> % git fetch origin 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'\n> fatal: Refusing to fetch into current branch\n> refs/heads/fc/fast-export/cleanup of non-bare repository\n> fatal: The remote end hung up unexpectedly\n\nThat's because your HEAD is pointing to something under refs/heads/*:\nit would work otherwise.  When I'm developing on my personal branch, I\nsometimes do 'git fetch origin master:master +pu:pu +next:next', and\nit works as expected.  When on master branch, I can't git fetch origin\nmaster:master and this is a cute safety feature.\n\nEither way, I think it's a bad practice to fetch directly into\nrefs/heads/*: you should really be fetching to refs/remotes and then\nmerging your changes in.  I do want shortcuts though, which is why I'm\ninterested in fixing pull: there is nothing to fix in fetch as far as\nI'm concerned.\n"},{"id":"217573","messageId":"CALkWK0m+_AbCd305dU5p5bxwuPPCBKJH7a3e6rHgxxnySMz0pQ@mail.gmail.com","threadId":"33832","inReplyTo":"CAMP44s2vsD2uwFoL5_79m05gtqyKLN9wHX8Yrhtn0kT4LVULxQ@mail.gmail.com","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-16T10:06:22Z","receivedAt":"2013-05-16T10:06:22Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Felipe Contreras wrote:\n>> [remote \"origin\"]\n>>     push = refs/heads/master:refs/heads/fc/master\n>>\n>> [remote \".\"]\n>>     push = refs/heads/fc/old-remote/hg:refs/heads/fc/remote/hg\n\nMajor thinko.  It should be:\n\n[remote \"github\"]\n    push = refs/heads/master:refs/heads/fc/master\n    push = refs/heads/fc/old-remote/hg:refs/heads/fc/remote/hg\n\n>> Advantage being you can do:\n>>\n>> [remote \"origin\"]\n>>     push = refs/heads/*:refs/for/*\n>>\n>> While you can't with branch.<name>.push.\n>\n> But I can do 'git push origin \"refs/head/*:refs/heads/for/*\"', not\n> that I've ever had the need to do something like that, so I don't\n> care.\n\nIsn't the entire point of this exercise getting git to dwim without\nbeing explicit?\n\nI don't care about it personally either, which is why I haven't\nwritten a patch yet.  However, there are users of Gerrit who would\nappreciate this feature: in the remote.pushdefault thread, some people\nrequested this feature.\n"},{"id":"217574","messageId":"CAMP44s08Q3xn13iqptf5jAUThHcEWQK5b77=pWLvOnjGsBfSMw@mail.gmail.com","threadId":"33832","inReplyTo":"CALkWK0kP1yhdhV7oLA4gYJTJ7VtU2WuhtJ_Q5UsZSS00y=FP_w@mail.gmail.com","subject":"Re: [RFC/PATCH 2/3] pull: trivial cleanups","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T10:15:06Z","receivedAt":"2013-05-16T10:15:06Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 4:54 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Felipe Contreras wrote:\n>> % git fetch origin 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'\n>> fatal: Refusing to fetch into current branch\n>> refs/heads/fc/fast-export/cleanup of non-bare repository\n>> fatal: The remote end hung up unexpectedly\n>\n> That's because your HEAD is pointing to something under refs/heads/*:\n> it would work otherwise.  When I'm developing on my personal branch, I\n> sometimes do 'git fetch origin master:master +pu:pu +next:next', and\n> it works as expected.  When on master branch, I can't git fetch origin\n> master:master and this is a cute safety feature.\n\nNow you know what's the problem.\n\n> Either way, I think it's a bad practice to fetch directly into\n> refs/heads/*: you should really be fetching to refs/remotes and then\n> merging your changes in.  I do want shortcuts though, which is why I'm\n> interested in fixing pull: there is nothing to fix in fetch as far as\n> I'm concerned.\n\nIt doesn't matter if you think it's a bad practice or not, 'git push\n--mirror' works, and it's possible to update a branch even if HEAD is\npoint to it. There should be a possibility to do the same with 'git\nfetch'.\n\nRight now the user is forced to do something like:\n\n\tgit checkout -q -b tmp &&\n\tgit fetch origin 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&\n\tgit checkout -q @{-1} &&\n\tgit branch -q -D tmp 2> /dev/null\n\nWhich doesn't seem to be quite right.\n\n-- \nFelipe Contreras\n"},{"id":"217575","messageId":"CALkWK0mAWUV1KgFaY2LpSQ_+=deE5wwV=Je23MuMi=6ktE+DAA@mail.gmail.com","threadId":"33832","inReplyTo":"CAMP44s08Q3xn13iqptf5jAUThHcEWQK5b77=pWLvOnjGsBfSMw@mail.gmail.com","subject":"Re: [RFC/PATCH 2/3] pull: trivial cleanups","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-16T10:18:21Z","receivedAt":"2013-05-16T10:18:21Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Felipe Contreras wrote:\n> It doesn't matter if you think it's a bad practice or not, 'git push\n> --mirror' works, and it's possible to update a branch even if HEAD is\n> point to it. There should be a possibility to do the same with 'git\n> fetch'.\n\nSo, introduce a configuration variable to turn off this safety feature?\n"},{"id":"217576","messageId":"CAMP44s1eB+bvg7vnG5S3SBACHTrkpCqJNX-Q2tzEVdvzFWvkcA@mail.gmail.com","threadId":"33832","inReplyTo":"CALkWK0m+_AbCd305dU5p5bxwuPPCBKJH7a3e6rHgxxnySMz0pQ@mail.gmail.com","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T10:22:52Z","receivedAt":"2013-05-16T10:22:52Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 5:06 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Felipe Contreras wrote:\n>>> [remote \"origin\"]\n>>>     push = refs/heads/master:refs/heads/fc/master\n>>>\n>>> [remote \".\"]\n>>>     push = refs/heads/fc/old-remote/hg:refs/heads/fc/remote/hg\n>\n> Major thinko.  It should be:\n>\n> [remote \"github\"]\n>     push = refs/heads/master:refs/heads/fc/master\n>     push = refs/heads/fc/old-remote/hg:refs/heads/fc/remote/hg\n\nWould I be able to do:\n\n% git branch --set-upstream-to origin/master --set-downstream-to\ngithub/fc/master\n\n?\n\nWould I see these branches when I do 'git branch -vv'?\nWould I be able to do 'git push next@{downstream}'?\n\n>>> Advantage being you can do:\n>>>\n>>> [remote \"origin\"]\n>>>     push = refs/heads/*:refs/for/*\n>>>\n>>> While you can't with branch.<name>.push.\n>>\n>> But I can do 'git push origin \"refs/head/*:refs/heads/for/*\"', not\n>> that I've ever had the need to do something like that, so I don't\n>> care.\n>\n> Isn't the entire point of this exercise getting git to dwim without\n> being explicit?\n>\n> I don't care about it personally either, which is why I haven't\n> written a patch yet.  However, there are users of Gerrit who would\n> appreciate this feature: in the remote.pushdefault thread, some people\n> requested this feature.\n\nThat is orthogonal to 'branch.A.push' the same way 'remote.B.fetch' is\northogonal to 'branch.A.merge'.\n\n-- \nFelipe Contreras\n"},{"id":"217577","messageId":"CAMP44s1H8g37QTdzGsfL7LDwszjDW9hj6YdmDdj54qH=ar0URA@mail.gmail.com","threadId":"33832","inReplyTo":"CALkWK0mAWUV1KgFaY2LpSQ_+=deE5wwV=Je23MuMi=6ktE+DAA@mail.gmail.com","subject":"Re: [RFC/PATCH 2/3] pull: trivial cleanups","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T10:24:06Z","receivedAt":"2013-05-16T10:24:06Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 5:18 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Felipe Contreras wrote:\n>> It doesn't matter if you think it's a bad practice or not, 'git push\n>> --mirror' works, and it's possible to update a branch even if HEAD is\n>> point to it. There should be a possibility to do the same with 'git\n>> fetch'.\n>\n> So, introduce a configuration variable to turn off this safety feature?\n\nI thought you were interested in fixing 'git pull'. My bad.\n\n-- \nFelipe Contreras\n"},{"id":"217582","messageId":"CALkWK0nBUHHkqOQannMu5Kjs00Fro8KBbiocfsT4Uf74jO9FgA@mail.gmail.com","threadId":"33832","inReplyTo":"CAMP44s1eB+bvg7vnG5S3SBACHTrkpCqJNX-Q2tzEVdvzFWvkcA@mail.gmail.com","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-16T11:31:50Z","receivedAt":"2013-05-16T11:31:50Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Felipe Contreras wrote:\n> Would I be able to do:\n>\n> % git branch --set-upstream-to origin/master --set-downstream-to\n> github/fc/master\n>\n> ?\n>\n> Would I see these branches when I do 'git branch -vv'?\n> Would I be able to do 'git push next@{downstream}'?\n\nHm, losing this functionality in the name of generality would\ncertainly be very undesirable.\n\n> That is orthogonal to 'branch.A.push' the same way 'remote.B.fetch' is\n> orthogonal to 'branch.A.merge'.\n\nNot at all (which is what I've been trying to say).\nremote.<name>.fetch is operated on by fetch, while branch.<name>.merge\nis operated on by merge; they are really orthogonal.  What happens if\nboth branch.<name>.push and remote.<name>.push are set?  What will\npush do?\n\nPerhaps we should get both, and get branch.<name>.push to override\nremote.<name>.push.  The issue being @{d} will not work if\nremote.<name>.push is set.  Then again, since we're targeting Gerrit\nusers here, I don't really think it's an issue: refs/for/master is not\nreally a \"downstream branch\"; it's a pseudo-ref that Gerrit handles\ninternally.\n"},{"id":"217583","messageId":"CALWbr2w120xDGHXB9b2UHgz5fAqX+VaSHMsaf3dhfx_5dYbruA@mail.gmail.com","threadId":"33832","inReplyTo":"CAMP44s1vMTfrSaU+0S8EOM5g4L0885780SvT_THBr7u==bJ06A@mail.gmail.com","subject":"Re: [RFC/PATCH 2/3] pull: trivial cleanups","fromName":"Antoine Pelisse","fromEmail":"apelisse@gmail.com","sentAt":"2013-05-16T11:54:37Z","receivedAt":"2013-05-16T11:54:37Z","isPatch":true,"sender":{"key":"apelisse@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1929644?v=4"},"body":"On Thu, May 16, 2013 at 11:36 AM, Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n> Actually trying that command:\n>\n> % git fetch origin 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'\n> fatal: Refusing to fetch into current branch\n> refs/heads/fc/fast-export/cleanup of non-bare repository\n> fatal: The remote end hung up unexpectedly\n\nCan you try something like this instead ?\n\n    git fetch --update-head-ok # or -u\n"},{"id":"217592","messageId":"CAMP44s2HPXnudioSSj0O_r2PbmbAqcyTORJNhRL_a=NWu_niBw@mail.gmail.com","threadId":"33832","inReplyTo":"CALkWK0nBUHHkqOQannMu5Kjs00Fro8KBbiocfsT4Uf74jO9FgA@mail.gmail.com","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T13:32:06Z","receivedAt":"2013-05-16T13:32:06Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 6:31 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Felipe Contreras wrote:\n>> Would I be able to do:\n>>\n>> % git branch --set-upstream-to origin/master --set-downstream-to\n>> github/fc/master\n>>\n>> ?\n>>\n>> Would I see these branches when I do 'git branch -vv'?\n>> Would I be able to do 'git push next@{downstream}'?\n>\n> Hm, losing this functionality in the name of generality would\n> certainly be very undesirable.\n\nI don't even know what that means.\n\n>> That is orthogonal to 'branch.A.push' the same way 'remote.B.fetch' is\n>> orthogonal to 'branch.A.merge'.\n>\n> Not at all (which is what I've been trying to say).\n> remote.<name>.fetch is operated on by fetch, while branch.<name>.merge\n> is operated on by merge; they are really orthogonal.  What happens if\n> both branch.<name>.push and remote.<name>.push are set?  What will\n> push do?\n\nThe same that 'git pull' does when both branch.<name>.merge and\nremote.<name>.fetch are set.\n\n> Perhaps we should get both, and get branch.<name>.push to override\n> remote.<name>.push.\n\nDoes branch.<name>.merge overrides remote.<name>.fetch? No. They\ncomplement each other.\n\n> The issue being @{d} will not work if\n> remote.<name>.push is set.\n\nOf course it would work. Does @{u} stop working when remote.<name>.fetch is set?\n\n> Then again, since we're targeting Gerrit\n> users here, I don't really think it's an issue: refs/for/master is not\n> really a \"downstream branch\"; it's a pseudo-ref that Gerrit handles\n> internally.\n\nIt is a downstream branch.\n\n-- \nFelipe Contreras\n"},{"id":"217593","messageId":"CAMP44s01cySnctrLjbRO6gDkFvAeoHtcSjdp11Sa8CujAKUEwA@mail.gmail.com","threadId":"33832","inReplyTo":"CALWbr2w120xDGHXB9b2UHgz5fAqX+VaSHMsaf3dhfx_5dYbruA@mail.gmail.com","subject":"Re: [RFC/PATCH 2/3] pull: trivial cleanups","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T13:36:08Z","receivedAt":"2013-05-16T13:36:08Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 6:54 AM, Antoine Pelisse <apelisse@gmail.com> wrote:\n> On Thu, May 16, 2013 at 11:36 AM, Felipe Contreras\n> <felipe.contreras@gmail.com> wrote:\n>> Actually trying that command:\n>>\n>> % git fetch origin 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'\n>> fatal: Refusing to fetch into current branch\n>> refs/heads/fc/fast-export/cleanup of non-bare repository\n>> fatal: The remote end hung up unexpectedly\n>\n> Can you try something like this instead ?\n>\n>     git fetch --update-head-ok # or -u\n\nNice! That does the trick.\n\n-- \nFelipe Contreras\n"},{"id":"217595","messageId":"CALkWK0my3kET2hdZre57NiNxiENoZ+XVLYjU-XMs+Xoche9QoQ@mail.gmail.com","threadId":"33832","inReplyTo":"CAMP44s2HPXnudioSSj0O_r2PbmbAqcyTORJNhRL_a=NWu_niBw@mail.gmail.com","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-16T13:52:58Z","receivedAt":"2013-05-16T13:52:58Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Felipe Contreras wrote:\n> Does branch.<name>.merge overrides remote.<name>.fetch? No. They\n> complement each other.\n\nI often wonder if you are reading what you're responding to:\n\nremote.<name>.fetch is operated on by fetch, while branch.<name>.merge\nis operated on by merge; they are really orthogonal.\n\n> The same that 'git pull' does when both branch.<name>.merge and\n> remote.<name>.fetch are set.\n\nAre you reading this?\n\ngit pull _fetches_ from remote.<name>.fetch and _merges_ from\nbranch.<name>.merge.  What is \"the same\" in git push terms?  It's a\nsimple question; which ref does push update: the one specified by\nremote.<name>.push or branch.<name>.push?\n\n> Of course it would work. Does @{u} stop working when remote.<name>.fetch is set?\n\nIt doesn't work when _only_ remote.<name>.fetch is set: you need\nbranch.<name>.merge to determine @{u}, just like you would need\nbranch.<name>.push to determine @{d}.\n\n> It is a downstream branch.\n\nWhich commit does git show @{d} show you?  There is no ref called\nrefs/for/master.\n"},{"id":"217597","messageId":"CAMP44s0DjCunjHHEs1SZoR502Uyk7LdGeBDz4nxqgG0GmdEDng@mail.gmail.com","threadId":"33832","inReplyTo":"CALkWK0my3kET2hdZre57NiNxiENoZ+XVLYjU-XMs+Xoche9QoQ@mail.gmail.com","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T14:53:54Z","receivedAt":"2013-05-16T14:53:54Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 8:52 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Felipe Contreras wrote:\n>> Does branch.<name>.merge overrides remote.<name>.fetch? No. They\n>> complement each other.\n>\n> I often wonder if you are reading what you're responding to:\n\nAnd I wonder if you care if what you say is actually true.\n\n> remote.<name>.fetch is operated on by fetch, while branch.<name>.merge\n> is operated on by merge; they are really orthogonal.\n\nYou keep saying they are orthogonal, but they are not. Read\nremote.c::branch_get().\n\nAnd try this:\n\n[remote \"origin\"]\n\turl = git@github.com:felipec/git.git\n\t# fetch = +refs/heads/*:refs/remotes/origin/*\n[branch \"master\"]\n\tremote = origin\n\tmerge = refs/heads/master\n\nCan you merge? No. Can you do master@{u}? No. Several other things don't work.\n\n>> The same that 'git pull' does when both branch.<name>.merge and\n>> remote.<name>.fetch are set.\n>\n> Are you reading this?\n>\n> git pull _fetches_ from remote.<name>.fetch and _merges_ from\n> branch.<name>.merge.  What is \"the same\" in git push terms?  It's a\n> simple question; which ref does push update: the one specified by\n> remote.<name>.push or branch.<name>.push?\n\n[remote]\n\tpushdefault = origin\n[remote \"origin\"]\n\tpush = refs/head/*:refs/heads/for/*\n[branch \"master\"]\n\tpushremote = github\n\tpush = refs/heads/new-master\n[branch \"next\"]\n\tpushremote = origin\n\tpush = refs/heads/new-next\n\n% git checkout master && git push\n\nWhere should it go? github/new-master. Obviously.\n\n% git checkout next && git push\n\nWhere should it go? origin/new-next. Obviously.\n\n% git checkout main && git push\n\nWhere should it go? origin/for/maint. Obviously.\n\nI don't see what the big deal is.\n\n>> Of course it would work. Does @{u} stop working when remote.<name>.fetch is set?\n>\n> It doesn't work when _only_ remote.<name>.fetch is set: you need\n> branch.<name>.merge to determine @{u}, just like you would need\n> branch.<name>.push to determine @{d}.\n\nSo? The answer is no.\n\n>> It is a downstream branch.\n>\n> Which commit does git show @{d} show you?  There is no ref called\n> refs/for/master.\n\nThe same commit 'git show @{-10000}' shows you. The fact it doesn't\nresolve to a commit doesn't mean @{-100} is not the nth-hundredth\nprevious checkout.\n\n-- \nFelipe Contreras\n"},{"id":"217598","messageId":"7va9nv7xss.fsf@alter.siamese.dyndns.org","threadId":"33832","inReplyTo":"7vip2j8ozu.fsf@alter.siamese.dyndns.org","subject":"Re: [RFC/PATCH 3/3] push: add separate 'downstream' branch","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-16T15:24:19Z","receivedAt":"2013-05-16T15:24:19Z","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> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n>> It doesn't make sense to push to the upstream branch, so create new\n>> configurations for the notion of 'downstream' branch, which is basically\n>> the branch to push to by default.\n>\n> It doesn't?  That depends.\n>\n> To people coming from (and people who are still using) central\n> shared repository workflow, pushing to anywhere other than the\n> upstream makes no sense.\n>\n> If qualified with something like \"When using a triangular workflow\n> to pull from one place and push to another place\" in front, I can\n> see why having a separate upstream and downstream makes sense, and...\n>\n>> The upstream branch is remote+merge, the downstream branch is\n>> pushremote+push.\n>\n> ... this is a perfect explanation of what a downsream is.\n\nAfter thinking about it, I do not think downstream is a good word to\ndescribe where you push to at all.\n\nI'll have more on this topic but the above is the short of it for\nnow.\n"}]}