Как получить конкретную версию папки из tfs без создания рабочей области?

Я хотел бы получить исходный код проекта в определенное время (changeet). Так что мне нужно скачать целую папку. Я хотел бы сделать это в разное время, и обработка другого рабочего пространства не очень удобна.

Я знаю о TFS Получить конкретную версию в отдельной папке (с рабочим пространством) и Требуется команда для получения файла из TFS без рабочего пространства (один файл).

Есть ли какое-то решение для цельной папки без создания нового рабочего пространства?

Edit Я нашел принятый ответ слишком амбициозным. Мне нужно было что-то более простое.

Предположения:

  • Я могу получить доступ к TFS из Visual Studio на моем компьютере.
  • Я хочу получить набор изменений ChangeSetNumber из папки DesiredFolder в проекте TFS tProj

Я запускаю следующую партию из папки назначения в командной строке Visual Studio

set workspace_name=TemporaryWorkspace%username%
set changeset= ChangeSetNumber                
tf workspace -new %workspace_name% -noprompt
tf workfold -map $/tProj . -workspace:%workspace_name%
tf get $/tProj/DesiredFolder -version:C%changeset% -recursive -noprompt
tf workfold -unmap . -workspace:%workspace_name%
tf workspace -delete %workspace_name% -noprompt

При запуске загруженного решения необходимо подтвердить удаление ассоциации управления версиями.

Ответ 1

Я использую этот синтаксис для временных рабочих областей:

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%

Ответ 2

Я обнаружил, что вы можете сделать это через HTTP-api, который предоставляет TFS. "Подпись" для URL-адреса выглядит следующим образом:

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

Итак, если у вас есть проект с именем "MyProject" в DefaultCollection и вы хотите получить содержимое папки под названием "MyFeature":

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

Я думаю, что "версия" может быть любой спецификацией версии, которая документирована в документации API TFS. В моем примере запрашивается версия с изменением 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();
    }
}

Ответ 3

Я думаю, вам нужно создать временную рабочую область для извлечения нужного содержимого, а затем удалить рабочую область и сохранить локальные элементы.

Рабочее пространство в TFS является локальным представлением о том, что на сервере, для данной рабочей области вы выбираете, какую папку вы хотите получить локально и где будете хранить папки/файлы.

Не похоже, что SourceSafe вы не привязаны только к одному рабочему пространству, вы можете иметь столько, сколько хотите на данном компьютере.

Поэтому я предлагаю вам создать выделенную Рабочую область для операции, которую вы хотите сделать, и избавиться от нее, когда вы сочтете это подходящим.

Используйте TF.exe рабочее пространство для создания/удаления рабочей области из командной оболочки. Затем TF.exe получите для извлечения файлов.

Ответ 4

Вы можете использовать tf view для получения определенного файла без создания рабочего пространства.

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