Ramkumar Ramachandra <artagnon@xxxxxxxxx> writes: > I agree with you largely, but I would still argue that choosing a > destination based on the current branch is a historical mistake made > by "matching". "matching" is not necessarily a good default for everybody, and we are fixing that historical mistake in Git 2.0. Step back and think again. "matching" has never been about where the push goes. It is about what are pushed out, once you decide where to push. If a user often wants to push out a branch as soon as he made a commit on it (even when other branches that go to the same publishing point should not be pushed out yet), an instructoin "Ok, I'll push to that repository" that pushes all matching branches will not work well, because it will publish uncooked other branches, too. That is the historical mistake of making "matching" the unconfigured default. The historical mistake of "matching" does not have anything to do with the choice of "where to push". It is only about "what to push". If you re-read your three-remote example involving "upstream" (me), "ram" (your wip publishing point) and "peff": Cf. http://thread.gmane.org/gmane.comp.version-control.git/220769/focus=220933 you'll see that the only reason why you thought you need the hack to set pushremote to null was because you did _not_ use matching. It illustrates one reason why blaming matching for selection of destination misses the point. In any case, dispelling a misplaced blame on "matching" is not the main point of this message. > With this patch, users must mandatorily know about > remote.pushdefault and branch.<name>.pushremote, if they want to > work in multiple-remote scenarios. I am afraid that it is neither sufficient nor a good solution. I do not necessarily think that the best course is to devise an unintuitive (to unsuspecting users) set of rules and force users to understand it. That is where my secondary unhappiness comes from, and that was why I said that limiting the magic only to a very simple and easy to understand case might make it more sellable. "git push" that pays attention to "branch.*.remote" was the original sin. To casual users with push.default=current/upstream, the two branches (my current branch? the branch I am pushing out?) have always been the same when branch.*.remote is used. These users don't even have to think about the distinction between the two [*1*]. But the distinction starts mattering once you start wishing to omit saying _where_ to push, because at that point, _what_ to push is the only thing the user would give us, but the end users are not used to see the destination chosen based on what is being pushed out. The new branch.*.pushremote does not alleviate this confusion. It gives the same "when on this branch, we push out to that remote" (and not "when pushing this branch out, it goes there" impression. The new remote.pushdefault _is_ a definite improvement: "If I do not say where to push, this is where things go". It makes a very clear statement, and does not have that confusion. > - In git push master, master is verified not to be a path on the > filesystem, not a remote, and finally a local branch. Yes. > - In git push master:next, master:next is interpreted as a destination. Ideally it should notice and diagnose it as a syntax error and error out (of course an attempt to locate master: URL handler will fail, but that is less nice). > - In git push master next:pu, master is verified as usual, and next:pu > is pushed to the remote specified by next. My patch currently does > this (checks that <src> and <dst> are branches). I am not sure what you mean by "and next:pu is...". If "git push next:pu master" should error out without mistaking "next:pu" as destination, so should "git push master next:pu", I think. The last one is also the same. The "guess destination" magic should kick in only when we can verify _all_ the refs we are pushing out are simple ones (branch names, and possibly tag names), and the behaviour should not depend on the order. Anything more complex is too confusing. I personally think it is much more sellable to use an even simpler rule than what Jeff suggested, to make git push -- <refspec> go to the remote.pushdefault (falling back to remote.default that is "origin"), without even paying attention to what branch you are on, and ignoring branch.*.remote/pushremote configuration. That is sufficient to support the triangular, the publish-to-mine, and the centralized workflows, no? In any of these cases, the repository you push out to is _one_, even though it may be a different one from where you pull from. If you have a very special branch that goes to a different place than all the other branches, you can always push out while on that branch without any refspec, anyway. [Footnote] *1* If you really think about what branch.*.remote is _for_, it says "I want this branch to integrate with that branch at this remote". If the user were to push the branch out using the configuration, it is more logical to think of it as "When pushing this branch out, it goes there", and not as "When I am on this branch and say 'git push', 'git push' pushes there". But that is clear and logical _only_ to Git-heads who have thought about this hard enough. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html