2012-05-03 2 views
11

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

Я знаю о TFS Get Specific Version into separate folder (с рабочим пространством) и Need command to get a file from TFS without a workspace (один файл).

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

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

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

  • я могу получить доступ к 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 

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

+0

Можете ли вы объяснить/разработать «делать это в разное время»? – Nock

+0

@Nockawa: Может быть, должны быть разные изменения. Мне просто нужно изучить, будет ли и почему он ведет себя иначе, чем раньше. – IvanH

+0

Можете ли вы объяснить, почему манипуляции с рабочей областью не удобны? Если у вас есть рабочее пространство, и вы хотите синхронизировать весь проект с набором изменений 150, вы можете сделать это с помощью одной команды: «tf get/version: 150». –

ответ

13

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

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% 
4

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

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

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

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

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

+0

Я дам ему шанс. Но я хотел бы иметь что-то как представление, но для папки. – IvanH

6

Я обнаружил, что вы можете сделать это через 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(); 
    } 
} 
+0

Вы связываетесь с сервером tfs с помощью WebClient или другим способом? Вы бы добавили образец кода? – IvanH

+0

@IvanH Я использую System.Net.WebRequest для получения контента. Включил пример. – MarkPflug

+0

Обратите внимание, что использование такого механизма не будет использовать преимущества прокси-серверов загрузки, если у вас есть настроенные. В противном случае это очень хороший механизм. –

1

Вы можете использовать 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 
+1

Этот подход работает только с отдельными файлами, а не с каталогами. Выполняя команду, как она есть здесь, вы получите один массивный файл (с именем C: \ path \ to \ localdirectory), который содержит каждый файл в объединенной папке. – JamesQMurphy

+0

@JamesQMurphy, спасибо! Я не могу поверить, что это так. Я решил решить эту проблему с помощью функции powershell, используя комбинацию 'dir' и' view'. Вы можете увидеть это в этом [gist] (https://gist.github.com/clintcparker/ee92d2e6faa45614e2c41afbd33884ed). – clintcparker