How to get specific version of folder from tfs without creating a workspace?

感情迁移 提交于 2019-11-30 05:06:10

I use this syntax for temporary workspaces:

tf workspace -new %JOB_NAME%;%user% -noprompt -server:http://%host%:8080/tfs/%project% -login:%user%,%password%
tf workfold -map $/Release/MilestoneX.X . -workspace:%JOB_NAME% -server:http://%host%:8080/tfs/%project% -login:%user%,%password%
tf get . -version:L%TFS_LABEL% -recursive -noprompt -login:%user%,%password%
tf workfold -unmap . -workspace:%JOB_NAME% -login:%user%,%password%
tf workspace -delete %JOB_NAME%;%user% -noprompt -server:http://%host%:8080/tfs/%project% -login:%user%,%password%

I've discovered that you can do this through the HTTP api that TFS exposes. The "signature" for the URL is as follows:

http(s)://{server}:{port}/tfs/{collectionName}/{teamProjectName}/_api/_versioncontrol/itemContentZipped?version={versionSpec}&path={escapedPathToFolder}

So, if you have a project named "MyProject" in the DefaultCollection, and want to get the content of a folder called "MyFeature":

http://MyTfsServer:8080/tfs/DefaultCollection/MyProject/_api/_versioncontrol/itemContentZipped?version=C1001&path=%24%2FMyProject%2FMyFeature

I think "version" can be any version spec, which is documented in the TFS API documentation. My example is requesting the version as of change set 1001. I was using the .NET API to get a specific version, which is pretty straightforward, but slow because it can only get one file at a time. I'm trying to figure out if this same functionality is exposed through the .NET API because downloading the files this way is much much faster than getting a single file at a time.

I implemented this as an extension method on Microsoft.TeamFoundation.VersionControl.Client.Item. This returns a stream that contains a zip file. I had used this as part of a custom MSBuild task which then saves the contents of this stream to a file location.

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();
    }
}

I think you should create a temporary Workspace to retrieve the content you want, then delete the Workspace and keep the local items.

A Workspace in TFS is a local view of what's on the server, for a given Workspace you choose which folder(s) you want to retrieve locally and where you'll store the folders/files.

It's not like SourceSafe you're not bound to only one workspace, you can have as many as you want on a given computer.

So I suggest you to create a dedicated Workspace for the operation you want to do and get rid of it when you judge it appropriate.

Use the TF.exe workspace command to create/delete a Workspace from the Shell. Then TF.exe get to retrieve the files.

You can use tf view to get a specific file without creating a workspace.

Retrieves a specific version of a file to a temporary folder on your computer and displays it.

tf vc view [/collection:TeamProjectCollectionUrl]
       [/console] [/recursive] [/output:localfile]
       [/shelveset:shelvesetname[;owner]] [/noprompt] itemspec
       [/version:versionspec] [/login:username,[password]]

Versionspec:
Date/Time         D"any .Net Framework-supported format"
                  or any of the date formats of the local machine
Changeset number  Cnnnnnn
Label             Llabelname
Latest version    T
Workspace         Wworkspacename;workspaceowner
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!