Re: [RFC PATCH] push: start warning upcoming default change for push.default

4 messages, 3 authors, 2016-06-15 · open the first message on its own page

Re: [RFC PATCH] push: start warning upcoming default change for push.default

From: Matthieu Moy <hidden>
Date: 2016-06-15 22:53:17

Marc Branchaud [off-list ref] writes:
On 12-03-10 01:16 AM, Michael Haggerty wrote:
quoted
I propose that the default should be even stricter: like "current", it
would push to an branch with the same name as the current local branch,
*but only if that branch already exists on the remote*.  It would only
be possible to create a new branch on the remote by calling "git push"
with an explicit branch argument.  I believe that such a policy would do
the right thing in the cases where the "right thing" is pretty
unambiguous, and would require a user decision in other cases.
I haven't thought it through very deeply, but at first glance this seems like
reasonable default behaviour to me.
I do find it reasonable, but I think 'upstream' has several advantages
over it.

* 'upstream' makes "git push" and "git pull" symmetrical. While there
  are workflows where it is usefull to have "push" and "pull" point to
  different branches, I think it is far more intuitive to have this
  symmetry by default.

* For newbies, the sequence "create an empty repository, clone it,
  commit and push" works like a charm with either 'upstream' or
  'current'. Today, the first push to an empty repository requires
  either saying "git push origin master" or "git push --all", both of
  which sound like black magic to the poor user who did not yet learn
  what 'origin' is and what a branch is.

* 'upstream' makes it easy to create a local topic branch, and let
  'push' send it to the master branch (i.e. have local 'topic-branch'
  pull and push to 'origin/master'). In general, 'upstream' allows
  workflows where you push to branches with either a different name or
  with the same name (by setting the upstream appropriately), but the
  opposite is not true.

That being said, I think the mode you Michael described at least
deserves to exist, even if I disagree that it would be the best default.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

Re: [RFC PATCH] push: start warning upcoming default change for push.default

From: Jeff King <hidden>
Date: 2016-06-15 22:53:17

On Mon, Mar 12, 2012 at 05:37:32PM +0100, Matthieu Moy wrote:
I do find it reasonable, but I think 'upstream' has several advantages
over it.

* 'upstream' makes "git push" and "git pull" symmetrical. While there
  are workflows where it is usefull to have "push" and "pull" point to
  different branches, I think it is far more intuitive to have this
  symmetry by default.
This is one of the things I really hate about 'upstream'. If you share a
central repo with other people, it makes sense. You push and pull from
the same place. But in the classic kernel-style workflow, you'd pull
from an upstream, and then publish your work elsewhere. And I think it's
not just kernel people who use this asymmetric workflow. On something
like GitHub, you get your own fork repo on the site as a publishing
point. But you also want to keep pulling and basing your work on what
the main project is doing. You can't just pull from your fork, since it
never gets updates from the main project; you pull them into your local
repo, and then push them up to your fork.

So in a very reasonable common newbie workflow, "upstream" will not at
all do what you want, because it will go to the wrong repo[1]

That being said, "current" will _also_ go to the wrong repo, because
push fundamentally respects "branch.*.remote".  Which is definitely not
what you want in the asymmetric case. This is not a push.default issue,
but I think it is somewhat related, and maybe worth discussing along
with the topic of asymmetry. Am I the only one who finds this behavior
annoying? I've mostly trained my fingers to type "git push
<my-publish-repo>", but I do occasionally forget. Do other people with
asymmetric workflows find this annoying? Do they not care? Or are many
fewer people doing asymmetric things than I think?

While I'm ranting, there's another weirdness I noticed. If I have
push.default set to upstream, and config like this:

  [branch "foo"]
     remote = origin
     merge = refs/heads/master

then typing "git push" will go to foo's master branch. But if I type
"git push other-remote", then it will go to other-remote's master
branch. Which makes no sense to me. The upstream is foo's master, and
now we are making guesses about how the names on each side are the same.
Is this an intentional behavior?

[1] One saving grace of going to the wrong repo is that you usually
    don't have permissions to push to that repo, so you get a harmless
    error message.
* For newbies, the sequence "create an empty repository, clone it,
  commit and push" works like a charm with either 'upstream' or
  'current'. Today, the first push to an empty repository requires
  either saying "git push origin master" or "git push --all", both of
  which sound like black magic to the poor user who did not yet learn
  what 'origin' is and what a branch is.
