At work we currently use Serena Version Manager and Tracker products (PVCS) for our source control and issue tracking. As previously (albeit briefly) mentioned, we are in the process of converting to Team System. Ultimately we decided to start the source control repository clean instead of importing our source trees from Version Manager. I did some exploratory work on figuring out how to do an import, and although it's not fully fleshed out, I'd like to throw my findings out there in the hopes this will help someone.
Okay, now to my (rough) approach. The first goal was to retrieve all version history from VM. After many fruitless online searches I eventually found what I needed, a command line utility which provides an interface to VM. This utility is pcli.exe, which I found in C:\Program Files\PVCS\win32\bin, but obviously your installation will differ. I had trouble finding documentation online for this program, however if you type "pcli -h" you will see a list of commands. You can type "pcli command -h" to get assistance on options for a particular command.
I used this utility to retrieve a list of all files within a particular folder (and all its subfolders) including all revision information for each file. I ran the following command to retrieve this list: pcli.exe vlog -z -idUSERNAME:PASSWORD -fOUTPUT.TXT -pr"PROJECT NAME" PATH_IN_VM
The "vlog" command reports archive/revision information. If you type "pcli vlog -h" you can see a full list of options. Several things to note about the command line I used. The "-z" argument recursively processes the path. Username and password are separated by a single colon. The project name should be in the form \\NAME with no trailing backslash. The PATH_IN_VM, however, must use forward slashes, with a forward slash starting the path and no trailing slash. I believe I tried different combinations and settled on these - other combinations might work, but I know for a fact that these will.
If you execute this on a VM project you should have an OUTPUT.TXT that contains information such as what follows next. I'll first show example contents and then discuss how to parse it and use the information. Before discussing this file, I should again caution that I barely scratched the surface of parsing this file. My focus was narrow, simply only needing each revision number of a particular file and some extra information such as author, check in comments, etc. Okay, here's a sample OUTPUT.TXT
Archive: \\SampleProject\archives\Dev\Web\PrototypeSite\Default.aspx-arcWorkfile: Default.aspxArchive created: Oct 10 2006 13:37:44Split mode: Split \\SampleProject\archives\Dev\Web\PrototypeSite\Default.aspx-arcOwner: jeffLast trunk rev: 1.2Locks: Groups: Rev count: 3Attributes: WRITEPROTECT CHECKLOCK NOEXCLUSIVELOCK EXPANDKEYWORDS NOTRANSLATE NOCOMPRESSDELTA NOCOMPRESSWORKIMAGE GENERATEDELTA COMMENTPREFIX = "" NEWLINE = "\r\n"Version labels: "Baseline 1.0" = 1.2 "SCR-1" = 1.2Description:Baseline 1.0
-----------------------------------Rev 1.2Checked in: Oct 11 2006 11:53:04Last modified: Oct 11 2006 11:52:14Author id: jeff lines deleted/added/moved: 6/6/0added custom httpmoduleResolution for 1: baseline-----------------------------------Rev 1.1Checked in: Oct 10 2006 17:43:24Last modified: Oct 10 2006 17:40:46Author id: jeff lines deleted/added/moved: 0/7/0added login screenResolution for 1: baseline-----------------------------------Rev 1.0Checked in: Oct 10 2006 13:37:44Last modified: Sep 27 2006 16:48:04Author id: jeff lines deleted/added/moved: 0/0/0creation of web project===================================
The first line of the file (and first line of text after any line containing only equal signs, ====) provides the full path to the file, however you need to strip the -arc at the end and also take out the archives\ directory. Since we want revision information, the next step is to skip ahead to the first line of dashes. After each dashed line we can read the revision number that appears after "Rev". In my parser I also parsed out check-in date, author ID, etc., but we only need revision numbers to retrieve a particular revision from VM. Also note that revisions are listed in reverse check-in order, so the latest revision comes first. When reading the revision information, either place this into a Stack (which you can then convert to an array via ToArray(), which will then be in the order you want) or process a List in reverse order. Again, each file is separated by a line of equal signs, so when you hit this line you know to stop processing the current file.
Now that we have all files in our repository and all revision information for each file, we have to construct a call to PCLI to retrieve a particular revision. This is the part that is ridiculously slow and sets off my internal alarms that scream THERE IS A BETTER WAY TO DO THIS! I just didn't dig in deep enough to find out the better way and I couldn't be bothered to do so now.
The command to retrieve a particular revision of a file is: pcli.exe run -y -ns get -id USERNAME:PASSWORD -o -a"c:\local\path\here" -wREV# -pr"PROJECTNAME" PATHNAME
"run" is the command, which we use to execute a specific PCLI command which, in this case, is "get"
The -y and -ns options stand alone, -y specifying that all prompts should be answered "yes" (I ran this from a C# program and did not want any user interaction) and -ns prevents extra stripping of quotes from command line.
The -id option is used again to specify credentials.
The -o option is used to override work file location so we can pull the file down to a directory of our choosing without needing to deal with work file locations.
The -a option is used to specify where the retrieved file should go.
The -w option specifies which revision number we want, such as -w1.0
The -pr option is used to specify the project and should be in the same format as our previous invocation of PCLI, for example, \\SampleProject
Now we have all the pieces to get a full list of files/revision history from VM and automatically retrieve a particular revision of a file. You can write a program to automatically invoke PCLI to create the revision history file, parse that file and pull down revisions one by one. I would suggest first processing all 1.0 revisions of all files within a particular root folder and then using Team Foundation Server's source control API to add these files. Then process all 1.1 revisions, checking these into Team Foundation server. And so on... Along with your check ins to TFS you can include original information such as author ID, check in comments, check in date, etc., so you can maintain a reasonable degree of information, hopefully alleviating the need to keep VM around for historical purposes. I'm leaving out details of the TFS source control API since it is documented well in many other places, but if you would like some suggestions or help, please leave a comment.
I'm almost ashamed to document such a clunky method of export/import, but without devoting significantly more time to exploring PCLI and various VM interfaces, this method was the best I found that I knew would work. There are (at least) two ways to improve on what I discussed, but I did not figure out how to do either. First, I believe there is a way to do batch operations with PCLI so you don't need to pull down a single revision at a time. Second, I came across a client API, but did not readily see how to do authentication so I was not sure how to properly connect to a repository and perform the calls needed.
I really hope this helps someone out there :)
Powered by: newtelligence dasBlog 1.9.6264.0
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2009, Jeff Scanlon
E-mail