TFSが公開するHTTPAPIを介してこれを実行できることを発見しました。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
「バージョン」は、TFSAPIドキュメントに記載されている任意のバージョン仕様にすることができると思います。私の例は、変更セット1001の時点でのバージョンを要求しています。.NETAPIを使用して特定のバージョンを取得しました。これは非常に簡単ですが、一度に1つのファイルしか取得できないため低速です。この方法でファイルをダウンロードする方が、一度に1つのファイルを取得するよりもはるかに高速であるため、これと同じ機能が.NETAPIを介して公開されているかどうかを調べようとしています。
これを拡張メソッドとして実装しました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();
}
}