Thread (21 messages) 21 messages, 7 authors, 2016-06-15

Re: Pull is Mostly Evil

From: Felipe Contreras <hidden>
Date: 2016-06-15 23:00:59

Richard Hansen wrote:
I think the fundamental difference is in the relationship between the
local and the remote branch (which branch derives from the other).
The relationship between the branches determines what the user wants
from 'git pull'.

In my experience 'git pull' is mostly (only?) used for the following
three tasks:
I agree.
 1. update a local branch to incorporate the latest upstream changes

    In this case, the local branch (master) is a derivative of the
    upstream branch (origin/master).  The user wants all of the
    commits in the remote branch to be in the local branch.  And the
    user would like the local changes, if any, to descend from the tip
    of the remote branch.
My current propsal of making `git pull` by default do --ff-only would
solve this. In addition I think by default 'master' should be merged to
'origin/master', if say --merge is given.
    For this case, 'git pull --ff-only' followed by 'git rebase -p'
    works well, as does 'git pull --rebase=preserve' if the user is
    comfortable rebasing without reviewing the incoming commits first.
I suppose you mean a `git rebase -p` if the `git pull --ff-only` failed.
This might be OK on most projects, but not all.

What happens after a `git pull --ff-only` fails should be totally
up to the user.
 2. update a published feature branch with the latest changes from its
    parent branch

    In this case, the local branch (foo) is a derivative of the
    upstream branch (origin/foo) which is itself a derivative of
    another branch (origin/master).  All commits in origin/master
    should be in origin/foo, and ideally all commits unique to
    origin/foo would descend from the tip of origin/master.
I don't understand why are you tainting the example with 'origin/foo',
'foo' and 'origin/master' are enough for this example. In fact, the
mention of 'origin/master' made it wrong: after the pull not all the
commits of origin/master would be in origin/foo, you need a push for
that. We have enough in our plate to taint this with yet another branch
and push.

For this case `git pull origin master` already work correctly for most
projects. We probably shouldn't change that.
 3. integrate a more-or-less complete feature/fix back into the line
    of development it forked off of

    In this case the local branch is a primary line of development and
    the remote branch contains the derivative work.  Think Linus
    pulling in contributions.  Different situations will call for
    different ways to handle this case, but most will probably want
    some or all of:

     * rebase the remote commits onto local HEAD
No. Most people will merge the remote branch as it is. There's no reason
to rebase, specially if you are creating a merge commit.
     * merge into local HEAD so that the first parent (if a real merge
       and not a ff) is the previous version of the main line of
       development and the second parent is the derivative work
     * merge --no-ff so that:
        - the merge can serve as a cover letter (who reviewed it,
          which bug reports were fixed, where the changes came from,
          etc.)
        - the commits that compose the new topic are grouped together
        - the first-parent path represents a series of completed tasks
It is very rare that an integrator is even able to do a fast-forward
merge anyway. So being explicit about --no-ff might better, but it would
hardly make a difference. Either way, a good integrator would configure
pull.ff = false.

I'd say `git pull origin master` already works fine for this case.

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