threads / discuss / 25561

Why the default action for pull is merge, but not rebase?

Subject: Why the default action for pull is merge, but not rebase?

## tl;dr

13 messages between Oct 27, 2010 and Oct 28, 2010.

replies: 12people: 7as markdown or json

Eugene Sajine· Oct 27, 2010, 16:46 UTC · lore
Hi,

I'm just curious if there are some downsides that i don't see? For me it seems to have much more sense to automatically rebase vs merge when you do pull. The diverged history will become "straighter" and cleaner, if the history is not diverged then it will be fast-forward. So, why not to rebase?

Thanks for your time in advance,
Eugene
Jonathan Nieder· Oct 27, 2010, 16:57 UTC · re: Eugene Sajine · lore

Re: Why the default action for pull is merge, but not rebase?

Eugene Sajine wrote:
>               So, why not to rebase?
An interesting question.

Rebasing results in untested commits. If this is a patch series for submission, that's fine, because you will be extensively testing each patch anyway or indicating to reviewers that that needs to be done (right?). But if it's a long-lived branch then such repeated testing work can be a serious hassle. https://git.wiki.kernel.org/index.php/GitFaq#What_is_the_difference_between_a_merge_and_a_rebase.3F

A public branch that is regularly rebased is hard to follow ("git log foo@{1}..foo") and build on. http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html#_recovering_from_upstream_rebase

Code consumers often want clean history, but that really means (a) clean and (b) history. http://thread.gmane.org/gmane.comp.video.dri.devel/34739/focus=34744

Hope that helps.
Eugene Sajine· Oct 27, 2010, 17:21 UTC · re: Jonathan Nieder · lore

Re: Why the default action for pull is merge, but not rebase?

On Wed, Oct 27, 2010 at 12:57 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:
Show 23 quoted lines
> Eugene Sajine wrote:
>
>>               So, why not to rebase?
>
> An interesting question.
>
> Rebasing results in untested commits.  If this is a patch series
> for submission, that's fine, because you will be extensively
> testing each patch anyway or indicating to reviewers that that
> needs to be done (right?).  But if it's a long-lived branch then
> such repeated testing work can be a serious hassle.
> https://git.wiki.kernel.org/index.php/GitFaq#What_is_the_difference_between_a_merge_and_a_rebase.3F
>
> A public branch that is regularly rebased is hard to follow
> ("git log foo@{1}..foo") and build on.
> http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html#_recovering_from_upstream_rebase
>
> Code consumers often want clean history, but that really means
> (a) clean and (b) history.
> http://thread.gmane.org/gmane.comp.video.dri.devel/34739/focus=34744
>
> Hope that helps.
>
Thanks for prompt answer. But let me clarify:
When you do pull git performs:

fetch of the remote branch to the FETCH_HEAD and then merge of FETCH_HEAD into the local branch

What I'm saying is that your local branch should be rebased on top of FETCH_HEAD instead

In this case there is no such thing as "often rebased public branch".

if the history got diverged then pull will result in new state that should be tested anyway, so why not to rebase local branch on top of the upstream instead of merging upstream into local branch?

i'm not saying to rebase the upstream published branch on top of the local changes - that's NO-NO I'm aware of

thanks, Eugene

Jonathan Nieder· Oct 27, 2010, 17:36 UTC · re: Eugene Sajine · lore

Re: Why the default action for pull is merge, but not rebase?

Eugene Sajine wrote:
Show 11 quoted lines
> Thanks for prompt answer. But let me clarify:
>
> When you do pull git performs:
>
> fetch of the remote branch to the FETCH_HEAD
> and then merge of FETCH_HEAD into the local branch
>
> What I'm saying is that your local branch should be rebased on top of
> FETCH_HEAD instead
> 
> In this case there is no such thing as "often rebased public branch".
Ah, but there is.

Imagine you are Junio and just received a pull request from Pat. Then you might try:

 $ git pull pat for-junio

