Posted in:

I recently had the need to retrieve several old versions of a project from TFS. Fortunately, the TFS API allows you to automate this process.

First you need to connect to the TFS Server:

TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri("http://tfsserver:8080/"));
tpc.EnsureAuthenticated();

Next we will set up a workspace to use. I check first that the workspace doesn’t exist.

VersionControlServer vcs = tpc.GetService<VersionControlServer>(); //.GetAllTeamProjects(false);
string workspaceName = "temp";
string workspaceOwner = "mheath"; // your user name
// protect ourselves from using a workspace in use for something else\
Assert.Throws<WorkspaceNotFoundException>(() => vcs.GetWorkspace(workspaceName, workspaceOwner), "The workspace already exists");
var workspace = vcs.CreateWorkspace(workspaceName, workspaceOwner);

// use the workspace...

// when we are done with it...   
vcs.DeleteWorkspace(workspaceName, workspaceOwner);

Now we need to map our workspace to a local temporary folder. We can use the server path to select only a subset of the code in the project (for example a single branch):

string localPath = @"D:\TFS\Temp";
string requestPath = "$/MyProject/Dev/Source";

// protect ourselves from accidentally overwriting something important
Assert.IsFalse(Directory.Exists(localPath), "directory should not exist before this test is run");
Directory.CreateDirectory(localPath);

workspace.Map(requestPath, localPath);

Finally we are ready to make a request. We use a VersionSpec to specify which version we want. I am using a DateVersionSpec here, but you can use a ChangeVersionSet or a LabelVersionSet if you prefer. The ItemSpec specifies what to get. We want everything in our request path including subfolders, so recursion is turned on:

var version = new DateVersionSpec(new DateTime(2009, 11, 24));
var item = new ItemSpec(requestPath, RecursionType.Full);
GetRequest getRequest = new GetRequest(item, version);

GetStatus status = workspace.Get(getRequest, GetOptions.GetAll);
Assert.AreEqual(0, status.NumWarnings);
Assert.AreEqual(0, status.NumFailures);

And that is it – it is usually quite quick to retrieve as well (certainly much faster than SourceSafe was!).