- trunk
- tags
- branches
Using the āhg convertā command line, when your SVN repository is structured this way will import your trunk into the Mercurial ādefaultā branch and your branches/tags into named branches. This also imports all history and revisions. From there, you can merge as you wish to structure your Mercurial repository the way that you want.
However, in some cases we have more complicated repositories. An example of this is a structure like the following:
- trunk
- DotNet
- Flash
- tags
- branches
- v1.1-DotNet
- v1.2-Flash
In the above structure, weāve actually branched the trunk/DotNet & trunk/Flash folders separately into their own branches. Unfortunately, Mercurial doesnāt operate this way so it doesnāt really understand creating branches from folders. Thereās a couple different ways that you can get this from SVN into Mercurial whilst maintaining all of your historyā¦
One way is to run āhg convertā on the entire repository. Youāll end up with 3 branches in Mercurial: default, v1.1-DotNet & v1.2-Flash. The problem is that if you try to merge the named branches into default, youāll end up with a mess since the branches donāt have the same folder structure as default. To overcome this, you can restructure each named branch to follow the same folder structure as default. To do this, we us the ārenameā method on Tortoise Hg. So for instance, if we had this folder structure inside of v1.1-DotNet:
- BuildFiles
- MyProject.Web
- MyProject.Config
So that we can merge this with default we need to restructure this into:
- DotNet
- BuildFiles
- MyProject.Web
- MyProject.Config
So we just need to right click each folder seperately, and select the rename option from the Tortoise Hg sub menu:
Then we prefix the folder name with the new folder location which will the āmoveā the file:
Now that the named branch v1.1-DotNet is in the same folder structure as default, we can perform a merge.
The other way to import a complicated SVN structure to mercurial is to convert individual branches to mercurial repositories one by one. The first thing youāll need to do is run an āhg convertā on the Trunk of your SVN repository. This will create your new āmasterā mercurial repository for which will push the other individual mercurial repositories in to. Next, run an āhg convertā on each of your SVN branches. For example: hg convert svn://my.svn.server.local/MyProject/Branches/v1.1-DotNet.
Once you have individual repositories for your branches, we can force push these into your āmasterā repository. To do a merge of these branches, the above procedure will still need to be followed to ensure your branches have the same folder structure as default. HOWEVER, because weāve forced pushed changesets into Mercurial, it has no idea how these branches relate to each other (in fact, it gives you warnings about this when you force push). When you try to do a merge, youāll end up getting conflict warnings for every file that exists in both locations since Mercurial doesnāt know which one is newer/older. This can be a huge pain in the arse, especially if you have tons of files. If we assume that the branch files are the most up to date and we just want to replace the files in default, then thereās a fairly obscure way to do that. In the merge dialog, youāll need to select the option āinternal : otherā from the list of Merge tools:
This tells Mercurial that for any conflict you want to use the āotherā revision (which is your branch revision since you should have default checked out to do the merge).
Weāve had success with both of these options for converting SVN to Mercurial and maintaining our history.