I'm starting with a Mercurial repository which has multiple subrepositories that I'm trying to merge into it, as if they had always been a part of the main repository. They should have never been subrepositories in the first place.
I put together a process to convert the old history into a single repository:
The problem I'm left with is that the history is unusable, i.e. I can't go back and update to a specific version, because each branch only has its own data. So let's say my main repo is A and my subrepos are B and C: if I update to history of branch A, it doesn't have the files from branch B or branch C, and if I update to history of branch B, it doesn't have files from branch A or branch C.
What I want is some way to merge the whole history together, so it is mostly a single branch, and the files from all the branches appear in each commit. Is there a way to convert it so all the history of the branches are merged, and not just a single merge at the very end?
I have a working process now. Instead of doing a pull --force for each step:
This works because the patch doesn't carry the full version information, just what has changed. It doesn't expect the parent to match up to where it was exported from, just the files you're patching. And since each patch only affects files from one branch on one repository, this is a perfectly reasonable thing to assume.
Changesets which are merges are a bit trickier. I have to edit the patch file to match up its source node ID to the newly imported node ID. This is why we must capture the node ID in step 5 above. You can import a merge changeset as long as you use --exact, but that doesn't work unless the 3 nodes in the patch file match the actual nodes in the repository.
So in case of a merge, after step 2 above, modify the patch file so each "# Parent" matches the correct parent node ID in the target repository. Then after it has been imported, update the patch file again, this time replacing "# Node ID" with the imported node ID.
At this point, the patch file should have all 3 accurate node IDs, and a "hg import --exact --bypass" will work. This second time you import the patch, it will overwrite the existing node you already imported, but it will mark it as a merge between the proper nodes.
The other slightly tricky part is to make sure merges are correctly parented. Each merge is defined in terms of 1 branch merging into the other. If you choose the wrong parent, the merge will fail. So we define the main branch as the branch which all other branches were merged into. When merging two repositories together, you have to start at the tip and follow the main branch back to the beginning. Only the main branches from each repository should be concatenated together, and the other branches stay as separate branches.