Merging two different repositories

I've 3 repos, A, B and C, all related to the same project. A is the oldest version of the project, B is an experiment that didn't really go anywhere and C is the latest working version. All these repos have different files - they're different implementations of the same product.

I'd like to merge these 3 repos into one keeping their history - this is vital. I guess I want to stack B on top of A and C on top of B but when I checkout the project I only want to get the changes related to repo C.

My idea is to tag or create a named branch on A, hg rm *, commit and then pile B on top. Repeat the same with B so I can pile C and then continue on the project as usual.

What do you think? Also, some inspiration for what I want to do: 1, 2.


You can just pull the changesets into one big repository. Start with the A repo:

$ hg init combined
$ cd combined
$ hg pull ../A
$ hg update

Then forcibly pull in B and dummy-merge the two heads so that you keep the files from B:

$ hg pull ../B --force
$ hg merge --tool internal:other
$ hg revert --all --rev tip
$ hg commit -m "Merge A and B, kept B"

Then repeat for C:

$ hg pull ../C --force
$ hg merge --tool internal:other
$ hg revert --all --rev tip
$ hg commit -m "Merge B and C, kept C"

That gives you three lines of history and a merge point where you first throw away A, then B, and finally end up with C.

Alternatively you can use the convert extension with a splice map to splice the three histories together. Start by forcibly pulling all the changesets into a single repository. Then do a Mercurial to Mercurial conversion where you add the tip of A as the first parent of the root of B. Similarly for B and C. That gives you one long history where there will be a very abrupt change when you go from A to B and from B to C.

I would go with the first option: it's the most explicit and shows best what happens without faking (converting) the history.