views:

107

answers:

2

Is it possible to merge a range of revisions from one branch to another in Mercurial?

e.g.

|r1
|r2
|r3
|\___
|    | r5
|    | r6
|    | r7
|    | ...
|    | r40
|r41  

If I want to merge revisions 6 & 7, but not 5, into the main branch - is this possible?

Such a merge can be trivial, for example, if r5 modified files that are not modified in 6 & 7 (and so its changes, if not needed, can safely be ignored)

What about multiple selected revision ranges from branch A to branch B? e.g. merge 4-7, 20-25 and 30-34?

(this isn't a real case, just an illustration. I'm trying to understand if hg has this revision-range merge feature that I know svn has)

+5  A: 

Check out the Transplant extension for mercurial, I think it will do exactly what you want.

http://mercurial.selenic.com/wiki/TransplantExtension

Nate Heinrich
+3  A: 

The simple answer is no.

This is contrary to the spirit of Mercurial.

Your graph implies that 6 depends upon 5 so anything that pulls 6 should pull 5 also otherwise it makes no sense.

It seems to me that you got Mercurial wrong here. If your change tree is linear, it's usually a sign that you are using Mercurial like you would use CVS or SVN.

Your change tree should look more like:

   4
  / \
 /| |\
/ | | \
5 7 23 \
| | |   25
6 8 24  |
        26

And then you could pull either the branch starting at 5 or the one starting at 23.

Now, mistake is human, so there is a "facility" called export, which allow you to create a simple diff file from one changeset.

In your specific case, you would thus:

  • clone the repository up to r4
  • create a diff from r6 and one from r7 (export)
  • apply both (in order) on the new clone (import)
  • run your unit tests until they pass
  • commit
  • pull in r41
  • merge
  • run your unit tests until they pass
  • commit

If you wish, you can also go the extension road. There are several useful extensions for manipulating the changesets. A sample set:

Here you could for example clone the repository (important, always test these on clones, just in case) and then collapse the ranges you are interested in. Then you can export/import them.

Matthieu M.
It's not true that r6 must depend on r5 in any meaningful way. For example, it could be that r5 changes only some file that other revisions do not touch, so there's absolutely no problem ignoring that particular revision (from a data-centric standpoint). Please do not assume I'm using hg in this way, I'm just trying to understand its capabilities.
Assaf Lavie
Also, I didn't quite get what you means by the way the tree _should_ look. Your tree illustration shows multiple branches with few revisions. Is that the spirit of hg - to only have short branches? Because sometimes you simply need a separate branch to do a lot of work on that's not going in the trunk. If you maintain many historic versions it's not feasible to have a repository per version, so branches are the only reasonable solution. So how do you suggest to keep these branches short, and why would that be better than having multiple divergent branches when needed?
Assaf Lavie
r6 depends on r5 because you said it did when you made r5 r6's parent. If you want to avoid that, and they're truly unrelated, you can 'hg update' to a different parent before making change 6. If before doing r6 you had done 'hg update r4' then r6's parent would be r4, and you could move it to any branch of development that already had r4.In the broadest sense when making a change ask yourself "what's the earliest point in history I could've done this" and then 'hg update' to that point. Then you have a changeset that can be easily merged anywhere it makes sense.
Ry4an
@Assaf: The branches need not be short, though it's not obvious from the example. The point is that branches are natural in `hg` while perhaps not so in SVN. What I was trying to say is that when you have v2.3 of your soft, then each bug fix should be on a branch of its own. This way when making v2.3.1 you'll select those you wish and let the others pending (perhaps because you haven't fully tested them). Also if your customer request only one bug fix because they are fearful of new bugs, then you have the ability to deliver it. So my point was it's strange you have so few branches :)
Matthieu M.
I find it hard to believe that most development can indeed occur on such independent and unrelated branches. Often while working on a bug you realize you have to do some more basic refactoring while you're working - so do you do this on a separate branch? Development is usually a cumulative effort, where - by default - you wish to work on the latest, most debugged version. It's only the exception to the rule (sometimes you want to work on an older version for some reason) that suggest branches are needed. I guess I still don't get why I need to juggle dozens of branches all the time. [tbc]
Assaf Lavie
Cross-cutting changes occur all the time (e.g. refactoring some basic library), and even though these are theoretically independent of the feature I may be working on, it's still a better version of the code-base. If it were to occur on strictly separate branches I'd then have to merge this cross-cutting change to all other branches I keep... why? What do I gain from this? Being able to choose which fixes go into the next release is usually not the biggest problem the project has. Usually if something's fixed, it's going in the next release. So, again, the exception is becoming the rule here.
Assaf Lavie