git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Jeff King <peff@peff.net>
Cc: Felipe Contreras <felipe.contreras@gmail.com>,
	Marc Branchaud <marcnarc@xiplink.com>,
	Git Mailing List <git@vger.kernel.org>
Subject: Re: Pull is Mostly Evil
Date: Tue, 06 May 2014 15:06:49 -0700	[thread overview]
Message-ID: <xmqqy4yed0jq.fsf@gitster.dls.corp.google.com> (raw)
In-Reply-To: <20140502214817.GA10801@sigill.intra.peff.net> (Jeff King's message of "Fri, 2 May 2014 17:48:17 -0400")

Jeff King <peff@peff.net> writes:

> I realize this has veered off into talking about an "update" command,
> and not necessarily "pull", but since there a lot of proposals floating
> around, I wanted to make one point: if we are going to do such a switch,
> let's please make it something the user explicitly turns on.

I mentioned "update" in an attempt to suggest some way to avoid
breaking "git pull" for people who do want to advane the history
with real work (i.e. not just following along with fast-forwarding).

A failed "git push" that suggests to pull first, which came from the
original "To emulate CVS workflow, you can pull, work, push, and if
the push fails, pull again and then push" in the early tutorial,
turns out to be very bad in the "trunk" centric worldview.
And I think the solution is to realize that we use "git pull" for
two fairly differnt workflows.

 - You know you own the tip of the "trunk" (in the global view).
   You merge from other people to advance the global world view in a
   way that makes sense in the "first-parent chain is the trunk"
   worldview.  That is what "git pull [--no-ff]" was designed to do,
   and it does it very well.

 - You have some work of yours (either you committed directly, you
   merged your own work done on a side branch, or you merged from
   other people using "git pull") on top of a commit that used to be
   at the tip of the global world.  You want to make sure that
   branch you are on is not missing what has happened while you are
   not communicating with the outside world.

The problematic case is the latter, and by introducing a new command
to do that well (which is *not* just about "swapping the order of
the parents", by the way), updating the "leaf developer" section of
"Everyday Git" document and tutorials, and suggesting to use that
upon failed "git push", I think users would get a more pleasant
experience.  And move "git pull" into "integrator" section, a
command that is not necessary for leaf developers.

I am not married to the name "update".  I think the ideal behaviour
of that "leaf-developer" command would be something along the lines
of the following:

 - If we can fast-forward, do so and we are done.

 - Otherwise, we have a history of this shape:

        ----O    
             \
    -----A----B----C
          \
           X---Y---Z

   where A was where we forked, B was a merge the user made, C was a
   commit the user directly made, and X, Y, and Z (some of them may
   be merges) are the "trunk" history  "git pull" would create a
   merge M whose parents are <C Z>, which is wrong from the
   "first-parent is the trunk" worldview.

   But recording the merge to have parents <Z C> does not give us
   "the first-parent is the trunk" worldview, in the presense of B.
   We would prefer to end up with a history more like this:

    -----A       ----O
          \           \
           X---Y---Z---B'--C'

   so that your work, your contribution with two commits of yours,
   was to merge the work done on a side branch and then made one
   commit directly on top of it.

   Hence, I think the ideal behaviour of the new command is to
   replay the first-parent history on top of the updated tip of your
   upstream (which by the way is different from how "rebase
   --preserve-merges" works; it is more like how J6t wanted to make
   "rebase --preserve-merges" work, IIRC).

After that, you can attempt to push, and it may fail again (because
somebody has grown the shared history to have a child W of Z at the
tip), in which case exactly the same "git update" would attempt to
recreate a history of this shape:

    -----A           ----O
          \               \
           X---Y---Z---W---B"--C"


During a long transition period (essentially, waiting for the
current crop of documents and tutorials to die out), we will need
extra safety to prevent people, who merely wanted to bring their
branch up to date, from running "git pull", and I think the command
needs to:

 - check which branch of what repository it is trying to pull;

 - check which branch of what repository it is going to update if
   "git push" is given;

 - if they are the same, then you are attempting to update from your
   upstream, so either warn or error out.  If we are going to warn
   but make a merge anyway, the warning message *must* come at the
   very end of the output (and tell the user the way to recover is
   to reset one away and run the other command).

Or something like that.

  parent reply	other threads:[~2014-05-06 22:07 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-02 15:37 Pull is Mostly Evil Marc Branchaud
2014-05-02 15:45 ` David Kastrup
2014-05-02 16:05   ` Philip Oakley
2014-05-02 19:05     ` Felipe Contreras
2014-05-02 22:34       ` Philip Oakley
2014-05-02 22:53         ` Jonathan Nieder
2014-05-03 20:24           ` Philip Oakley
2014-05-02 23:23         ` Felipe Contreras
2014-05-03 11:24           ` Philip Oakley
2014-05-03 11:30             ` Felipe Contreras
2014-05-02 19:31   ` David Lang
2014-05-02 19:37     ` David Kastrup
2014-05-02 18:13 ` Junio C Hamano
2014-05-02 19:11   ` Felipe Contreras
2014-05-02 20:06     ` Junio C Hamano
2014-05-02 20:58       ` Felipe Contreras
2014-05-02 21:48     ` Jeff King
2014-05-02 21:55       ` Felipe Contreras
2014-05-02 22:36         ` Jeff King
2014-05-02 23:27           ` Felipe Contreras
2014-05-03  2:18       ` David Kastrup
2014-05-06 22:06       ` Junio C Hamano [this message]
2014-05-06 22:19         ` Felipe Contreras
2014-05-03  7:56   ` Richard Hansen
2014-05-03  8:17     ` David Kastrup
2014-05-03  9:04       ` Felipe Contreras
2014-05-03  9:56         ` David Kastrup
2014-05-04  4:30           ` David Lang
2014-05-04  4:38             ` Felipe Contreras
2014-05-04  6:13               ` David Kastrup
2014-05-04  6:50               ` James Denholm
2014-05-04  7:48                 ` David Kastrup
2014-05-04  9:51                 ` Felipe Contreras
2014-05-04 10:37                   ` James Denholm
2014-05-04 11:02                     ` David Kastrup
2014-05-03  9:26     ` Felipe Contreras
2014-05-03 22:09       ` Richard Hansen
2014-05-04  3:08         ` Felipe Contreras
2014-05-04  7:49           ` Richard Hansen
2014-05-04 10:17             ` Felipe Contreras
2014-05-04 19:09               ` Richard Hansen
2014-05-04 21:13                 ` Felipe Contreras
2014-05-05  5:44                   ` Richard Hansen
2014-05-05  5:47                     ` Felipe Contreras
2014-05-07 22:37     ` Max Kirillov
2014-05-03 10:00   ` John Szakmeister
2014-05-05 15:39     ` Richard Hansen
2014-05-05 18:15       ` Felipe Contreras
2014-05-02 22:12 ` Philip Oakley
2014-05-09 19:49 ` Marc Branchaud

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqy4yed0jq.fsf@gitster.dls.corp.google.com \
    --to=gitster@pobox.com \
    --cc=felipe.contreras@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=marcnarc@xiplink.com \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).