Version control API - basic recipes  
Author Message
Carl Daniel





PostPosted: Team Foundation Server - Version Control, Version control API - basic recipes Top

I'm working on writing a simple client using the version control API and I'm having trouble with a couple of basic concepts related to server names, local paths and server paths. I'm hoping someone can fill in the gaps with a few recipes - I've looked at some of the samples on various blogs, but haven't found solutions to these basic issues:

1. Given a local path, determine the name of a TFS server that has a mapping for that path (if such a server exists). The code from the example on Buck's blog ( http://www.hide-link.com/ ) doesn't seem to work - it never finds a server name.

2. Given a local path, determine the exact name of the server path that maps to it.

3. Given a server path, determine the exact name of the local path that maps to it.

I'm only looking for solutions that work when mapping are unique - if the solution detects when there are multiple mappings, that's fine, but I don't need even that (because my mapping are always unique).




Visual Studio Team System38  
 
 
Buck Hodges





PostPosted: Team Foundation Server - Version Control, Version control API - basic recipes Top

Here the conversion code for a local path, boiled down to the basics. What this does is use the local paths stored in the user's workspace cache file to get the workspace information (name, owner, server) for a given local path. If it doesn't find it, it returns null. In order for this code to work, the workspace cache file has to exist and be populated with the user's workspaces. This is the same call that tf.exe uses to determine the workspace and server for a given local path. If you aren't getting the workspace info for a local path that really is mapped, make sure that it's listed in your workspace cache file (tf workspaces).

WorkspaceInfo wsInfo = Workstation.Current.GetLocalWorkspaceInfo(path);

// Stop if we couldn't figure out the server.
if (wsInfo == null)
{
Console.Error.WriteLine("Unable to determine the server.");
Environment.Exit(1);
}

Getting the local path for a given server path is less straightforward, because a single server path may be in more than one of the users workspaces. Furthermore, the server path portion of a workspace mapping is not stored in the workspace cache file. So, if you want this information, you'll need to use the QueryWorkspaces() call on VersionControlServer to get a list of the current user's workspaces on the current computer. Then you'll need to iterate through the list of workspaces returned, which may be empty, and call TryGetLocalItemForServerItem() on each Workspace object. If the item is mapped, you'll get the local path. If not, you'll get null. I'd likely get something wrong off the top of my head, but I can give you a snippet tomorrow if you like.

Buck



 
 
Carl Daniel





PostPosted: Team Foundation Server - Version Control, Version control API - basic recipes Top

OK, that's basically the code that I found in one of the examples on your blog - but it's not working in my program.  I'm running my client in a directory where tf.exe is able to find the server yet my code doesn't.  I'll have to look at it more closely tomorrow to see what I'm overlooking.

A difficulty with what I'm trying to do is that Workstation.GetLocalWorkspaceInfo needs a local path, but VersionControlServer.QueryLabels (apparently) needs a server path (*), and I don't want to have to supply both.  Rather, I'd like to accept a local path, use it to find the workspace, use that the find the server path (and the server) so that I can call QueryLabels on the server path.

An unrelated oddity - Microsoft.TeamFoundation.VersionControl.Common didn't appear in the Visual Studio add reference dialog - I had to browse to the file myself.  Is there a known issue with that, or is my installation somehow messed up

* I say apparently because the available documentation doesn't say, but it doesn't seem to do anything but throw an exception when I give it a local path.



 
 
Buck Hodges





PostPosted: Team Foundation Server - Version Control, Version control API - basic recipes Top

QueryLabels() can be used with either local or server paths. The only restriction is that the local path must be mapped to a workspace (under the covers, the workspace name and owner are sent to the server, along with the local path, so that it can do the right thing). As a result, you don't have to convert the local path to a server path. Generally speaking, methods that take paths will take either local or server paths.

Regarding Microsoft.TeamFoundation.VersionControl.Common, VS requires you to manually add the assemblies to the Add Reference dialog. Here's a script to do it: http://blogs.msdn.com/buckh/archive/2006/01/12/511886.aspx.

Buck



 
 
Carl Daniel