Ending that confusion is one of the best reasons to switch the default,
IMHO, but I don't think it argues for "current" versus "upstream", as
they both fix it (but Michael's matching-current hybrid would not, so I
agree it is less appealing).
* 'upstream' makes it easy to create a local topic branch, and let
  'push' send it to the master branch (i.e. have local 'topic-branch'
  pull and push to 'origin/master'). In general, 'upstream' allows
  workflows where you push to branches with either a different name or
  with the same name (by setting the upstream appropriately), but the
  opposite is not true.
Actually, this is the thing that scares me the most about "upstream" as
a default, because in this case, you are implicitly performing the
equivalent of a fast-forward merge. So that's handy if you are a new
user who wants to publish your work back to the master branch. But that
has two problems:

  1. If you are a new user who does like the implicit merge, you may
     find it convenient not to have to learn about "git checkout; git
     merge topic ; git push remote master". But it only helps you
     _sometimes_. If master has had other work built on it, your push
     will fail, and you will have to do the merge yourself. So it is
     only helping you by omitting a step some of the time, and you still
     have to learn why the step is sometimes necessary and sometimes
     not.

     Yes, experienced users do not have this learning problem. But
     remember we are talking about a default targeted at new users, and
     trying to reduce their confusion.  People who know and like what
     "upstream" does can configure it themselves.

  2. If you are a new user who _doesn't_ want to do the merge, but
     instead wants to publish your work-in-progress topic, then the
     implicit merge-back-to-master behavior is wrong and dangerous.
     You are publishing work that probably violates the general rules
     for what goes on master.

     Or perhaps somebody else has built on top of master, and your push
     fails. If you're an astute reader, you will see that the failing
     push tried to go to master. But if you're not, you may retry with
     "-f", which is quite dangerous, as now you are not just
     accidentally publishing a work-in-progress, but you are
     overwriting somebody else's work. Obviously this is a problem
     anytime you use "-f", but the fact that your "foo" branch is going
     to somewhere besides the remote's "foo" branch makes me think it is
     much more likely a clueless user will get confused and overwrite
     something on the more "mainstream" branch.

So far a lot of the discussion has focused on "what is the most sensible
default for the most number of people". But I wonder if a better
question is "what is the default that is the least likely to do
something dangerous and embarrassing". People who use git enough to say
"wow, I don't like this default for my workflow" are probably at the
point that they can configure push.default themselves.

-Peff

Re: [RFC PATCH] push: start warning upcoming default change for push.default

From: Michael Haggerty <hidden>
Date: 2016-06-15 22:53:18

On 03/12/2012 07:37 PM, Jeff King wrote:
On Mon, Mar 12, 2012 at 05:37:32PM +0100, Matthieu Moy wrote:
quoted
* For newbies, the sequence "create an empty repository, clone it,
  commit and push" works like a charm with either 'upstream' or
  'current'. Today, the first push to an empty repository requires
  either saying "git push origin master" or "git push --all", both of
  which sound like black magic to the poor user who did not yet learn
  what 'origin' is and what a branch is.
Ending that confusion is one of the best reasons to switch the default,
IMHO, but I don't think it argues for "current" versus "upstream", as
they both fix it (but Michael's matching-current hybrid would not, so I
agree it is less appealing).
In the case of my proposed matching-current hybrid, the error message
for the failing push would make it pretty obvious what went wrong and
how to fix it; something like:

    $ git push
    The remote repository "git.example.com:myproject" does not yet
    contain a branch called "master".  If you would like to create one
    now, type

        git push origin master

    For other alternatives, please see gitworkflows(7).

This error message would appear *whenever* the matching-current hybrid
policy caused the push to fail.  Since this problem occurs only if (1)
the upstream repository is empty and (2) the user hasn't configured a
more liberal global push.default, and since it is blindingly obvious
what to do to fix the problem, it doesn't seem especially onerous.

(One could even create a special-case to allow such a push when the
upstream repository is empty, but I don't think the gain in convenience
is worth the loss of consistency.)
So far a lot of the discussion has focused on "what is the most sensible
default for the most number of people". But I wonder if a better
question is "what is the default that is the least likely to do
something dangerous and embarrassing". People who use git enough to say
"wow, I don't like this default for my workflow" are probably at the
point that they can configure push.default themselves.
I agree entirely.  And here is an algorithm for deciding what the
default should be:

