Re: Pull is Mostly Evil
- From
Felipe Contreras <felipe.contreras@gmail.com>
- Date
- May 3, 2014, 09:26 UTC
- Message-ID
- <5364b62d5fb7b_ac68dd30816@nysa.notmuch>
- In-Reply-To
- <5364A143.1060404@bbn.com>
Richard Hansen wrote:
Show 7 quoted lines
> 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.
Show 7 quoted lines
> 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.
Show 8 quoted lines
> 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.
Show 10 quoted lines
> 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.
Show 9 quoted lines
> * 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