SubVersion Migration

This post is one of multiple posts to come on experiences learned from source control. Below are the long term goals:

  1. Restructure the repository and split out projects appropriately
  2. Migrate the source control to a new server as the old server is being decommissioned
  3. Move to Team Foundation Server

Current Scenario

In planning for migration of SubVersion repositories from one server to another, we took the opportunity to re-structure how projects were kept in SubVersion. As it has been, the structure lives as follows:

Sitecore
- trunk
  - Project1
  - Project2
  - Project3
- branches
  - Project1 1.2.0
  - Project2 3.7.0
  - Project3 8.0.0
- tags

Typically, branches have been used to hold new development of features while trunk could be kept for hotfixes. Since each project does not seem to be related or dependent on each other, it seems appropriate to separate each project into its own repository.

Steps for Migration

The goal of the migration is to move each project into its own repository. To do this, the following steps were proven to reach our goal:

Create a dump of the entire repository

Initially, the repository was thought to be migrated in one command:

svnadmin create Project1

svnadmin dump E:\Repositories\Sitecore | svndumpfilter include "/trunk/project" | svnadmin load E:\Repositories\Project1

This did not work. It seem to create a dump file with only revision history. When the new repository was created and loaded with the dump file, there were no files present. At this point, we needed to prove another way to accomplish our goal.

As we started over, we started with just creating an initial dump of the repository:

svnadmin dump E:\Repositories\Sitecore > Global.dump

Filter dump file to create project specific dump file

Now what we needed to do is filter what we wanted into a new dump file. Below is the command used to filter out revisions that relate to the project that is stored under the repository in SubVersion:

svndumpfilter include "/trunk/project/" < Global.dump > Project.dump

When running this command, we found that some revisions were tied to other projects. We encountered the following error:

Invalid copy source path '/trunk/project2/js'

In those cases, we just added the specific sub-path to be included as the below example follows:

svndumpfilter include "/trunk/project/" "/trunk/project2/js" < Global.dump > Project.dump

"/trunk/project2/js" will include the specific item needed to satisfy the dependency. If it doesn't add too much work in the end, we will just delete the other project out of destination when we are done.

The next issue that surfaced during the migration were branches that are missing their source as part of the merge. You may see an error as follows:

Missing merge source path "branches/project 2.0/

So then we add the following to the commend:

svndumpfilter include "/trunk/project/" "/trunk/project2/js" --skip-missing-merge-sources < Global.dump > Project.dump

It seems adding this command allows the filter to skip over previous branches that may not exist anymore or merge sources.

After the dump is successfully created that targets the project, we can proceed with loading the dump file into a newly created repository. In a previous step, we already did this. If you are using a product for managing your SVN repositories such as VisualSVN Server, you may want to create the repository with the administrative interface and then proceed with loading the dump file. See http://www.visualsvn.com/support/topic/00010/#import-incompatible for more information.

We can finish with the command:

svnadmin load E:\Repositories\Project1 < Project.dump

Finally, since we have our new repository that is specific to our project, we can proceed with cleaning up things we needed to include from the filtering to meet dependencies and any restructuring of the repository as necessary. Once we were done, our repostory looked as the following:

Project1
- trunk 
  - lib
  - Tools
  - etc
- branches
  - Project1 1.2.0