views:

548

answers:

2

I have a subversion repo with the following layout:

svnrepo/projectA/trunk
svnrepo/projectA/tags
svnrepo/projectA/branches
svnrepo/projectB/trunk
svnrepo/projectB/tags
svnrepo/projectB/branches


which I would like to move to a mercurial repo with a revised layout:
hgrepo/projectA
hgrepo/projectB

What is the best way of doing this? Some of my thoughts are:

Option1

Rearrange the paths in subversion (using svn move) to an intermediate format:

svnrepo/trunk/projectA
svnrepo/trunk/projectB
svnrepo/tags/projectA
svnrepo/tags/projectB
svnrepo/branches/projectA
svnrepo/branches/projectB

then hg convert on the svnrepo/trunk. Will this confuse hg importing?

Option 2 hg convert each of the projects/trunk into separate hg repos. Then merge them into a single hg repo (using hg init, hg pull -f projectA, etc). I think this will lose the branch names and tags on the first imported project.

+6  A: 

In Mercurial, storing unrelated codebases in the same repository is a bad idea because it will

  • Significantly complicate merging. Merges will depend on changes made to all projects, rather than just the project you're trying to merge.
  • Cause storage and checkout overhead -- Mercurial, as far as I know, does not support checking out only subdirectories of a repository. You'd have to branch all projects at once.

The solution is to convert your single Subversion repository into multiple Mercurial repositories. Most conversion tools support this.

John Millikin
+4  A: 

Each project should be in its own Hg repository (to be able to get or tag only a specific project).

Remember than the directory you see in Subversion (trunk, tags, branches) will not exist in any modern (D)VCS, where branches and tags are first class citizen (i.e. meta-data directly managed by the tool), as opposed as simple directory resulting from a cheap copy (in SVN).

That means when you convert a SVN repository, you should not store directly any "trunk", "tags" or "branches" directory in the history of the Hg repo.

You should rather use a tool like hgsubversion to import your SVN repo (like just "repo/projectA") into a Hg repo dedicated to the projectA. it will keep tags and branches of the orignal SVN project and convert them into Hg objects.
From its documentation:

All updates using hgpullsvn are made in the branch named from the last component of the SVN URL (e.g., if the SVN URL is svn://server/myproj/branches/feature-ZZZ, hgpullsvn will create and use the named branch 'feature-ZZZ')


If you do not want "convert" but "syncing", tonfa recommend hgsubversion, although it "is currently in a state of flux due to heavy refactoring":

Right now it is not ready for production use. You should only be using this if you're ready to hack on it, and go diving into the internals of Mercurial and/or Subversion.

Since hgsvn also allow some syncing through hgpushsvn and hgpullsvn... I would stick with hgsvn for now.

VonC
Please do not advocate hgsvn, hgsubversion is the preferred way to handle svn live syncing (as opposed to "final" conversions as done by hg convert).
tonfa
you mixed the two tools now. (I still think hgsubversion is better, even if it doesn't advertize itself for production use, it is the long term solution).
tonfa