Попытка получить файлы из приложения TFS с рабочим пространством. - PullRequest
5 голосов
/ 10 февраля 2011

Итак, я пытаюсь получить файлы из рабочей области в TFS. К сожалению, каждая попытка сделать это приводит к остановке приложения. На данный момент это код:

    public void GetWorkspaceFiles(string workspaceName)
    {
        VersionControlServer sourceControl = (VersionControlServer)TfsServer.GetService(typeof(VersionControlServer));

        var items = sourceControl.GetItems(workspaceName, VersionSpec.Latest, RecursionType.Full)
                                 .Items
                                 .Where(x => x.ItemType == ItemType.File)
                                 .ToList();

        for (int x = 0; x < items.Count; x++)
            items[x].DownloadFile();

В результате каждый раз, когда я запускаю это приложение (на нескольких машинах), оно останавливается на items[x].DownloadFile(). Все файлы в TFS не заблокированы, все в порядке. Попытка использовать метод Workspace.Get() приводит к тому же самому.

Если я нажму паузу, x будет определенным значением, но я не смогу получить доступ к коллекции элементов, например, когда я получу «Невозможно оценить выражение, потому что текущий поток находится в режиме ожидания, ожидания или соединения». Когда я оцениваю стек вызовов, я получаю:

[In a sleep, wait, or join]
[External Code]
GetWorkspaceFiles(string workspaceName) Line 55

Я не знаю, что делать дальше. Всякий раз, когда я приостанавливаю приложение, x всегда имеет одно и то же значение (хотя значение, на котором оно останавливается, отличается для каждого запуска приложения).

У кого-нибудь есть идеи?


Редактировать: После добавления диагностической логики (на основе ссылки в ответе Гранта) я еще больше запутался, чем когда-либо.

Рабочая область, которую я передаю этому методу, - $/QA/Automated Test Scripts/Regression or System Test Scripts/RDE or Condo (проверено отладчиком).

Однако, когда я просматриваю журналы tfs, мне кажется, что он загружает файл кода, который я запускаю, и говорит:

02/10/2011 12:26:58 (pid 5808, tid 5968, 42180 ms) Recording OperationStatus.Getting for $/QA/Automated Test Scripts/QA Tools/Test Manager/Test Polling Server/fmMain.cs

Сразу после этой записи:

02/10/2011 12:26:58 (pid 5808, tid 5968, 42180 ms) DownloadFiles: 18 ms
02/10/2011 12:26:58 (pid 5808, tid 5968, 42181 ms) Acknowledgements: 0 ms

После этого больше нет обновлений в файле журнала, и мое приложение остановилось. Что меня смущает, так это

1) Почему это пытается извлечь код приложения из TFS, когда я указываю совершенно другое рабочее пространство TFS

2) Почему это происходит после попытки получить файл? Возможно, это потому, что fmMain.cs открыто в Visual Studio, но оно все равно должно исключать и не зависать. Я могу получить последнюю версию, пока файл открывается через Visual Studio нормально.



Edit2:

Хорошо, я читал через MSDN и заметил, что именем рабочей области может быть локальный путь к файлам. Поэтому я изменил то, что передал в качестве параметра workspaceName, в локальный каталог файлов. Я все еще получаю киоски, но в файле журнала гораздо менее понятно, почему. Я загрузил файл tf.log здесь (я, очевидно, изменил конфиденциальную информацию, такую ​​как имена серверов и проектов, но все остальное осталось нетронутым). После этой последней записи в журнал дальнейшие данные не записываются в журнал.

Ответы [ 3 ]

7 голосов
/ 11 февраля 2011

GetItems не принимает имя рабочей области, ему нужен путь к серверу для получения списка файлов.если вы пытаетесь получить копию файлов из определенной области, вам нужно сделать следующее:

  var items = sourceControl.GetItems("$/Project/Path/subpath"/et cetera", VersionSpec.Latest, RecursionType.Full)
                                 .Items
                                 .Where(x => x.ItemType == ItemType.File)
                                 .ToList();

Когда вы звоните

items[x].DownloadFile();

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

Если вы на самом деле пытаетесь получить файлы из TFS в рабочую область, этонемного по-другому.

        VersionControlServer sourceControl = coll.GetService<VersionControlServer>();

        var ws = sourceControl.QueryWorkspaces(workspaceName, null, null);

        var status = ws[0].Get();

(к этому добавлена ​​необходимость обработки ошибок)

Это обновит ваше рабочее пространство файлами с сервера.Он будет работать так же, как пользовательский интерфейс Visual Studio, в этом он будет сравнивать то, что в настоящий момент находится на диске, с тем, что находится в хранилище, и обновит локальную версию, если существует более новая версия.

Существует несколько перегрузок.к методу Get (), который вы можете использовать, чтобы указать точное поведение, которое вы ищете.

- Правка -

Когда вы вызываете Workspace.Get (), первым делом этоон выходит в TFS (используя вызов веб-службы) и получает список файлов.Затем он просматривает эти файлы, сравнивая то, что вы уже «получили» в этом рабочем пространстве, с тем, что находится в запрошенной вами ревизии (или VersionSpec.Latest, если вы не указали другую ревизию).

Этот процесс может занять некоторое время.Это все равно, что щелкнуть правой кнопкой мыши и получить последние сведения о каждом сопоставленном каталоге в вашем рабочем пространстве.

Если ваше рабочее пространство сопоставлено с $/, оно будет проходить по всем файлам в TFS.Если у вас есть несколько сопоставлений путей с локальными путями, он будет проходить через каждый из них, а также будет извлекать и сохранять локально любые файлы, которые вы еще не получили.

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

- РЕДАКТИРОВАТЬ 2 -

Если вы хотите ограничить то, что вы получаете, у вас естьпара вариантов.Первый вариант - ограничить отображение в рабочей области, к которой вы обращаетесь.Например, если ваше рабочее пространство имеет только одно сопоставление с $/Project/Branch/Source/Utilities/MyUtility, будут получены только файлы в этом сопоставлении.

В паре наших собственных служебных программ мы даже заходим так далеко:

  • Динамически создавать рабочее пространство
  • Сопоставлять пути к каталогам только с теми путями, которые нам нужны для получения
  • Выполнять получение
  • Редактировать определенные файлы (используя метод PendEdit ())
  • Проверить измененные файлы
  • И, наконец, удалить рабочее пространство

Это много работы, если выпросто пытаемся автоматизировать обновление набора файлов, поэтому вы можете передать путь к методу Get():

var status = ws[0].Get(new GetRequest("$/path/to/subfolder", RecursionType.Full, VersionSpec.Latest),
                   GetOptions.Overwrite);
2 голосов
/ 10 февраля 2011

Работает ли та же команда / параметры при использовании инструментов командной строки TFS? например TF.exe get?

У вас установлено антивирусное программное обеспечение? Возможно ли, что это мешает? Попробуйте временно отключить его.

Вы также можете включить трассировку TFS на стороне клиента в своем app.config, чтобы увидеть, что происходит по сети: http://blogs.msdn.com/b/edhintz/archive/2007/03/30/tfs-client-tracing.aspx

0 голосов
/ 29 января 2014

Ниже приведен рабочий пример, с помощью которого вы можете получить последнюю версию кода по пути к серверу

var status = workspace.Get(new GetRequest("$/XXXX/Development/Subfolder/",
            RecursionType.Full, VersionSpec.Latest),
            GetOptions.GetAll| GetOptions.Overwrite);
...