which will do all the fetching and merging magic that "git pull" is known for. Now if pat's for-junio branch is based on the tip of your current branch, this will be a fast-forward and it doesn't matter whether you merge or rebase. But what if there are some intervening commits?

 $ git pull eric for-junio
 $ git pull pat for-junio

If this pull were the rebasing kind, the result would be for Eric's commits to be rewritten based on Pat's.

Björn Steinbrink· Oct 28, 2010, 06:17 UTC · re: Eugene Sajine · lore

Re: Why the default action for pull is merge, but not rebase?

On 2010.10.27 13:21:18 -0400, Eugene Sajine wrote:
Show 33 quoted lines
> On Wed, Oct 27, 2010 at 12:57 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:
> > Eugene Sajine wrote:
> >
> >>               So, why not to rebase?
> >
> > An interesting question.
> >
> > Rebasing results in untested commits.  If this is a patch series
> > for submission, that's fine, because you will be extensively
> > testing each patch anyway or indicating to reviewers that that
> > needs to be done (right?).  But if it's a long-lived branch then
> > such repeated testing work can be a serious hassle.
> > https://git.wiki.kernel.org/index.php/GitFaq#What_is_the_difference_between_a_merge_and_a_rebase.3F
> >
> > A public branch that is regularly rebased is hard to follow
> > ("git log foo@{1}..foo") and build on.
> > http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html#_recovering_from_upstream_rebase
> >
> > Code consumers often want clean history, but that really means
> > (a) clean and (b) history.
> > http://thread.gmane.org/gmane.comp.video.dri.devel/34739/focus=34744
> 
> Thanks for prompt answer. But let me clarify:
> 
> When you do pull git performs:
> 
> fetch of the remote branch to the FETCH_HEAD
> and then merge of FETCH_HEAD into the local branch
> 
> What I'm saying is that your local branch should be rebased on top of
> FETCH_HEAD instead
> 
> In this case there is no such thing as "often rebased public branch".

How do you know? Right before the pull, you could have run push, so you would be rebasing a public branch.

> if the history got diverged then pull will result in new state that
> should be tested anyway, so why not to rebase local branch on top of
> the upstream instead of merging upstream into local branch?

Merging results in either 0 (fast-forward) or 1 (mege) new commit, rebase results in 0-N new commits.

Let's say you have this history:
A---B---C (master)
 \
  D---E---F (topic)
If you merge topic to master, you get:
A---B---C---M (master)
 \         /
  D---E---F (topic)
So there's one new commit to test.
If you instead rebase topic onto master, you get:
          D'--E'--F' (topic)
         /
A---B---C (master)
 \
  D---E---F

So there are three new commits, all untested. And it's not enough to test just F'. Even if that is ok, D' and E' might still be broken.

Simple example:
 - In A there was a function "int foo(int a)".
 - In D you added a call to that function.
 - In F you removed that call.
 - B changed the function signature to "int foo(int a, int b)"

The new F' commit will be fine, as there is no call to that function. But D' and E' are broken as they still contains the call to foo with just one argument.

HTH Björn

Eugene Sajine· Oct 27, 2010, 17:58 UTC · lore

Re: Re: Why the default action for pull is merge, but not rebase?

On Wed, Oct 27, 2010 at 1:50 PM,  <Euguess@gmail.com> wrote:
Show 74 quoted lines
> On Oct 27, 2010 1:36pm, Jonathan Nieder <jrnieder@gmail.com> wrote:
>> Eugene Sajine wrote:
>>
>>
>>
>> > Thanks for prompt answer. But let me clarify:
>>
>> >
>>
>> > When you do pull git performs:
>>
>> >
>>
>> > fetch of the remote branch to the FETCH_HEAD
>>
>> > and then merge of FETCH_HEAD into the local branch
>>
>> >
>>
>> > What I'm saying is that your local branch should be rebased on top of
>>
>> > FETCH_HEAD instead
>>
>> >
>>
>> > In this case there is no such thing as "often rebased public branch".
>>
>>
>>
>> Ah, but there is.
>>
>>
>>
>> Imagine you are Junio and just received a pull request from Pat.
>>
>> Then you might try:
>>
>>
>>
>>  $ git pull pat for-junio
>>
>>
>>
>> which will do all the fetching and merging magic that "git pull"
>>
>> is known for.  Now if pat's for-junio branch is based on the tip
>>
>> of your current branch, this will be a fast-forward and it doesn't
>>
>> matter whether you merge or rebase.  But what if there are some
>>
>> intervening commits?
>>
>>
>>
>>  $ git pull eric for-junio
>>
>>  $ git pull pat for-junio
>>
>>
>>
>> If this pull were the rebasing kind, the result would be for Eric's
>>
>> commits to be rewritten based on Pat's.
>>
>
> Oh, I see. In this case you're right.
> My scenario is probably making more sense for the "centralized approach",
> where the exchange goes via some blessed bare repo on the server.
> So, I just have to run git pull --rebase to get my scenario working, right?
>
>
> Thanks!
> Eugene

