我发现您可以通过 TFS 公开的 HTTP api 执行此操作。URL 的“签名”如下:
http(s)://{server}:{port}/tfs/{collectionName}/{teamProjectName}/_api/_versioncontrol/itemContentZipped?version={versionSpec}&path={escapedPathToFolder}
因此,如果您在 DefaultCollection 中有一个名为“MyProject”的项目,并且想要获取名为“MyFeature”的文件夹的内容:
http://MyTfsServer:8080/tfs/DefaultCollection/MyProject/_api/_versioncontrol/itemContentZipped?version=C1001&path=%24%2FMyProject%2FMyFeature
我认为“版本”可以是 TFS API 文档中记录的任何版本规范。我的示例是请求更改集 1001 的版本。我使用 .NET API 来获取特定版本,这非常简单,但速度很慢,因为它一次只能获取一个文件。我试图弄清楚是否通过 .NET API 公开了相同的功能,因为以这种方式下载文件比一次获取单个文件要快得多。
我将此作为扩展方法实现,Microsoft.TeamFoundation.VersionControl.Client.Item.
它返回一个包含 zip 文件的流。我曾将此用作自定义 MSBuild 任务的一部分,然后将此流的内容保存到文件位置。
public static class TfsExtensions
{
const String ItemContentZippedFormat = "/_api/_versioncontrol/itemContentZipped?version={0}&path={1}&__v=3";
public static Stream DownloadVersion(this Item folder, VersionSpec version)
{
if (folder.ItemType != ItemType.Folder)
throw new ArgumentException("Item must be a folder", "folder");
var vcs = folder.VersionControlServer;
var collectionName = vcs.TeamProjectCollection.CatalogNode.Resource.DisplayName;
var baseUri = folder.VersionControlServer.TeamFoundationServer.Uri;
if (!baseUri.LocalPath.EndsWith(collectionName, StringComparison.OrdinalIgnoreCase))
baseUri = new Uri(baseUri, baseUri.LocalPath + "/" + collectionName);
var apiPath = String.Format(ItemContentZippedFormat, version.DisplayString, WebUtility.UrlEncode(folder.ServerItem));
var downloadUri = new Uri(baseUri, baseUri.LocalPath + apiPath);
var req = WebRequest.Create(downloadUri);
req.Credentials = CredentialCache.DefaultCredentials;
var response = req.GetResponse();
return response.GetResponseStream();
}
}