git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [RFC/PATCH] push: introduce implicit push

From
Ramkumar Ramachandra <artagnon@gmail.com>
Date
Apr 14, 2013, 13:29 UTC
Message-ID
<CALkWK0k6bmjFxTSMAutgu2EjWRZ_cyTU9jZ3Er-aaV78T16RtQ@mail.gmail.com>
In-Reply-To
<7vehed7ilu.fsf@alter.siamese.dyndns.org>
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 this.

Show 5 quoted lines
> 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.
Show 5 quoted lines
> 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.

Show 16 quoted lines
> 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.

Previous: Jakub NarębskiNext: Junio C Hamano
Message 6 of 21 in “push: introduce implicit push”
  1. push: introduce implicit pushRamkumar Ramachandra, Apr 12, 2013
  2. Junio C HamanoApr 12, 2013
  3. Ramkumar RamachandraApr 13, 2013
  4. Junio C HamanoApr 14, 2013
  5. Jakub NarębskiApr 14, 2013
  6. Ramkumar RamachandraApr 14, 2013
  7. Junio C HamanoApr 15, 2013
  8. Johannes SixtApr 15, 2013
  9. Junio C HamanoApr 15, 2013
  10. John KeepingApr 15, 2013
  11. Ramkumar RamachandraApr 15, 2013
  12. John KeepingApr 15, 2013
  13. Junio C HamanoApr 15, 2013
  14. Ramkumar RamachandraApr 15, 2013
  15. John KeepingApr 15, 2013
  16. Felipe ContrerasApr 15, 2013
  17. John KeepingApr 15, 2013
  18. Felipe ContrerasApr 15, 2013
  19. Ramkumar RamachandraApr 15, 2013
  20. Jonathan NiederApr 16, 2013
  21. Jonathan NiederApr 16, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.