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

2 messages, 2 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

Jeff King [off-list ref] writes:
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).
Exactly. It does not change the 'upstream' vs 'current' debate.
quoted
* '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.
There's a rule of thumb which works very well for beginners: when "git
push" tells you to pull before, then pull before. This rule of thumb
works, but only provided "push" and "pull" are symmetrical.

My experience with teaching Git is that this is the number 1 issue with
beginners (I'm talking about students who didn't learn CVS/SVN before,
so real beginners). They try to push, the push fails, and they come to
me saying "Git is broken, we can't work". That's why I introduced the
advice about non-fast forward, and later added the mention (e.g. 'git
pull') to point users in the right direction when the push fails. It
considerably reduced my workload as teacher ;-).

Now, if pushing sends commits to a branch other than 'upstream', you can
get the following scenario:

$ git push
To bla
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'bla'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.
$ git pull
Already up-to-date.
$ git push
<still denied, wtf>

One can easily get in this situation even in a kernel-style workflow:
work from your desktop, push, work from your laptop, try to push and it
fails.

Back to my students, most of them will never get in this situation
because they won't use branch, so HEAD = master and upstream =
origin/master, but the not-so-newbies may get this once they start
creating branches ifever they have HEAD = topic-branch and upstream =
origin/master for example.
  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.
To me, this is the real argument in favor of 'current'. I think it is
less important than others, but that's obviously subjective.

In any case, I'm not opposed to 'current', and I think 'current' is a
better default than 'matching', but I'm still not convinced it is better
than 'upstream'.
     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.
I don't think 'current' Vs 'upstream' really changes that. You may get a
non-fast forward on your topic branch if you've push to it from another
machine for example.
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".
I think "what's the most intuitive" is also very important. If we're
talking about real, real newbies, the risk of pushing to the wrong
branch is marginal compared to the risk of giving up and say "Git
doesn't work, I'll send my files by email" (which is real in my
experience :'-( ). But your remark does apply to not-totally newbies
anymore, but not yet Git gurus.

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

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

From: Dmitry Potapov <hidden>
Date: 2016-06-15 22:53:17

On Tue, Mar 13, 2012 at 1:34 PM, Matthieu Moy
[off-list ref] wrote:
Jeff King [off-list ref] writes:
quoted
  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.
There's a rule of thumb which works very well for beginners: when "git
push" tells you to pull before, then pull before. This rule of thumb
works, but only provided "push" and "pull" are symmetrical.
I am not sure what you mean by symmetrical here, because they are never
truly symmetrical as "pull" does merge and "push" does not. If there is
a centralized workflow with only one branch then everything is simple,
but it is not so with other workflows.

Moreover, doing 'git pull' too often (unless it is 'git pull --rebase)
pollutes history with useless merges, making more difficult to review
changes, or doing git-bisect.
Now, if pushing sends commits to a branch other than 'upstream', you can
get the following scenario:

$ git push
To bla
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'bla'
I agree that the current diagnostic is not suitable for beginners.
Not-fast-forward push is something that beginners should never use,
but from this message is not clear what is the alternative to forcing
non-fast-forward push.
One can easily get in this situation even in a kernel-style workflow:
work from your desktop, push, work from your laptop, try to push and it
fails.
IMHO, when you often switch between your desktop and laptop, 'matching'
makes much more sense. If 'push' fails then usually I want to force non-
fast-forward push, because the new series contain reworked patches that
already were on the other computer.
Back to my students, most of them will never get in this situation
because they won't use branch, so HEAD = master and upstream =
origin/master,
So, there is no real difference between 'current' and 'upstream' for
them.
but the not-so-newbies may get this once they start
creating branches ifever they have HEAD = topic-branch and upstream =
origin/master for example.
The real question is what one expects from 'push' in that situation. It
could be pushing this branch back to the upstream branch or creating a
new feature branch in the upstream.
quoted
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".
I think "what's the most intuitive" is also very important.
But it depends on the workflow that is employed by the project.
Different projects may have different workflows. We can assume that
the person who sets up the repository has good knowledge of Git and
how to use it, but many others who work on the same project may not
know Git well. For them "the most intuitive" means whatever policy
this project has.


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