Guillaume Vincent
Guillaume Vincent

Reputation: 14811

Merge two mercurial repositories without breaking file history

I need to merge two mercurial repositories into a brand new, third repository.

Project A:

1--2--3

Project A':

4--5--6

What I want :

Project B:

1--2--3--4--5--6

History was deleted from Project A because of size limitation on my server. I don't have size limitation anymore. I want to bring back

similar to this question except that I need a solution for mercurial

Upvotes: 0

Views: 352

Answers (1)

Nanhydrin
Nanhydrin

Reputation: 4472

You can certainly do this and preserve the history, but your changeset hashes will almost certainly change from the originals.
Also, before I go on, backups, backups, backups. Make sure you're preserving your originals in case this all goes horribly wrong, which it very well could.

Off the top of my head you have two options.
Both start with you pulling Project A' into Project A using the --force option to allow you to pull in an unrelated repository. E.g.

hg pull --force ProjectA'

Lets call this new combined repo Project A+.

Rebase

Then you could use the Rebase extension (which needs to be enabled in your Mercurial extension settings) to rebase changeset 4 and it's descendents onto changeset 3. For example:

hg rebase --source 4 --dest 3

You might also want to use the --keepbranches option, or it might reset all your branch names to that of revision 3.
I've never used this particular tactic myself but I don't see why it wouldn't work.

Convert

The second option, which I have used before, is hg convert with a splicemap.
The splicemap option lets you specify new parents for changesets, so you'd be able to specify that rev 3 was rev 4's parent whereas right now rev 4 presumably has no parent.

The splicemap is basically a text file, and the contents are formatted like:

revision-hash new-parent-hash

and each map in the file is separated by a new line.
You have to use the full hash, the friendly revision number or short hash won't work.

Then to actually use the splicemap you do the following:

hg convert --splicemap splicemap_filepath.txt ProjectA+ ProjectB

And that will spit out a Project B repo with a unified history.

Depending on the size of your repos neither of these will be quick.

Upvotes: 3

Related Questions