PostPosted: Team Foundation Server - Version Control, Version control API - basic recipes Top

Hmm.. I'll have to try QueryLabels again with a local path - I was getting an exception from deep inside that seemd to be complaining about the local path.

I knew I'd seen something about adding those items to the Add Reference dialog - funny thing was, the other 3 that I needed were already there - just .VersionControl.Common was missing. Thanks for the link!



 
 
Carl Daniel





PostPosted: Team Foundation Server - Version Control, Version control API - basic recipes Top

Trying again with a local path, I'm getting this exception from QueryLabels:

VersionControlException:TF10125: The path 'C:\Development\Products\Product1\Branches\1.0' must start with $/
   at Microsoft.TeamFoundation.VersionControl.Client.Repository.ProcessHttpResponse(HttpWebResponse response, Stream responseStream, WebException webException, XmlReader& xmlResponseReader)
   at Microsoft.TeamFoundation.VersionControl.Client.Repository.ExecWebServiceRequest(HttpWebRequest request, XmlWriter requestXml, String methodName, HttpWebResponse& response)
   at Microsoft.TeamFoundation.VersionControl.Client.Repository.QueryLabels(String workspaceName, String workspaceOwner, String labelName, String labelScope, String owner, String filterItem, VersionSpec versionFilterItem, Boolean includeItems, Boolean generateDownloadUrls)
   at Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer.QueryLabels(String labelName, String labelScope, String owner, Boolean includeItems, String filterItem, VersionSpec versionFilterItem, Boolean includeDownloadInfo)
   at Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer.QueryLabels(String labelName, String labelScope, String owner, Boolean includeItems)
   at ... my code

The path that was passed to QueryLabels is mapped to the corresponding server path: $/Development/... via a single mapping ($/Development maps to C:\Development).  What am I missing

 I hacked up a quick iteration through the workspaces as you outlined above.  Passing the server path that I found via that route to QueryLabels works just fine.

 



 
 
Richard Berg MSFT





PostPosted: Team Foundation Server - Version Control, Version control API - basic recipes Top

Is the app in question running as the same user who owns the c:\Development workspace

Glad to hear the server path works.

 
 
Buck Hodges





PostPosted: Team Foundation Server - Version Control, Version control API - basic recipes Top

Hmmm, I used a local path for the filterItem in the following usage of QueryLabels (A\a.txt in the last example): http://blogs.msdn.com/buckh/archive/2005/10/25/484854.aspx.

What does the call look like In particular, what version spec is being passed

Buck



 
 
Carl Daniel





PostPosted: Team Foundation Server - Version Control, Version control API - basic recipes Top

I'm calling the 4-parameter version of QueryLabels, which doesn't accept a VersionSpec.  I'm passing in labelName (e.g. 'AFF-20060720-2211'), labelScope (the path in question), owner (null), includeItems (true).

From the example you cited, it looks like I need to call the 5- or 6-parameter version, passing my path as filterItem instead of labelScope.  I'd looked at that example before but didn't realize that you'd used a different overload of QueryLabels than I did.

Since getting the server path seems to give the results I was looking for, I'll probably just leave it the way it is, but it's always good to know why things are the way they are!



 
 
Buck Hodges





PostPosted: Team Foundation Server - Version Control, Version control API - basic recipes Top

Oh, I see. I assumed the issue was with filterItem, but you were talking about labelScope. I should have asked -- sorry about that. Looking at the code, the server requires that the labelScope is a server item.

Buck



 
 
zot





PostPosted: Team Foundation Server - Version Control, Version control API - basic recipes Top

I tried but I couldn't find any documentation for the class TeamFoundationServer. Do you know how I can find it on the msdn site
Thanks.

 
 
Carl Daniel





PostPosted: Team Foundation Server - Version Control, Version control API - basic recipes Top

You can't find it on the MSDN site. You have to download and install the Visual Studio SDK from the VSIP site (which requires becoming a VSIP member - the "affiliate" membership is free).

See http://msdn.microsoft.com/vstudio/extend/ to get started.



 
 
zot





PostPosted: Team Foundation Server - Version Control, Version control API - basic recipes Top

got the docs. Thanks :)