Actually it seems that it will not work as i would expect... git pull --rebase is going to rebase the upstream on top of my local branch, right? Is this really intended behavior? Shouldn't it rebase my local on top of the upstream instead?

Thanks, Eugene

Jonathan Nieder· Oct 27, 2010, 18:05 UTC · lore

Re: Re: Why the default action for pull is merge, but not rebase?

Eugene Sajine wrote:
> So, I just have to run git pull --rebase to get my scenario working, right?

Maybe the “[branch "<name>"] rebase” and “[branch] autosetuprebase” configuration items could help.

Eric Raible· Oct 27, 2010, 19:30 UTC · re: Jonathan Nieder · lore

Re: Re: Re: Why the default action for pull is merge, but not rebase?

On 11:59 AM, Jonathan Nieder wrote:
Show 6 quoted lines
> Eugene Sajine wrote:
> 
>> So, I just have to run git pull --rebase to get my scenario working, right?
> 
> Maybe the “[branch "<name>"] rebase” and “[branch] autosetuprebase”
> configuration items could help.

One frustrating aspect of branch.<name>.rebase is that AFAIK there's no way for it to preserve merges.

I would much prefer if branch.<name>.rebase was allowed to specify the arguments to be passed to rebase:

	git config branch.mybranch.rebase "-i --preserve-merges"
Anyone else see the value of something like this?
Joshua Jensen· Oct 28, 2010, 02:53 UTC · re: Eric Raible · lore

Re: Why the default action for pull is merge, but not rebase?

----- Original Message -----
From: Eric Raible
Date: 10/27/2010 1:30 PM
Show 9 quoted lines
> One frustrating aspect of branch.<name>.rebase is that AFAIK
> there's no way for it to preserve merges.
>
> I would much prefer if branch.<name>.rebase was allowed to
> specify the arguments to be passed to rebase:
>
> 	git config branch.mybranch.rebase "-i --preserve-merges"
>
> Anyone else see the value of something like this?

