Why I prefer rebase to merge. Is there a better alternative?

John Arbash Meinel john at arbash-meinel.com
Wed Oct 14 17:10:30 BST 2009

Hash: SHA1


> I have a main branch "mainline" and I branch "feat1" from it. I make some 
> changes in feat1 and, when I am read to propose feat1 for integration into 
> mainline, I bzr merge the latest mainline into feat1. At this point I 
> usually find some problems that take some days to be resolved. By the time 
> I'm ready to propose feat1 again, mainline has changed and I have to bzr 
> merge another time; luckily this time the merge does not produce any 
> conflict and I can bzr merge feat1 into mainline.

Why do you have to merge the second time? If you are just checking for
conflicts, you can do the merge, see that it succeeds, then 'bzr revert'
and go about merging feat1 into mainline (proposing it for review, etc.)

Alternatively, you can 'bzr merge --preview' and see if it does what you

> Result: mainline's history contains a merge that contains two (unneeded?) 
> merges and only one commit with the (little) feature. I do not like this: 
> bzr is recording in feat1 two merges that I did because I *had to*, not 
> because I intended to do them (by contrast I *intended* to merge feat1 into 
> mainline). I think that the fact that a branch is synchronized with its 
> parent and how many times that synchronization is performed is just an 
> "implementation detail", not something meaningful to the development and 
> thus should not be recorded, at least not always.

You *had to* resolve the conflict with mainline, whether you did this in
your feature branch, or whether you would have done it when landing onto

> This is why I use rebase instead of merge. Rebase performs this 
> synchronization without recording anything and without "polluting" the 
> history.

It doesn't really. You still have to resolve the conflict. It just
happens that now you are throwing away what you used to have, and
replacing it with something that looks conflict free.

Does the fact that you had to resolve a conflict matter? Maybe, maybe
not. Does having a pristine history matter? Is it better to show what
really happened (you did X, Y, Z, resolved a conflict, and then did D),
or is it better to show the simplified view (X', Y', Z')?

Almost always these come down to personal preferences. I went through
something where I wanted "nice discrete patches" for review, and did so
without using rebase, etc.:

I did it after I had worked on all the features combined, which meant
that I didn't have to think about how I would factor it out until I
proposed it for review. I got to keep my annotations, so I didn't have a
single "add SimpleSet" commit message as describing every line of the file.

> I understand the implications of rebase (history-rewriting is generally bad 
> and hinders additional development on top of branches where it is used) but 
> I think that merge, at least as it works now, is being used for two 
> different functions, one of which is wrong (synchronizing before proposing).
> Maybe what is needed is another version of merge: this new merge would do 
> whatever is needed to keep they history in sync without "polluting" the log 
> and the history with unintended merges.

'bzr merge ../trunk; bzr revert --forget-merges' would approximate this.

However, I would generally say "if a merge actually provides no benefit,
'bzr revert' it". Otherwise IMO it *does* provide information. It shows
that something happened (I brought in more features from trunk, I
resolved conflicts with trunk, etc.)

> Does anyone share my feeling about merge? Are there better workflows that 
> can be used to obtain the same result without implementing a new kind of 
> merge?

Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/


More information about the bazaar mailing list