Junio C Hamano wrote:
> [...]
> In any case, dispelling a misplaced blame on "matching" is not the
> main point of this message.

I _thought_ "matching" was a good scapegoat to blame current user
expectations on.  However, it's okay if you think that we're
misplacing the blame.  As long as we can agree that user expectations
are aligned with "choosing the remote based on the current branch",
we're good.  Let's not waste time attempting to dissect the reason for

> 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.

Note that I'm not married to the interface I'm proposing: we can
always have a git branch --set-destination-to, corresponding to git
branch --set-upstream-to.  I'm not sure what interface to come up for
tweaking remote.pushdefault though (since we have deemed that a
remote.default counterpart is unnecessary, we've never really thought
about the problem).

> 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.

branch.*.pushremote is a very new feature, and I doubt it's even
available to users yet (distribution package); therefore there is no
meaning set-in-stone that we cannot change quickly.  If you think
about it, it's completely illogical for branch.* options to depend on
the state of the worktree; I really think we should push for them to
be inherent branch properties: we can update the documentation
accordingly, if we agree on this.

I think the main point of disagreement is that I'm in favor of
respecting logic, while you're in favor of respecting user
expectations set by (what we acknowledge now as) historical mistakes.
 I'm not saying that we should _not_ respect user expectations, but
rather that we should find some way to mould our users' expectations
to align with the logical choice without causing unpleasantness.

> 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.

Okay, no problem.  Just so we're clear: the "guess destination magic"
will only kick in when all the refspecs specified are either tags or
branches, and are missing the :<dst> counterpart.  So, git push master
+implicit-push should work just fine.

> 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.

This is logically incorrect: you're essentially making branches and
tags equivalent, while this is clearly not the case.  Will I ever
create "throwaway tags" just on my local machine for ease of working,
that I desire not to publish anywhere?  Now, replace "tags" with
"branches" in that sentence, and you have a completely different
answer.  Will I ever want to send certain specific "tags" to a special
destination (for review, for instance)?  Again, "branches" gives you a
different answer.  Can I attach properties to tags?  Are there tag.*
variables that I can set?  Why, then, do branches have these
variables?  Because they're not tags!  The way we work with branches
is completely different from the way we work with tags.

Let me try to drive this point in even harder:

My local clone is never one repository, but a "composite repository"
containing object stores from multiple remotes mixed in.  The
fantastic thing about git is that I can use the same worktree/ index/
local refs to work with this composite, as if it were a single
repository.  However, I need a way to sort through this mixed object
store/ multiple remotes madness: and for this, I have different remote
refs, and local branch specific configuration variables.  Again, I
don't think of my repository as a whole, but rather as a collection of
related branches that each have a specific source and destination.  I
do _not_ have one global source, or one global destination: that's
just the two-remote case, and git allows me to have N remotes in the
general case.  What I meant by "triangular workflows" was not the
reduced case of a repository-wide triangle, but about many little
triangles associated with every branch.

What is the practical application for all this?  What if I always want
to send some specific branches to a different destination (say Gerrit
review, or my friend's "integration server")?  What if I never want to
publish some branches (say they contain sensitive information such as
private keys)?  What if my upstream gave me write access to some
specific branches (in which case, I don't want to push those branches
to my usual "fork destination")?  Why are you proposing to
artificially limit the implicit-push topic to not support these cases?
 They're not special or fringe cases, but the general case that git
was always designed for.

Moreover, in your attempt to design a compromise, you're inventing a
different precedence order!  Wait a minute: why should we compromise
in the first place?  We're not an old enterprise trying to satisfy a
myopic client specification for a living; developing git is our
full-time hobby (today is a Sunday, by the way), and we should not
build something that we're less-than-elated with.  In my proposal, the
precedence order branch.<name>.pushremote, remote.pushdefault,
branch.<name>.remote, remote.default, origin, remains the same: we
just want to change which branch that <name> refers to.  In my
opinion, it is a much more subtle change than the entirely new
precedence order that you're inventing.
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to