When --preserve-merges actually preserves the merges (perhaps the rebase-i-p branch is on the way to finishing this feature?? I couldn't get it to apply...), I would like this facility very much. By default, I think rebase *should* preserve merges, and the current flattening it does now should be an option.

Josh
Kevin Ballard· Oct 28, 2010, 03:27 UTC · re: Joshua Jensen · lore

Re: Why the default action for pull is merge, but not rebase?

On Oct 27, 2010, at 7:53 PM, Joshua Jensen wrote:
Show 13 quoted lines
> ----- Original Message -----
> From: Eric Raible
> Date: 10/27/2010 1:30 PM
>> One frustrating aspect of branch.<name>.rebase is that AFAIK
>> there's no way for it to preserve merges.
>> 
>> I would much prefer if branch.<name>.rebase was allowed to
>> specify the arguments to be passed to rebase:
>> 
>> 	git config branch.mybranch.rebase "-i --preserve-merges"
>> 
>> Anyone else see the value of something like this?
> When --preserve-merges actually preserves the merges (perhaps the rebase-i-p branch is on the way to finishing this feature??  I couldn't get it to apply...), I would like this facility very much.  By default, I think rebase *should* preserve merges, and the current flattening it does now should be an option.
Sure would be nice, but that sort of backwards-incompatible change would likely break a lot of people who rely on the current flattening behavior.
-Kevin Ballard
Eric Raible· Oct 28, 2010, 06:39 UTC · re: Kevin Ballard · lore

Re: Why the default action for pull is merge, but not rebase?

On 10/27/2010 8:27 PM, Kevin Ballard wrote:
Show 17 quoted lines
> On Oct 27, 2010, at 7:53 PM, Joshua Jensen wrote:
> 
>> ----- Original Message -----
>> From: Eric Raible
>> Date: 10/27/2010 1:30 PM
>>>
>>> I would much prefer if branch.<name>.rebase was allowed to
>>> specify the arguments to be passed to rebase:
>>>
>>> 	git config branch.mybranch.rebase "-i --preserve-merges"
>>>
>>> Anyone else see the value of something like this?
>> When --preserve-merges actually preserves the merges (perhaps the rebase-i-p branch is on the way to finishing this feature??  I couldn't get it to apply...), I would like this facility very much.  By default, I think rebase *should* preserve merges, and the current flattening it does now should be an option.
> 
> Sure would be nice, but that sort of backwards-incompatible change would likely break a lot of people who rely on the current flattening behavior.
> 
> -Kevin Ballard.

But it's not backwards incompatible: only true/false are now allowed so an arbitrary string would not currently be used.

In my proposal a string would imply true, and would mean "append the specified value when running rebase".

Kevin Ballard· Oct 28, 2010, 07:13 UTC · re: Eric Raible · lore

Re: Why the default action for pull is merge, but not rebase?

On Oct 27, 2010, at 11:39 PM, Eric Raible wrote:
Show 24 quoted lines
> On 10/27/2010 8:27 PM, Kevin Ballard wrote:
>> On Oct 27, 2010, at 7:53 PM, Joshua Jensen wrote:
>> 
>>> ----- Original Message -----
>>> From: Eric Raible
>>> Date: 10/27/2010 1:30 PM
>>>> 
>>>> I would much prefer if branch.<name>.rebase was allowed to
>>>> specify the arguments to be passed to rebase:
>>>> 
>>>> 	git config branch.mybranch.rebase "-i --preserve-merges"
>>>> 
>>>> Anyone else see the value of something like this?
>>> When --preserve-merges actually preserves the merges (perhaps the rebase-i-p branch is on the way to finishing this feature??  I couldn't get it to apply...), I would like this facility very much.  By default, I think rebase *should* preserve merges, and the current flattening it does now should be an option.
>> 
>> Sure would be nice, but that sort of backwards-incompatible change would likely break a lot of people who rely on the current flattening behavior.
>> 
>> -Kevin Ballard.
> 
> But it's not backwards incompatible: only true/false are now
> allowed so an arbitrary string would not currently be used.
> 
> In my proposal a string would imply true, and would mean
> "append the specified value when running rebase".
Sorry, I meant making it the default would be a backwards-incompatible change.
-Kevin Ballard
Stefan Haller· Oct 28, 2010, 07:27 UTC · re: Eric Raible · lore

Re: Why the default action for pull is merge, but not rebase?

Eric Raible <raible@nextest.com> wrote:
Show 12 quoted lines
> On 11:59 AM, Jonathan Nieder wrote:
>
> > Maybe the "[branch "<name>"] rebase" and "[branch] autosetuprebase"
> > configuration items could help.
> 
> One frustrating aspect of branch.<name>.rebase is that AFAIK
> there's no way for it to preserve merges.
> 
> I would much prefer if branch.<name>.rebase was allowed to
> specify the arguments to be passed to rebase:
> 
>   git config branch.mybranch.rebase "-i --preserve-merges"

For me it would be good enough if there were some way of making "pull --rebase" error out in the case that merges are involved. I'll then either do a pull --no-rebase, or deal with the situation in some other way; but getting the merge "flattened" by "git pull" without being told about it is what's frustrating to me.

-- 
Stefan Haller
Berlin, Germany
http://www.haller-berlin.de/

← back to recent threads