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

后端 未结 4 543
情书的邮戳
情书的邮戳 2020-12-29 13:03

I would like to get the source code of a project at specific time (changeset). So I need do download whole folder. I would like to do it for different times and handling a d

相关标签:
4条回答
  • 2020-12-29 13:17

    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.

    0 讨论(0)
  • 2020-12-29 13:21

    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
    
    0 讨论(0)
  • 2020-12-29 13:28

    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%
    
    0 讨论(0)
  • 2020-12-29 13:31

    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();
        }
    }
    
    0 讨论(0)
提交回复
热议问题