1. Make a list of branch configurations that can be distinguished by
   git, which would be something like all combinations of

   * remote has a branch with the same name as the current branch?
     * no
     * yes, and remote branch could be fast-forwarded to local state
     * yes, but remote branch cannot be fast-forwarded to local state

   * local branch has known upstream branch on remote?
     * no
     * yes, and remote upstream branch could be fast-forwarded to
       the state of the current local branch
     * yes, but remote upstream branch cannot be fast-forwarded to
       the state of the current local branch

2. In each of these situations, decide what "git push" should do in
   each of the common workflows.

3. In the branching configurations for which all workflows agree about
   what "git push" should do, then that is what "git push" should do by
   default.  When they do not agree, then "git push" should do nothing,
   give an informative error message, and leave it to the user to
   decide.  If all workflows agree on a safe subset of what "git push"
   should do (for example, "matching" and "current" agree that the
   current branch should be pushed even though they disagree whether
   other branches should be pushed), then it might be OK to carry out
   the safe subset.

The most common workflows, along with the configuration settings that
are recommended for that workflow, should be given standard names and
documented in gitworkflows(7).  The warning message for a failed "git
push" invocations (especially if push.default is unset) should direct
the user to this manpage.


Isn't it obvious?: The fact that we cannot even agree among ourselves
what "git push" should do in all cases *proves* that we are trying to be
too ambitious with DWIM.  "git push" must therefore become more
deferential when the obvious thing to do is unclear, especially given
that mistakes (due to the very nature of "git push") often have
embarrassing and publicly visible effects.

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

Re: [RFC PATCH] push: start warning upcoming default change for push.default

From: Jeff King <hidden>
Date: 2016-06-15 22:53:18

On Wed, Mar 14, 2012 at 09:59:04AM +0100, Michael Haggerty wrote:
quoted
Ending that confusion is one of the best reasons to switch the default,
IMHO, but I don't think it argues for "current" versus "upstream", as
they both fix it (but Michael's matching-current hybrid would not, so I
agree it is less appealing).
In the case of my proposed matching-current hybrid, the error message
for the failing push would make it pretty obvious what went wrong and
how to fix it; something like:

    $ git push
    The remote repository "git.example.com:myproject" does not yet
    contain a branch called "master".  If you would like to create one
    now, type

        git push origin master

    For other alternatives, please see gitworkflows(7).

This error message would appear *whenever* the matching-current hybrid
policy caused the push to fail.  Since this problem occurs only if (1)
the upstream repository is empty and (2) the user hasn't configured a
more liberal global push.default, and since it is blindingly obvious
what to do to fix the problem, it doesn't seem especially onerous.
Thanks for the clarification. That does go a long way towards dealing
with the confusion. I think I'd be OK with that, though I am on the
fence about whether just pushing (i.e., "current") would be better or
worse.
3. In the branching configurations for which all workflows agree about
   what "git push" should do, then that is what "git push" should do by
   default.  When they do not agree, then "git push" should do nothing,
   give an informative error message, and leave it to the user to
   decide.
[...]
Isn't it obvious?: The fact that we cannot even agree among ourselves
what "git push" should do in all cases *proves* that we are trying to be
too ambitious with DWIM.  "git push" must therefore become more
deferential when the obvious thing to do is unclear, especially given
that mistakes (due to the very nature of "git push") often have
embarrassing and publicly visible effects.
I find your approach interesting, but it doesn't deal with one problem:
user perception when git fails to do something out of the box. I am
worried that the rule above means that push will end up defaulting to
nothing. It is one thing to say "there are so many workflows, and they
do not agree, so we should be safe and do nothing"; that makes sense to
an advanced user who thinks about things like different workflows. But
to a brand-new git user who is running "push" in their first session, it
makes git seem very unfriendly.

And that's why I think either "current" or "current-if-matching" as you
describe is a sane default. I don't think it matches with what the
"upstream" people want, and so does not meet your criteria above as a
default behavior. But it does something sensible and not very dangerous
or embarrassing, and it means git will do something that is probably
useful out of the box for a new user.

-Peff
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help