Mercurial merge technique
We’re using Mercurial here at LShift for much of our development work, now, and we’re finding it a great tool. We make heavy use of branches (“branch per bug”) for many projects, and this is also a pretty smooth experience. One issue that has come up is policy regarding merging the trunk (“default”) into any long-lived feature/bug branches: should you do it, or should you not?
My vote is that you should merge default into long-lived branches fairly regularly; otherwise, you have a big-bang, all-at-once nightmare of a merge looming ahead of you. If you do merge frequently, though, there’s one subtlety to be aware of:
is not history aware, so in order to get an accurate, focussed picture of all the changes that have been made on your long-lived branch, you need to do one of two things:
- either, merge default into your long-lived branch right before you merge the long-lived branch back into default, and run
after that’s complete; or * (recommended) do a throw-away test-merge of the long-lived branch into default directly.
Imagine a history like this:
(2) (3) | | \ / V | (1)
… where (1) is an ancestral revision, (2) is the default branch, and (3) is the long-lived branch – let’s call it “foo”.
Given this history, running
(to make the working copy be the default branch, i.e. revision (2)) followed by
will give you a misleading diff – one that undoes the changes (1) to (2) before doing the changes from (1) to (3). This is almost certainly not what you want!
Instead, run a test merge, by
and then plain old
. Note that this modifies your working copy! You will need to revert (by
) if you decide the merge isn’t ready to be committed.
The output of
shows a history-aware summary of the changes that the merge would introduce to your checked-out branch. It’s this history-awareness (“three-way merge”) that makes it so much superior to the history-unaware simple diff (“two-way merge”).