{"thread":{"id":"33842","subject":"Random thoughts on \"upstream\"","startedAt":"2013-05-16T17:55:52Z","lastAt":"2013-05-24T06:39:49Z","messageCount":26,"participants":["Junio C Hamano","Felipe Contreras","Ramkumar Ramachandra"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"217630","messageId":"7vobca6c7r.fsf@alter.siamese.dyndns.org","threadId":"33842","inReplyTo":null,"subject":"Random thoughts on \"upstream\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-16T17:55:52Z","receivedAt":"2013-05-16T17:55:52Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"I do agree that separating\n\n - where to push to, and\n - where to fetch for integrating with\n\nis a necessary step for supporting triangular workflow better.\n\nThe \"upstream\" is that on top of which you build your work.  You\nclone from there to bootstrap yourself, you add your work (which may\ninclude integrating the work of your contributors, if you are a\nmid-tier maintainer/integrator aka a lieutenant) on top of it, and\narrange the result to reach the \"upstream\" in some way.\n\nFor the simplest (and still widely used) workflow that employs a\ncentral shared repository, the way to make the result to reach the\n\"upstream\" is by directly pushing into it yourself.  In that sense,\nthe word \"upstream\" and the traditional behaviour of \"git push\" that\npushes back to the 'origin' (or branch.$name.remote) to update your\n\"upstream\" (or branch.$name.merge at 'origin') both make perfect\nsense.\n\nAlso, if you are rebasing, @{u} refers to that place you integrate\nwith, i.e. your \"upstream\", in the central shared repository\nworkflow.\n\nBut in a triangular workflow, the way to make the result reach the\n\"upstream\" is *not* by pushing there yourself.  For developers at\nthe leaf level, it is to push to their own repository (often on\nGitHub), which is different from where they (initially) clone from\nin order to bootstrap themselves, and (subsequently) pull from in\norder to keep them up-to-date.  And then they request the published\nwork to be pulled by the \"upstream\".\n\nNote that even in a triangular workflow, @{u} should still refer to\nthe place you integrate with, i.e. your \"upstream\", not to the place\nyou push to publish the result of your work.\n\nThere is an interesting twist.  For a maintainer/integrator (either\na mid-tier one who has \"upstream\" somebody else controls, or the\ntop-level one whose conceptual \"upstream\" is himself), \"git pull\"\ndoes not necessarily always go to the \"upstream\".  You also respond\nto pull requests made to you, by those who consider you as their\n\"upstream\".  As the antonym of \"upstream\", \"downstream\" would be a\ngood word to refer to them (and that is why calling the place you\npush to \"downstream\" is not a good idea).  The integrator responds\nto such a pull request by running \"git pull\" against his\n\"downstream\".\n\nBecause an integrator will pull from more than one \"downstream\" by\ndefinition (otherwise he is merely a relay or a gatekeeper), a pull\nrequest typically carries the full URL and the branch name to be\npulled from, and there is not much need for an integrator to have a\nshort-hand mechanism to allow \"git pull\" (without other arguments on\nthe command line) to go to a \"downstream\".\n\nBut for an integrator, the place they consider their \"upstream\" is\nnot the place they push to publish.  A mid-tier integrator aka\nlieutenant has exactly the same issue as leaf developers do on the\n\"push\" side.\n\nIn a triangular workflow, \"git push\" that goes to 'origin' does not\nmake sense, and remote.pushdefault (and branch.$name.pushremote)\nsolves a half of the problem by allowing them to name the repository\nthey publish their work as the destination of a push.\n\nThe other half of the issue is that there is no good way to say \"The\nresult of my work on this branch should go to that branch in the\nrepository I publish to; they are not named the same\".\n\nThe value \"upstream\" for push.default does not make sense in the\ncontext of a triangular workflow, as you may well base your work on\n'master' from the upstream, which is a branch with a very generic\npurpose (e.g. \"to advance the state of the overall project\"), but\nyour work may have a more specific purpose (e.g. \"to improve frotz\nfeature\") that deserves to be on a branch named after that specific\npurpose in the repository you publish your work on.  That is, after\nworking on your 'frotz' branch this way:\n\n    git checkout -t -b frotz origin/master\n    work work work, commit commit commit\n\nyou do not want to push the result as 'master'; you want to call it\n'frotz' in the published repository.\n\nThe value \"current\" for push.default dictates that the work you did\non your branch 'frotz' must be published as the same name 'frotz',\nwhich may be good enough.\n\nFor those who do not find it good enough, a possible improvement is\nto introduce another mechanism that tweaks the remote.publish.push\nrefspec.  I am thinking aloud here, but imagine that you are working\non your 'frotz' branch with this configuration:\n\n    [remote \"origin\"]\n    \turl = ... this is where your upstream is ...\n        fetch = +refs/heads/*:refs/remotes/origin/*\n    [remote \"publish\"]\n        url = ... this is where you push to ...\n        ;; push = +refs/heads/*:refs/heads/topics/*\n    [remote]\n        pushdefault = publish\n    [push]\n        default = single\n\n    ; the remainder is per-branch\n    [branch \"frotz\"]\n        remote = origin\n        merge = refs/heads/master\n\nand you eventually want to push the result to topics/frotz branch\nthere.\n\nIn a triangular workflow, when you need to depend on some feature\nthat is only available in the updated upstream, you would rebase\nyour work on your upstream, e.g.\n\n    git pull --rebase\n\nwhich would go to branch.frotz.remote (= origin) and rebase your\nwork on top of their master.  Before such a rebase, you could\n\n    git fetch\n    git log ..@{u}\n\nto see what new stuff you could exploit if you did rebase now.\n\nUp to this point, there was no need to change anything; the current\nGit does the above perfectly fine.  But then you try to push:\n\n    git push\n\nThanks to the recent introduction of remote.pushdefault, this push\nwill no longer go to 'origin' but goes to 'publish'.  But not\nnecessarily to the desired branch.\n\nWith 'upstream', it may try to go to 'master' (as branch.frotz.merge\nis set there), and with 'current', it may go to 'frotz'.\n\nUncommenting\n\n    [remote \"publish\"]\n        push = +refs/heads/*:refs/heads/topics/*\n\nwill let \"git push publish\" (or \"git push\") push 'frotz' to update\n'topics/frotz' branch over there, which is what we want in this\nexample, but it will also push other branches at the same time,\nwhich is not what we want.\n\nNow I have a curious value \"single\" in the above configuration that\nis not understood by current Git.  It is to trigger a new rule to\nmodify the way remote.publish.push refspec is used:\n\n    When on branch 'frotz', where pushremote_get() would return\n    'publish', find where refs/heads/frotz would be pushed with the\n    refspec for that remote (i.e. refs/heads/*:refs/heads/topics/*\n    maps refs/heads/frotz to refs/heads/topics/frotz) and push only\n    that, i.e. update refs/heads/topics/frotz over there with the\n    tip of 'frotz' we are pushing.\n\nThat may be a solution for those who do not find 'current' good\nenough.\n"},{"id":"217652","messageId":"CAMP44s2t3+yBQMj9uSd_=3w0CgeJsHeAQM051j7Xt+SqVthvzQ@mail.gmail.com","threadId":"33842","inReplyTo":"7vobca6c7r.fsf@alter.siamese.dyndns.org","subject":"Re: Random thoughts on \"upstream\"","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-16T23:03:55Z","receivedAt":"2013-05-16T23:03:55Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 12:55 PM, Junio C Hamano <gitster@pobox.com> wrote:\n\n> The value \"upstream\" for push.default does not make sense in the\n> context of a triangular workflow, as you may well base your work on\n> 'master' from the upstream, which is a branch with a very generic\n> purpose (e.g. \"to advance the state of the overall project\"), but\n> your work may have a more specific purpose (e.g. \"to improve frotz\n> feature\") that deserves to be on a branch named after that specific\n> purpose in the repository you publish your work on.  That is, after\n> working on your 'frotz' branch this way:\n>\n>     git checkout -t -b frotz origin/master\n>     work work work, commit commit commit\n\nIf the user has branch.autosetupmerge=always, that's not correct; even doing:\n\n% git checkout -b frotz origin/master\n\nWould setup the upstream. And I believe for v2.0 we do want\nbranch.autosetupmerge=always, but we might not want to always override\nthe push location.\n\n> Now I have a curious value \"single\" in the above configuration that\n> is not understood by current Git.  It is to trigger a new rule to\n> modify the way remote.publish.push refspec is used:\n>\n>     When on branch 'frotz', where pushremote_get() would return\n>     'publish', find where refs/heads/frotz would be pushed with the\n>     refspec for that remote (i.e. refs/heads/*:refs/heads/topics/*\n>     maps refs/heads/frotz to refs/heads/topics/frotz) and push only\n>     that, i.e. update refs/heads/topics/frotz over there with the\n>     tip of 'frotz' we are pushing.\n>\n> That may be a solution for those who do not find 'current' good\n> enough.\n\nWhat happens if I want to push to 'refs/heads/topics/frotz-for-juno'?\n\n-- \nFelipe Contreras\n"},{"id":"217658","messageId":"7vobca3465.fsf@alter.siamese.dyndns.org","threadId":"33842","inReplyTo":"CAMP44s2t3+yBQMj9uSd_=3w0CgeJsHeAQM051j7Xt+SqVthvzQ@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-16T23:17:54Z","receivedAt":"2013-05-16T23:17:54Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> On Thu, May 16, 2013 at 12:55 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>\n>> The value \"upstream\" for push.default does not make sense in the\n>> context of a triangular workflow, as you may well base your work on\n>> 'master' from the upstream, which is a branch with a very generic\n>> purpose (e.g. \"to advance the state of the overall project\"), but\n>> your work may have a more specific purpose (e.g. \"to improve frotz\n>> feature\") that deserves to be on a branch named after that specific\n>> purpose in the repository you publish your work on.  That is, after\n>> working on your 'frotz' branch this way:\n>>\n>>     git checkout -t -b frotz origin/master\n>>     work work work, commit commit commit\n>\n> If the user has branch.autosetupmerge=always, that's not correct; even doing:\n>\n> % git checkout -b frotz origin/master\n>\n> Would setup the upstream. And I believe for v2.0 we do want\n> branch.autosetupmerge=always, but we might not want to always override\n> the push location.\n>\n>> Now I have a curious value \"single\" in the above configuration that\n>> is not understood by current Git.  It is to trigger a new rule to\n>> modify the way remote.publish.push refspec is used:\n>>\n>>     When on branch 'frotz', where pushremote_get() would return\n>>     'publish', find where refs/heads/frotz would be pushed with the\n>>     refspec for that remote (i.e. refs/heads/*:refs/heads/topics/*\n>>     maps refs/heads/frotz to refs/heads/topics/frotz) and push only\n>>     that, i.e. update refs/heads/topics/frotz over there with the\n>>     tip of 'frotz' we are pushing.\n>>\n>> That may be a solution for those who do not find 'current' good\n>> enough.\n>\n> What happens if I want to push to 'refs/heads/topics/frotz-for-juno'?\n\nYou would weigh pros-and-cons of supporting such a \"single branch\nonly\" special case, and add a branch level override, and if the\nbenefit outweighs the cost of complexity, design and implement it.\n\nThe push.default setting is to make sure we have a simple mechanism\nto cover more common cases, and my suspicion is what 'current' gives\nus is already there without the need for 'single'.\n"},{"id":"217667","messageId":"CAMP44s1dB+VQnzPL-qVADMTC6-Y8AfUvBOmy+4kusujyT_jW4g@mail.gmail.com","threadId":"33842","inReplyTo":"7vobca3465.fsf@alter.siamese.dyndns.org","subject":"Re: Random thoughts on \"upstream\"","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-17T00:00:50Z","receivedAt":"2013-05-17T00:00:50Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 6:17 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n>> On Thu, May 16, 2013 at 12:55 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>>\n>>> The value \"upstream\" for push.default does not make sense in the\n>>> context of a triangular workflow, as you may well base your work on\n>>> 'master' from the upstream, which is a branch with a very generic\n>>> purpose (e.g. \"to advance the state of the overall project\"), but\n>>> your work may have a more specific purpose (e.g. \"to improve frotz\n>>> feature\") that deserves to be on a branch named after that specific\n>>> purpose in the repository you publish your work on.  That is, after\n>>> working on your 'frotz' branch this way:\n>>>\n>>>     git checkout -t -b frotz origin/master\n>>>     work work work, commit commit commit\n>>\n>> If the user has branch.autosetupmerge=always, that's not correct; even doing:\n>>\n>> % git checkout -b frotz origin/master\n>>\n>> Would setup the upstream. And I believe for v2.0 we do want\n>> branch.autosetupmerge=always, but we might not want to always override\n>> the push location.\n>>\n>>> Now I have a curious value \"single\" in the above configuration that\n>>> is not understood by current Git.  It is to trigger a new rule to\n>>> modify the way remote.publish.push refspec is used:\n>>>\n>>>     When on branch 'frotz', where pushremote_get() would return\n>>>     'publish', find where refs/heads/frotz would be pushed with the\n>>>     refspec for that remote (i.e. refs/heads/*:refs/heads/topics/*\n>>>     maps refs/heads/frotz to refs/heads/topics/frotz) and push only\n>>>     that, i.e. update refs/heads/topics/frotz over there with the\n>>>     tip of 'frotz' we are pushing.\n>>>\n>>> That may be a solution for those who do not find 'current' good\n>>> enough.\n>>\n>> What happens if I want to push to 'refs/heads/topics/frotz-for-juno'?\n>\n> You would weigh pros-and-cons of supporting such a \"single branch\n> only\" special case, and add a branch level override, and if the\n> benefit outweighs the cost of complexity, design and implement it.\n\nI already implemented it. I already sent the patch.\n\n-- \nFelipe Contreras\n"},{"id":"217671","messageId":"7vzjvu1jes.fsf@alter.siamese.dyndns.org","threadId":"33842","inReplyTo":"7vobca3465.fsf@alter.siamese.dyndns.org","subject":"Re: Random thoughts on \"upstream\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-17T01:31:39Z","receivedAt":"2013-05-17T01:31:39Z","isPatch":false,"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>> What happens if I want to push to 'refs/heads/topics/frotz-for-juno'?\n>\n> You would weigh pros-and-cons of supporting such a \"single branch\n> only\" special case, and add a branch level override, and if the\n> benefit outweighs the cost of complexity, design and implement it.\n>\n> The push.default setting is to make sure we have a simple mechanism\n> to cover more common cases, and my suspicion is what 'current' gives\n> us is already there without the need for 'single'.\n\nActually, I suspect that you shouldn't even need to do that\npros-and-cons analysis, because the 'single' thing should cover as a\nnatural extension of the existing infrastructure.  You should only\nneed to have something like this:\n\n\t[remote \"there\"]\n        \turl = ... were you push ...\n\t\tpush = refs/heads/frotz:refs/heads/topics/frotz-for-juno\n                push = refs/heads/*:refs/heads/topics/*\n\nWithout the 'single', your 'frotz' will be pushed to update\nheads/topics/frotz-for-juno, not heads/topics/frotz, because the\nexact refspec match will prevent it from matched twice by the\nwildcarded one.  The imagined 'single' mode would just limit the\npush to the current branch, so it would end up pushing to the branch\nyou want to update, without sending an extra copy to the same name.\n"},{"id":"217673","messageId":"CAMP44s1atVbN6CXAud4XzkKjAJOwoobF5uiXX12pBut0Becydw@mail.gmail.com","threadId":"33842","inReplyTo":"7vzjvu1jes.fsf@alter.siamese.dyndns.org","subject":"Re: Random thoughts on \"upstream\"","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-17T01:59:38Z","receivedAt":"2013-05-17T01:59:38Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 8:31 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>>\n>>> What happens if I want to push to 'refs/heads/topics/frotz-for-juno'?\n>>\n>> You would weigh pros-and-cons of supporting such a \"single branch\n>> only\" special case, and add a branch level override, and if the\n>> benefit outweighs the cost of complexity, design and implement it.\n>>\n>> The push.default setting is to make sure we have a simple mechanism\n>> to cover more common cases, and my suspicion is what 'current' gives\n>> us is already there without the need for 'single'.\n>\n> Actually, I suspect that you shouldn't even need to do that\n> pros-and-cons analysis, because the 'single' thing should cover as a\n> natural extension of the existing infrastructure.  You should only\n> need to have something like this:\n>\n>         [remote \"there\"]\n>                 url = ... were you push ...\n>                 push = refs/heads/frotz:refs/heads/topics/frotz-for-juno\n>                 push = refs/heads/*:refs/heads/topics/*\n>\n> Without the 'single', your 'frotz' will be pushed to update\n> heads/topics/frotz-for-juno, not heads/topics/frotz, because the\n> exact refspec match will prevent it from matched twice by the\n> wildcarded one.  The imagined 'single' mode would just limit the\n> push to the current branch, so it would end up pushing to the branch\n> you want to update, without sending an extra copy to the same name.\n\nAnd would 'git branch --set-downstream-to github/frotz-for-juno' do\nthat? If not it's basically useless for 99% of the users who never\nfiddle with push refspecs.\n\n-- \nFelipe Contreras\n"},{"id":"217674","messageId":"CAMP44s1J6xvxTKhf79QvLGxDWUWKYe+et=g3RTA_a5_UaymKEw@mail.gmail.com","threadId":"33842","inReplyTo":"CAMP44s1atVbN6CXAud4XzkKjAJOwoobF5uiXX12pBut0Becydw@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-17T02:00:36Z","receivedAt":"2013-05-17T02:00:36Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 16, 2013 at 8:59 PM, Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n> On Thu, May 16, 2013 at 8:31 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Junio C Hamano <gitster@pobox.com> writes:\n>>\n>>> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>>>\n>>>> What happens if I want to push to 'refs/heads/topics/frotz-for-juno'?\n>>>\n>>> You would weigh pros-and-cons of supporting such a \"single branch\n>>> only\" special case, and add a branch level override, and if the\n>>> benefit outweighs the cost of complexity, design and implement it.\n>>>\n>>> The push.default setting is to make sure we have a simple mechanism\n>>> to cover more common cases, and my suspicion is what 'current' gives\n>>> us is already there without the need for 'single'.\n>>\n>> Actually, I suspect that you shouldn't even need to do that\n>> pros-and-cons analysis, because the 'single' thing should cover as a\n>> natural extension of the existing infrastructure.  You should only\n>> need to have something like this:\n>>\n>>         [remote \"there\"]\n>>                 url = ... were you push ...\n>>                 push = refs/heads/frotz:refs/heads/topics/frotz-for-juno\n>>                 push = refs/heads/*:refs/heads/topics/*\n>>\n>> Without the 'single', your 'frotz' will be pushed to update\n>> heads/topics/frotz-for-juno, not heads/topics/frotz, because the\n>> exact refspec match will prevent it from matched twice by the\n>> wildcarded one.  The imagined 'single' mode would just limit the\n>> push to the current branch, so it would end up pushing to the branch\n>> you want to update, without sending an extra copy to the same name.\n>\n> And would 'git branch --set-downstream-to github/frotz-for-juno' do\n> that? If not it's basically useless for 99% of the users who never\n> fiddle with push refspecs.\n\nAnd 'git branch -vv' would not show that either. Nor can the user do\n'@{downstream}'.\n\n-- \nFelipe Contreras\n"},{"id":"217710","messageId":"CALkWK0=rHFQ14G8baYpY7gYo+Qb+5a0qOKZGBTrp6BamKC2vRg@mail.gmail.com","threadId":"33842","inReplyTo":"7vzjvu1jes.fsf@alter.siamese.dyndns.org","subject":"Re: Random thoughts on \"upstream\"","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-17T12:43:13Z","receivedAt":"2013-05-17T12:43:13Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n> Actually, I suspect that you shouldn't even need to do that\n> pros-and-cons analysis, because the 'single' thing should cover as a\n> natural extension of the existing infrastructure.  You should only\n> need to have something like this:\n\nWhich is the exact argument I presented on the other thread.  However,\nFelipe has a point: we shouldn't cripple @{f} (I think \"fork\" is a\ngood name for it) in the name of generality.  Think of what\nremote.<name>.push and branch.<name>.push are actually going to be\nused for:\n\nremote.<name>.push are most probably going to be used with wildcards\n(like in the Gerrit case): I don't mind if @{f} is not able to tell me\nwhere my branch will go (and it's probably even a pseudo-ref, in which\ncase the answer is really meaningless).  The limitation doesn't affect\nremote.<name>.fetch, because @{u} only operates between remote\nbranches and local branches, not at the ref-mapping level.\n\nbranch.<name>.push cannot be used with wildcards, and @{f} is pretty\nstraightforward to determine in this case.  When the information is\neasily available for end-user consumption, why would we _not_ want to\nexpose it by stuffing branch.<name>.push into remote.<name>.push\nconfiguration?\n\nSo, I think the way forward is:\n\n1. Introduce @{f[ork]} to show $(branch.<name>.pushremote or\nremote.pushdefault)/$(HEAD).  We can update 'git status' to show this\ninformation as well: the ahead/ behind with @{f} is no less important.\n\n2. (optional) Make remote.<name>.fetch non-mandatory.  Currently, a\nlot of git-core breaks unless this is present, and this is an annoying\nwart.\n\n3. Introduce remote.<name>.push.  Make it clear that it is intended\nfor the Gerrit-user.  @{f} cannot be determined with this [*1*].\n\n4. Introduce branch.<name>.push for a branch-specific override to\nremote.<name>.push.  @{f} can be determined when this is in effect.\n\n[Footnotes]\n\n*1* Do we want to do some magic wildcard-expansion to get/set @{f}\nanyway?  In which case, branch.<name>.push is really not necessary.\nWhich approach is less ugly?\n"},{"id":"217723","messageId":"7vk3mx1rox.fsf@alter.siamese.dyndns.org","threadId":"33842","inReplyTo":"CALkWK0=rHFQ14G8baYpY7gYo+Qb+5a0qOKZGBTrp6BamKC2vRg@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-17T16:45:02Z","receivedAt":"2013-05-17T16:45:02Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> Which is the exact argument I presented on the other thread.  However,\n> Felipe has a point: we shouldn't cripple @{f} (I think \"fork\" is a\n> good name for it) in the name of generality.\n\nPlease clarify the semantics of @{f}.  Does it conceptually refer to\nwhere the current branch is going to be pushed to (i.e. a pair of\n(<remote>, <ref>))?  Will we have a remote tracking branch for it\nto record what we pushed there the last time?  I am guessing that\nyour answers to both of these questions are \"Yes\", and frotz@{f}\nwould resolve to refs/remotes/there/topics/frotz-for-juno in the\nsample set-up in the message you are responding to.\n\n\tSide note: I do not think \"fork\" rings bell to the end\n\tusers.  Who is forking from what?  I am guessing you are\n\ttrying to make a short form of \"the branch in my public\n\tpepository I push this branch to, and other people would\n\tconsider it my fork of the upstream project\", but it is hard\n\tto do the reverse, i.e. a new person who is presented a word\n\t'fork' to guess that you wanted to refer to the above by\n\tthat word.\n\nI am not saying branch.<name>.push should not exist.  Having a\nfinest-grained special case would be an escape hatch you can use\nwhen you want to do something unusual.\n\nBut it has exactly the same issue as branch.<name>.pushremote;\nadding it without having the single \"all of my pushes go to here,\nnot to 'origin'\" would have meant that for N branches you have to\nset the same thing N times.  We fixed it with remote.pushdefault\nbefore the series graduated.  If you only add branch.<name>.push,\nthen people have to configure it N times, for N branches they want\nto push out.\n\nReusing the existing push refspecs was just a suggestion to solve\nthat issue, and I am not married to that particular design.  You or\nFelipe may be able to come up with a better alternative to achieve\nthe same goal and that is perfectly fine.  I just wanted to make\nsure that we do not force the user to repeatedly set the same thing\nover and over in the common case.\n\nBy the way, about \"crippling\".\n\nI do not think of a reason why you cannot implement that @{f} with\nthe 'single' matching (or its better version you may come up with).\nIf \"git push\" can figure out where it would push to, you certainly\nshould be able to borrow that same logic to see what tracking branch\nyou are locally using to track the last push result for the current\nbranch in response to @{f} request, no?\n"},{"id":"217728","messageId":"CALkWK0mLtc8dmMPOcLMez1agF1+ZMUDAUwtwmiKSxOCfyiW0Bw@mail.gmail.com","threadId":"33842","inReplyTo":"7vk3mx1rox.fsf@alter.siamese.dyndns.org","subject":"Re: Random thoughts on \"upstream\"","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-17T17:01:13Z","receivedAt":"2013-05-17T17:01:13Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n> Please clarify the semantics of @{f}.  Does it conceptually refer to\n> where the current branch is going to be pushed to (i.e. a pair of\n> (<remote>, <ref>))?  Will we have a remote tracking branch for it\n> to record what we pushed there the last time?  I am guessing that\n> your answers to both of these questions are \"Yes\", and frotz@{f}\n> would resolve to refs/remotes/there/topics/frotz-for-juno in the\n> sample set-up in the message you are responding to.\n\nYes.\n\n>         Side note: I do not think \"fork\" rings bell to the end\n>         users.  Who is forking from what?  I am guessing you are\n>         trying to make a short form of \"the branch in my public\n>         pepository I push this branch to, and other people would\n>         consider it my fork of the upstream project\", but it is hard\n>         to do the reverse, i.e. a new person who is presented a word\n>         'fork' to guess that you wanted to refer to the above by\n>         that word.\n\nGitHub is an overwhelmingly popular service, and many end-users are\nused to clicking on the \"Fork\" button on various projects to\ncontribute.  Here, \"fork\" is short for \"my fork\".  Do you have a\nbetter name in mind?\n\n> But it has exactly the same issue as branch.<name>.pushremote;\n> adding it without having the single \"all of my pushes go to here,\n> not to 'origin'\" would have meant that for N branches you have to\n> set the same thing N times.  We fixed it with remote.pushdefault\n> before the series graduated.  If you only add branch.<name>.push,\n> then people have to configure it N times, for N branches they want\n> to push out.\n\nOh, I'm completely against just adding branch.<name>.push as I've\npointed out on the other thread.  Even in the part you clipped out, I\nclearly stated remote.<name>.push above a branch-specific thing in the\npriorities.\n\n> Reusing the existing push refspecs was just a suggestion to solve\n> that issue, and I am not married to that particular design.  You or\n> Felipe may be able to come up with a better alternative to achieve\n> the same goal and that is perfectly fine.  I just wanted to make\n> sure that we do not force the user to repeatedly set the same thing\n> over and over in the common case.\n\nOfcourse.\n\n> I do not think of a reason why you cannot implement that @{f} with\n> the 'single' matching (or its better version you may come up with).\n> If \"git push\" can figure out where it would push to, you certainly\n> should be able to borrow that same logic to see what tracking branch\n> you are locally using to track the last push result for the current\n> branch in response to @{f} request, no?\n\nOfcourse, I'm not saying it's not possible.\n\n1. Getting @{f} requires extra computation, and that might be ugly/\nundesirable/ surprising considering how @{u} doesn't require it.\n\n2. Setting @{f} with branch --set-fork-to won't operate on the\nbranch.<name> section, and this might be surprising.\n\n3. If remote.<name>.push is only going to be used by the Gerrit\npeople, @{f} is not going to work anyway.\n\nThese issues aren't deal breakers, but are certainly worth mentioning.\n Frankly, I'm not overtly fond of the branch.<name>.push idea, and am\ntilting towards this now.  What do you think?\n"},{"id":"217744","messageId":"7vk3mxze8v.fsf@alter.siamese.dyndns.org","threadId":"33842","inReplyTo":"CALkWK0mLtc8dmMPOcLMez1agF1+ZMUDAUwtwmiKSxOCfyiW0Bw@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-17T17:51:28Z","receivedAt":"2013-05-17T17:51:28Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> Junio C Hamano wrote:\n>\n>>         Side note: I do not think \"fork\" rings bell to the end\n>>         users.  Who is forking from what?  I am guessing you are\n>>         trying to make a short form of \"the branch in my public\n>>         pepository I push this branch to, and other people would\n>>         consider it my fork of the upstream project\", but it is hard\n>>         to do the reverse, i.e. a new person who is presented a word\n>>         'fork' to guess that you wanted to refer to the above by\n>>         that word.\n>\n> GitHub is an overwhelmingly popular service, and many end-users are\n> used to clicking on the \"Fork\" button on various projects to\n> contribute.  Here, \"fork\" is short for \"my fork\".  Do you have a\n> better name in mind?\n\nIn my original \"Random thoughts\", I deliberately avoided introducing\na new name for the publishing point, because I did not think of a\ngood name myself (\"publish\" for \"what I publish this as?\" was what I\nhad in mind, and while it is better than \"downstream\" which this\nthing clearly isn't, I do not think it is a great name).\n\nAs I said number of times, I am not good at naming, even though I\ncan tell when a proposed name (like \"publish\") is not a good one\nX-<.\n\nMatching it with the way to set this per-branch might be a good\nalternative.  If branch.<name>.push is it, then it would mean\n\"@{push}\".\n\n> Ofcourse, I'm not saying it's not possible.\n>\n> 1. Getting @{f} requires extra computation, and that might be ugly/\n> undesirable/ surprising considering how @{u} doesn't require it.\n\nThis is minor, but I am not sure \"doesn't require it\" part should\nalways stay true in the first place.  If you are always forking your\n'master' from the upstream 'master' and your 'next' from the\nupstream 'next', there is no real reason why the user must record an\nobvious value in branch.master.merge and branch.next.merge\nvariables.\n\n> 2. Setting @{f} with branch --set-fork-to won't operate on the\n> branch.<name> section, and this might be surprising.\n\nHmm, why?\n\nAs I said, I do _not_ mean branch.<name>.push must _not_ exist.\n\nSetting it explicitly with --fork-to or whatever option is perfectly\nfine; the logic to resolve @{f} notation would honor it naturally if\nyou reused the same logic as \"git push\" decides where to push, no?\n\n> 3. If remote.<name>.push is only going to be used by the Gerrit\n> people, @{f} is not going to work anyway.\n\nI do not understand what you mean by this.\n\n> These issues aren't deal breakers, but are certainly worth mentioning.\n> Frankly, I'm not overtly fond of the branch.<name>.push idea, and am\n> tilting towards this now.  What do you think?\n\nI think I'd better rephrase what I wanted to say in the message you\nare responding to.\n\n * \"branch.<name>.push\" would be a way to set per-branch push\n   destination. There may be other ways to do the same but I do not\n   think it is bad and it probably will fall into bikeshedding\n   category to attempt to come up with something different for the\n   same purpose of setting per-branch destination.\n\n * There should be a mechanism to allow people _not_ configure it\n   per-branch if they do not want to push to randomly custimized\n   destinations per-branch (i.e. want to always push $branch to\n   refs/heads/$branch, or refs/remotes/satellite/$branch).\n\nSo that is what I think.\n\nHaving said that I am not sure where your \"not overly fond of\" comes\nfrom, as I do not see a problem with branch.<name>.push.  The only\nproblem I may have with the approach would arise _only_ if we make\nit the sole way to allow people push to different names, forcing\npeople who want to push N branches to configure it N times.  Other\nthan that, I think it is an acceptable solution to give per-branch\ncontrol.\n"},{"id":"217822","messageId":"CALkWK0kYKZGhthdrb6-7RD_c2A7E9rscAZU3=JHM-4rYre6w=Q@mail.gmail.com","threadId":"33842","inReplyTo":"7vk3mxze8v.fsf@alter.siamese.dyndns.org","subject":"Re: Random thoughts on \"upstream\"","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-18T18:27:41Z","receivedAt":"2013-05-18T18:27:41Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n> Having said that I am not sure where your \"not overly fond of\" comes\n> from, as I do not see a problem with branch.<name>.push.  The only\n> problem I may have with the approach would arise _only_ if we make\n> it the sole way to allow people push to different names, forcing\n> people who want to push N branches to configure it N times.  Other\n> than that, I think it is an acceptable solution to give per-branch\n> control.\n\nIt doesn't strike me as being elegant at all.\n\n[branch \"hot-branch\"]\n    remote = ram\n    push = refs/heads/for-junio/hot-branch\n\n1.  I git branch -M for-each-ref and push.  Screwed.\n\n2.  Let's say you give me the thumbs up to write hot-branch to origin.\n Excitedly, I change the remote to origin.  Now I already have push\nsemantics for origin (you obviously want me to write to rr/, so I can\ncooperate with others):\n\n[remote \"origin\"]\n    push = refs/heads/*:refs/heads/rr/*\n\nUnfortunately, it doesn't kick in unless I change branch.<name>.push.\n\nI guess what I'm saying is: refspec semantics are inherent properties\nof the remote, not of the local branch.  Since there is no\nintermediate refs/remotes/* sitting between the remote and local\nbranches, this is _not_ like branch.<name>.merge at all.  That is why\nI'm tiling towards remote.<name>.push: we're not giving up any\nfunctionality anyway; there's nothing we can't do without\nbranch.<name>.push.\n"},{"id":"217828","messageId":"CALkWK0=0SwWW+LC3iPy=A9tLBOxrXgYH1cYNazrchv3_jU_oMg@mail.gmail.com","threadId":"33842","inReplyTo":"CALkWK0kYKZGhthdrb6-7RD_c2A7E9rscAZU3=JHM-4rYre6w=Q@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-18T20:07:51Z","receivedAt":"2013-05-18T20:07:51Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Ramkumar Ramachandra wrote:\n> I guess what I'm saying is: refspec semantics are inherent properties\n> of the remote, not of the local branch.\n\n[remote \"ram\"]\n    push = refs/heads/link:refs/heads/for-junio/link\n\nis saying: if the branch name matches \"link\", push it to for-junio/link.\n\n[branch \"link\"]\n    push = refs/heads/for-junio/link\n\nis saying: push _this_ branch to for-junio/link, irrespective of what\nit is called.\n\nAn example illustrating this clearly:\n\n# on branch link-v2\n# work ...\n$ git push\n# work ...\n# ok, I'm ready to replace link\n$ git branch -M link\n$ git push\n# where should the push go?\n\nAlso: putting branch-specific configuration in remote.<name>.push\nwould mean that it can potentially accumulate a lot of cruft from\ndeleted branches.  It's the same kind problem we face with .gitignore,\nno?\n"},{"id":"217833","messageId":"CAMP44s1Rv1zobP99z6dNKhSXgBgvWa+1-BZL-Pi1HWo3vrK6vw@mail.gmail.com","threadId":"33842","inReplyTo":"CALkWK0kYKZGhthdrb6-7RD_c2A7E9rscAZU3=JHM-4rYre6w=Q@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-18T22:33:30Z","receivedAt":"2013-05-18T22:33:30Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Sat, May 18, 2013 at 1:27 PM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Junio C Hamano wrote:\n>> Having said that I am not sure where your \"not overly fond of\" comes\n>> from, as I do not see a problem with branch.<name>.push.  The only\n>> problem I may have with the approach would arise _only_ if we make\n>> it the sole way to allow people push to different names, forcing\n>> people who want to push N branches to configure it N times.  Other\n>> than that, I think it is an acceptable solution to give per-branch\n>> control.\n>\n> It doesn't strike me as being elegant at all.\n>\n> [branch \"hot-branch\"]\n>     remote = ram\n>     push = refs/heads/for-junio/hot-branch\n\ns/remote/pushremote/\n\n> 1.  I git branch -M for-each-ref and push.  Screwed.\n\nCan't parse that.\n\n> 2.  Let's say you give me the thumbs up to write hot-branch to origin.\n>  Excitedly, I change the remote to origin.  Now I already have push\n> semantics for origin (you obviously want me to write to rr/, so I can\n> cooperate with others):\n>\n> [remote \"origin\"]\n>     push = refs/heads/*:refs/heads/rr/*\n>\n> Unfortunately, it doesn't kick in unless I change branch.<name>.push.\n\nIf course it doesn't that's what you told git to do. Of course, you\ncould simply do:\n\n% git branch --set-downstream-to origin/rr/for-junio/hot-branch\n\nOr if you are going to push multiple branches and set a 'remote.<name>.push':\n\n% git branch --unset-downstream\n\n> I guess what I'm saying is: refspec semantics are inherent properties\n> of the remote, not of the local branch.  Since there is no\n> intermediate refs/remotes/* sitting between the remote and local\n> branches, this is _not_ like branch.<name>.merge at all.  That is why\n> I'm tiling towards remote.<name>.push: we're not giving up any\n> functionality anyway; there's nothing we can't do without\n> branch.<name>.push.\n\nYes there is, I thought you already acknowledged that:\n\n% git branch --set-downstream-to github/fc/master\n% git rebase -i @{downstream}\n\n-- \nFelipe Contreras\n"},{"id":"217834","messageId":"CAMP44s29L1Yr0mQjUmUBr7Zm9NouG5_vrQ4cZ=TY2QbLKMB9eA@mail.gmail.com","threadId":"33842","inReplyTo":"CALkWK0=0SwWW+LC3iPy=A9tLBOxrXgYH1cYNazrchv3_jU_oMg@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-18T22:36:23Z","receivedAt":"2013-05-18T22:36:23Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Sat, May 18, 2013 at 3:07 PM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Ramkumar Ramachandra wrote:\n>> I guess what I'm saying is: refspec semantics are inherent properties\n>> of the remote, not of the local branch.\n>\n> [remote \"ram\"]\n>     push = refs/heads/link:refs/heads/for-junio/link\n>\n> is saying: if the branch name matches \"link\", push it to for-junio/link.\n>\n> [branch \"link\"]\n>     push = refs/heads/for-junio/link\n>\n> is saying: push _this_ branch to for-junio/link, irrespective of what\n> it is called.\n>\n> An example illustrating this clearly:\n>\n> # on branch link-v2\n> # work ...\n> $ git push\n> # work ...\n> # ok, I'm ready to replace link\n> $ git branch -M link\n> $ git push\n> # where should the push go?\n\nExactly where you told it to go.\n\n> Also: putting branch-specific configuration in remote.<name>.push\n> would mean that it can potentially accumulate a lot of cruft from\n> deleted branches.  It's the same kind problem we face with .gitignore,\n> no?\n\nNot many people would use 'remote.<name>.push' and in very specific\ncircumstances. It's not a problem.\n\n-- \nFelipe Contreras\n"},{"id":"217840","messageId":"7vmwrr1pem.fsf@alter.siamese.dyndns.org","threadId":"33842","inReplyTo":"CALkWK0kYKZGhthdrb6-7RD_c2A7E9rscAZU3=JHM-4rYre6w=Q@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-19T05:58:57Z","receivedAt":"2013-05-19T05:58:57Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> Junio C Hamano wrote:\n>> Having said that I am not sure where your \"not overly fond of\" comes\n>> from, as I do not see a problem with branch.<name>.push.  The only\n>> problem I may have with the approach would arise _only_ if we make\n>> it the sole way to allow people push to different names, forcing\n>> people who want to push N branches to configure it N times.  Other\n>> than that, I think it is an acceptable solution to give per-branch\n>> control.\n>\n> It doesn't strike me as being elegant at all.\n>\n> [branch \"hot-branch\"]\n>     remote = ram\n>     push = refs/heads/for-junio/hot-branch\n>\n> 1.  I git branch -M for-each-ref and push.  Screwed.\n\n-ECANTSEEWHATYOUMEAN.  Your proofreader is screwed ;-)\n\n> 2.  Let's say you give me the thumbs up to write hot-branch to origin.\n>  Excitedly, I change the remote to origin.  Now I already have push\n> semantics for origin (you obviously want me to write to rr/, so I can\n> cooperate with others):\n>\n> [remote \"origin\"]\n>     push = refs/heads/*:refs/heads/rr/*\n>\n> Unfortunately, it doesn't kick in unless I change branch.<name>.push.\n\nI thought branch.$name.push is \"What ref do I push this out as?\"\n\nAt this point you have two remotes, me as your upstream, and your\npublishing point, and remote.pushdefault set to the latter since\noriginally you cannot push to 'origin':\n\n    [push]\n        default = simple ;# adopt 2.0 default early\n    [remote]\n        pushdefault = ram\n\n    [remote \"ram\"}\n\turl = github.com:ram/something.git\n        fetch = +refs/heads/*:refs/remotes/ram/*\n        push = +refs/heads/*:refs/heads/*\n\n    [remote \"origin\"]\n        url = git://git.kernel.org/pub/scm/git/git.git\n        fetch = +refs/heads/*:refs/remotes/origin/*\n\n    # assuming you forked from my master\n    [branch \"hot-branch\"]\n        remote = origin\n        merge = refs/heads/master\n   +    pushremote = origin\n   +    push = refs/heads/rr/hot-branch\n\nThe above pseudo-diff would be the changes you would be making to\nyour configuration when you were asked to push your 'hot-branch' to\n'origin' as 'rr/hot-branch', I think.\n\nIf somebody implements the \"push.default = single\" (see the original\nmessage you are responding to), then the change might be smaller.\n\n    [push]\n   -    default = simple ;# adopt 2.0 default early\n   +    default = single\n\n    [remote]\n        pushdefault = ram\n\n    [remote \"ram\"}\n\turl = github.com:ram/something.git\n        fetch = +refs/heads/*:refs/remotes/ram/*\n        push = +refs/heads/*:refs/heads/*\n\n    [remote \"origin\"]\n        url = git://git.kernel.org/pub/scm/git/git.git\n        fetch = +refs/heads/*:refs/remotes/origin/*\n   +    push = +refs/heads/*:refs/heads/rr/*\n\n    # assuming you forked from my master\n    [branch \"hot-branch\"]\n        remote = origin\n        merge = refs/heads/master\n   +    pushremote = origin\n\n> I guess what I'm saying is: refspec semantics are inherent\n> properties of the remote, not of the local branch.  Since there is\n> no intermediate refs/remotes/* sitting between the remote and\n> local branches, this is _not_ like branch.<name>.merge at all.\n\nSomewhat true, if you write this with branch.hot-branch.push without\npush.default=single implicitly introduces\n\n\trefs/heads/hot-branch:refs/heads/rr/hot-branch\n\nrefspec to the remote named by branch.hot-branch.pushremote.\n"},{"id":"217883","messageId":"CALkWK0=6L529C452MaNGksL5KeVb+cL1SeC=FwA9veS=tNQurA@mail.gmail.com","threadId":"33842","inReplyTo":"7vmwrr1pem.fsf@alter.siamese.dyndns.org","subject":"Re: Random thoughts on \"upstream\"","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-19T11:44:43Z","receivedAt":"2013-05-19T11:44:43Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n> If somebody implements the \"push.default = single\" (see the original\n> message you are responding to), then the change might be smaller.\n\nI think this is a bad hack covering up an underlying problem: it is\nugly, confusing, and inextensible in my opinion.  I think of\npush.default as merely a default remote.<name>.push value for all\nremotes, that can be overridden on a per-remote basis.\n\nI suspect that the issue you're trying to address is:\n\n[remote \"ram\"]\n    push = refs/heads/*:refs/heads/rr/*\n\nnot dictating which refs to push when I say 'git push' (it'll push all\nthe refs under refs/heads/*, not respecting push.default=current in my\nscheme).  That is a valid problem, and it is a problem with our\nrefspec: I can say \"HEAD\" (which is what push.default=current is) to\nmean current branch, but I can't dictate the rhs of the refspec then.\nIn other words, I cannot have the refspec \"HEAD:refs/heads/rr/%1\", and\n_this_ is the problem.\n\nWhat do you think?\n"},{"id":"217884","messageId":"CAMP44s3HaEc1UoULYHYnzd_B_VayfedG_Gd1gT27=SeMdp4=eg@mail.gmail.com","threadId":"33842","inReplyTo":"CALkWK0=6L529C452MaNGksL5KeVb+cL1SeC=FwA9veS=tNQurA@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-19T11:48:49Z","receivedAt":"2013-05-19T11:48:49Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Sun, May 19, 2013 at 6:44 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Junio C Hamano wrote:\n>> If somebody implements the \"push.default = single\" (see the original\n>> message you are responding to), then the change might be smaller.\n>\n> I think this is a bad hack covering up an underlying problem: it is\n> ugly, confusing, and inextensible in my opinion.  I think of\n> push.default as merely a default remote.<name>.push value for all\n> remotes, that can be overridden on a per-remote basis.\n\nYou can't represent push.default = single either.\n\n-- \nFelipe Contreras\n"},{"id":"217894","messageId":"CALkWK0mOH8ZpmDR3HWW3j-q9fEpSawNonLDDWixD9LrPcKNnDA@mail.gmail.com","threadId":"33842","inReplyTo":"CAMP44s3HaEc1UoULYHYnzd_B_VayfedG_Gd1gT27=SeMdp4=eg@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-19T11:54:34Z","receivedAt":"2013-05-19T11:54:34Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Felipe Contreras wrote:\n> You can't represent push.default = single either.\n\nRight.  And I propose that we extend the refspec to be able to\nrepresent it, instead of having \"single\" sticking out like a sore\nthumb (and possibly introducing more sore thumbs like this in the\nfuture).\n"},{"id":"217897","messageId":"CAMP44s3OCPZYK8Cm25hLLGVOcQ5VAZ103-apHeDf3+gR5GjOcA@mail.gmail.com","threadId":"33842","inReplyTo":"CALkWK0mOH8ZpmDR3HWW3j-q9fEpSawNonLDDWixD9LrPcKNnDA@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-19T12:00:12Z","receivedAt":"2013-05-19T12:00:12Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Sun, May 19, 2013 at 6:54 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Felipe Contreras wrote:\n>> You can't represent push.default = single either.\n>\n> Right.  And I propose that we extend the refspec to be able to\n> represent it, instead of having \"single\" sticking out like a sore\n> thumb (and possibly introducing more sore thumbs like this in the\n> future).\n\nYeah, go ahead and have fun making refspecs Turing complete. Why?\nBecause you decided to call something a \"sore thumb\". Calling\nsomething a \"sore thumb\" doesn't make it so.\n\nWe, the sane people, will people will keep using simple configuration\noptions. Hopefully some day there won't be much need for many of the\ncurrent configurations, including push.default.\n\n-- \nFelipe Contreras\n"},{"id":"217953","messageId":"7vfvxixoks.fsf@alter.siamese.dyndns.org","threadId":"33842","inReplyTo":"CALkWK0=6L529C452MaNGksL5KeVb+cL1SeC=FwA9veS=tNQurA@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-20T04:28:03Z","receivedAt":"2013-05-20T04:28:03Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> I suspect that the issue you're trying to address is:\n>\n> [remote \"ram\"]\n>     push = refs/heads/*:refs/heads/rr/*\n>\n> not dictating which refs to push when I say 'git push' (it'll push all\n> the refs under refs/heads/*, not respecting push.default=current in my\n> scheme).\n\nThat is not what I was addressing.  You outlined your scenario as\n\"you were not, but you are now, allowed to push an approved ref into\n'origin'\".  And you do so under a different name.  That is why I set\nthat rr/ renaming push refspec for a remote ORIGIN not RAM.\n\nAnd that was done with extensivility your example implied in mind:\nyou may later be allowed to push other branches as well to origin.\nThat is why the refspec definition for 'origin' does not hardcode\nthe name of the branch you are permitted to push there at this\nmoment.  The fact that hot-branch goes to origin is encapsulated in\nthe branch.hot-branch.pushremote.  The rule, under which the name of\nany branch that goes to the origin is renamed, is encapsulated in\nremote.origin.push refspec (the introduction of the new mode\n\"push.default = single\" is necessary to make this work).\n\nWhen making that change, our fictitious ram did not have to touch\n\"remote.ram.push\" *at all*.  Independent of what the owner of\n\"origin\" and ram agreed in that example, ram would keep doing\nexactly the same thing to his own publishing point so that people\nwho are working off of his work would get updates from the place\nknown to contain his work from before.\n\nSo with \"git push ram\", it will push everything to \"ram\" under the\nsame name *without* rr/ renaming, but that was *by design*, not\nsomething I wanted to or I needded to work around.  And you would\nalso push to \"origin\" by doing \"git push\" while on hot-topic branch.\n"},{"id":"218250","messageId":"CALkWK0m1x_qrJfQ2Xw3w_kVuM-JHERFukbfxHyR08ODvxysKzw@mail.gmail.com","threadId":"33842","inReplyTo":"7vfvxixoks.fsf@alter.siamese.dyndns.org","subject":"Re: Random thoughts on \"upstream\"","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-23T10:42:03Z","receivedAt":"2013-05-23T10:42:03Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n> And that was done with extensivility your example implied in mind:\n> you may later be allowed to push other branches as well to origin.\n> That is why the refspec definition for 'origin' does not hardcode\n> the name of the branch you are permitted to push there at this\n> moment.  The fact that hot-branch goes to origin is encapsulated in\n> the branch.hot-branch.pushremote.  The rule, under which the name of\n> any branch that goes to the origin is renamed, is encapsulated in\n> remote.origin.push refspec (the introduction of the new mode\n> \"push.default = single\" is necessary to make this work).\n\nMy problem with this entire scheme _is_ the magic push.default =\nsingle.  Currently, push.default only kicks in when no\nremote.<name>.push refspec is specified (in other words, it is a\ndefault value of remote.<name>.push for all remotes), and I don't\nthink we should change this.  If the user wants to configure the push\nrefspec (either for rewriting, or for determining what to push), there\nis exactly one thing to change: remote.<name>.push.  So I can have:\n\n[remote \"theodore\"]\n    push = master\n    push = +pu\n\nThis means that I will always push master without force and pu with\nforce, irrespective of the branch I'm on.\n\n[remote \"origin\"]\n    push = refs/heads/*:refs/heads/rr/*\n\nThis means that I will always push all branches without force with\nrewriting, irrespective of the branch I'm on.\n\n[remote \"ram\"]\n    push = HEAD:refs/heads/rr/%1\n\nThis means that I will always push the current branch without force,\nwith rewriting.\n\n[remote \"felipe\"]\n     # empty\n\nThis means that remote.\"felipe\".push falls back to the refspec\nspecified by push.default.\n\nIsn't branch.<name>.push is completely unnecessary?  Does this make\nsense to you?  Isn't it more straightforward and general (how do I get\na push.default = single on a per-remote basis) than your solution?\n"},{"id":"218252","messageId":"CAMP44s22V9gETtjpMutmcO9_v1YnwnicAE=3zQfbyPXgUeKmKw@mail.gmail.com","threadId":"33842","inReplyTo":"CALkWK0m1x_qrJfQ2Xw3w_kVuM-JHERFukbfxHyR08ODvxysKzw@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-05-23T10:53:59Z","receivedAt":"2013-05-23T10:53:59Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, May 23, 2013 at 5:42 AM, Ramkumar Ramachandra\n<artagnon@gmail.com> wrote:\n> Junio C Hamano wrote:\n>> And that was done with extensivility your example implied in mind:\n>> you may later be allowed to push other branches as well to origin.\n>> That is why the refspec definition for 'origin' does not hardcode\n>> the name of the branch you are permitted to push there at this\n>> moment.  The fact that hot-branch goes to origin is encapsulated in\n>> the branch.hot-branch.pushremote.  The rule, under which the name of\n>> any branch that goes to the origin is renamed, is encapsulated in\n>> remote.origin.push refspec (the introduction of the new mode\n>> \"push.default = single\" is necessary to make this work).\n>\n> My problem with this entire scheme _is_ the magic push.default =\n> single.  Currently, push.default only kicks in when no\n> remote.<name>.push refspec is specified (in other words, it is a\n> default value of remote.<name>.push for all remotes), and I don't\n> think we should change this.  If the user wants to configure the push\n> refspec (either for rewriting, or for determining what to push), there\n> is exactly one thing to change: remote.<name>.push.  So I can have:\n>\n> [remote \"theodore\"]\n>     push = master\n>     push = +pu\n>\n> This means that I will always push master without force and pu with\n> force, irrespective of the branch I'm on.\n>\n> [remote \"origin\"]\n>     push = refs/heads/*:refs/heads/rr/*\n>\n> This means that I will always push all branches without force with\n> rewriting, irrespective of the branch I'm on.\n>\n> [remote \"ram\"]\n>     push = HEAD:refs/heads/rr/%1\n>\n> This means that I will always push the current branch without force,\n> with rewriting.\n>\n> [remote \"felipe\"]\n>      # empty\n>\n> This means that remote.\"felipe\".push falls back to the refspec\n> specified by push.default.\n>\n> Isn't branch.<name>.push is completely unnecessary?\n\nNo, it's not; 'git push --set-downstream' is not going to configure\nthat for the user. Nor will the user be able to see the downstream\nwith 'git branch -vv', nor will the user be able to see the downstream\nwith 'git rev-parse branch@{downstream}'.\n\nYou keep ignoring those use-cases I already mentioned multiple times\nbecause they don't fit your idealistic model.\n\n-- \nFelipe Contreras\n"},{"id":"218287","messageId":"7vppwhfw20.fsf@alter.siamese.dyndns.org","threadId":"33842","inReplyTo":"CALkWK0m1x_qrJfQ2Xw3w_kVuM-JHERFukbfxHyR08ODvxysKzw@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-23T17:25:11Z","receivedAt":"2013-05-23T17:25:11Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> [remote \"theodore\"]\n>     push = master\n>     push = +pu\n>\n> This means that I will always push master without force and pu with\n> force, irrespective of the branch I'm on.\n>\n> [remote \"origin\"]\n>     push = refs/heads/*:refs/heads/rr/*\n>\n> This means that I will always push all branches without force with\n> rewriting, irrespective of the branch I'm on.\n\nExactly.  And some people are unhappy about it, because they prefer\nto work per-branch basis, as opposed to having to perfect everything\ninto a publishable state first and then finally push everything out\nin one go.\n\nI am not saying default=single would be _the_ single right way to\nsolve it, but \"when you have default=single, remote.$name.push is\nused only to describe the mapping, not forcing you to push\neverything out at once\" is one possible solution to that.\n"},{"id":"218289","messageId":"CALkWK0n+_QqavstRCt8zM5ahmu9jnKB4M4XwdtqB4qSsJgq=hQ@mail.gmail.com","threadId":"33842","inReplyTo":"7vppwhfw20.fsf@alter.siamese.dyndns.org","subject":"Re: Random thoughts on \"upstream\"","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-23T17:41:21Z","receivedAt":"2013-05-23T17:41:21Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Junio C Hamano wrote:\n> I am not saying default=single would be _the_ single right way to\n> solve it, but \"when you have default=single, remote.$name.push is\n> used only to describe the mapping, not forcing you to push\n> everything out at once\" is one possible solution to that.\n\nThe big advantage it has, in my opinion, is ease of implementation:\nyou'd essentially have to grab the remote.<name>.push refspec, rewrite\nit to replace refs/heads/*: with $HEAD: and feed that refspec to the\ntransport layer.  Compare that to inventing a new refspec syntax,\nwhich is a mammoth task.  We can always extend the refspec later, if\nwe want that.  I wonder if it makes sense to bake the functionality\ninto current though: will we be breaking anything?\n\n(My opinion has changed after wrestling with the horrible transport layer)\n"},{"id":"218344","messageId":"CALkWK0nGhYYvHA4-nEtfCvRV3UyA2u28LJoX=GhxbmtRW1mMvA@mail.gmail.com","threadId":"33842","inReplyTo":"CALkWK0n+_QqavstRCt8zM5ahmu9jnKB4M4XwdtqB4qSsJgq=hQ@mail.gmail.com","subject":"Re: Random thoughts on \"upstream\"","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2013-05-24T06:39:49Z","receivedAt":"2013-05-24T06:39:49Z","isPatch":false,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Ramkumar Ramachandra wrote:\n> you'd essentially have to grab the remote.<name>.push refspec, rewrite\n> it to replace refs/heads/*: with $HEAD: and feed that refspec to the\n> transport layer\n\nUm, sorry.  It involves two independent steps:\n\n1. add_refspec() $HEAD:$HEAD@{push} to feed to the transport layer.\n(@{push} is already in progress; see list)\n\n2. Forcing the transport layer to ignore remote->push and use the fed\nrefspec instead.  (I'm not sure how to do this yet)\n"}]}