Как я могу программно извлечь элемент для редактирования в TFS?

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

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

Какие существуют способы извлечь файл?

P.S. Мне нужно что-то для программирования, а не Process.Start("tf.exe", "...");, если это применимо.


person abatishchev    schedule 23.02.2011    source источник


Ответы (5)


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

Этот подход работает в 2005, 2008 и 2010 годах. Я больше не использую TFS, поэтому я не тестировал 2013 год.

var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(fileName);
using (var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri))
{
    var workspace = workspaceInfo.GetWorkspace(server);    
    workspace.PendEdit(fileName);
}
person Ben    schedule 23.02.2012
comment
Я удалил свой ответ, потому что у вас упрощенная версия, которая также работает с VS 2010. Оказывается, вам не нужно проходить TfsConfigurationServer, чтобы получить нужные вам предметы. blogs.msdn.com/b/taylaf/archive/2010/02/23/ - person RandomEngy; 12.06.2012
comment
TfsTeamProjectCollection является IDisposable, поэтому вы можете заключить его в блок using - person Carl Walsh; 18.04.2015
comment
Ты прав. Код, из которого я скопировал это, сохранил TfsTeamProjectCollection для многократного использования. Но это улучшает пример. - person Ben; 05.05.2015
comment
Хотел добавить комментарий для будущих посетителей. Если вы используете более подробную функцию PendEdit(), которая принимает параметр silent, вы хотите установить silent на false, это приведет к снятию блокировки только для чтения. - person njkremer; 17.10.2016

private const string tfsServer = @"http://tfsserver.org:8080/tfs";

public void CheckOutFromTFS(string fileName)
{
    using (TfsTeamProjectCollection pc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(tfsServer)))        
    {
        if (pc != null)
        {
            WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(fileName);
            if (null != workspaceInfo)
            {                   
                Workspace workspace = workspaceInfo.GetWorkspace(pc);
                workspace.PendEdit(fileName);
            }
        }
    }
    FileInfo fi = new FileInfo(fileName);
}

Обратите внимание, что Microsoft.TeamFoundation.Client.TeamFoundationServerFactory устарел: класс TeamFoundationServer устарел. Используйте классы TeamFoundationProjectCollection или TfsConfigurationServer, чтобы общаться с Team Foundation Server 2010. Для связи с Team Foundation Server 2005 или 2008 используйте класс TeamFoundationProjectCollection. Соответствующий заводской класс для этого - TfsTeamProjectCollectionFactory.

person wp9omp    schedule 26.11.2012

Вы можете использовать клиентский API управления версиями Team Foundation. Метод PendEdit ()

workspace.PendEdit(fileName);

Подробный пример оформления заказа на MSDN http://blogs.msdn.com/b/buckh/archive/2006/03/15/552288.aspx

person ukhardy    schedule 23.02.2011

Сначала получите рабочее пространство

var tfs = new TeamFoundationServer("http://server:8080/tfs/collection");
var version = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
var workspace = version.GetWorkspace("WORKSPACE-NAME", version.AuthorizedUser);

С помощью рабочей области вы можете оформить файл

workspace.PendEdit(fileName);
person BrunoLM    schedule 27.06.2011

У меня есть два подхода к этому: простой и продвинутый.

1). Простой:

  #region Check Out
    public bool CheckOut(string path)
    {
        using (TfsTeamProjectCollection pc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(ConstTfsServerUri)))
        {
            if (pc == null) return false;

            WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(path);
            Workspace workspace = workspaceInfo?.GetWorkspace(pc);
            return workspace?.PendEdit(path, RecursionType.Full) == 1;
        }
    }

    public async Task<bool> CheckoutAsync(string path)
    {
        return await Task.Run(() => CheckOut(path));
    }
    #endregion

2). Расширенный (со статусом получения):

    private static string GetOwnerDisplayName(PendingSet[] pending)
    {
        var result = pending.FirstOrDefault(pendingSet => pendingSet.Computer != Environment.MachineName) ?? pending[0];
        return result.OwnerDisplayName;
    }
    private string CheckoutFileInternal(string[] wsFiles, string folder = null)
    {
        try
        {

            var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(folder);
            var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri);
            var workspace = workspaceInfo.GetWorkspace(server);
            var request = new GetRequest(folder, RecursionType.Full, VersionSpec.Latest);
            GetStatus status = workspace.Get(request, GetOptions.None);
            int result = workspace.PendEdit(wsFiles, RecursionType.Full, null, LockLevel.None);
            if (result == wsFiles.Length)
            {
                //TODO: write info (succeed) to log here - messageText
                return null;
            }
            var pending = server.GetService<VersionControlServer>().QueryPendingSets(wsFiles, RecursionType.None, null, null);
            var messageText = "Failed to checkout !.";
            if (pending.Any())
            {
                messageText = string.Format("{0}\nFile is locked by {1}", messageText, GetOwnerDisplayName(pending));
            }

            //TODO: write error to log here - messageText
            return messageText;
        }
        catch (Exception ex)
        {
            UIHelper.Instance.RunOnUiThread(() =>
            {
                MessageBox.Show(Application.Current.MainWindow, string.Format("Failed checking out TFS files : {0}", ex.Message), "Check-out from TFS",
                               MessageBoxButton.OK, MessageBoxImage.Error);
            });
            return null;
        }
    }

    public async Task<string> CheckoutFileInternalAsync(string[] wsFiles, string folder)
    {
        return await Task.Run(() => CheckoutFileInternal(wsFiles, folder));
    }
person Mr.B    schedule 04.07.2016
comment
Вы можете добавить суффикс внутренней функции internal и удалить этот суффикс из общедоступной. - person abatishchev; 04.07.2016
comment
Также асинхронный запуск функции синхронизации не имеет для меня особого смысла. В любом случае вы, вероятно, можете вернуть задачу напрямую, а не ждать ее, чтобы ее ждал вызывающий - person abatishchev; 04.07.2016