Estendendo controle de versão

Visual Studio Team Foundation Server 2010 representa uma alteração na arquitetura de Team Foundation Server. Antes de ler o exemplo de código em este tópico, você deve compreender a arquitetura de Team Foundation Server pelo menos um muito de alto nível, e as seguintes informações deve ajudar você a entender a finalidade de projetos de equipe e coleções de projeto de equipe em uma coleção de projeto. Essa alteração de organização permite que você execute operações de controle de versão em itens relacionados dentro do contexto de uma coleção de projeto de equipe.

A estrutura organizacional primária em Team Foundation Server 2010 é a coleção de projeto de equipe. A coleção de projeto de equipe é um agrupamento de projetos de equipe em uma estrutura organizacional que você pode usar para definir e gerenciar um grupo de projetos que compartilham recursos ou uma base de código. A vantagem de esse tipo de hierarquia de organização é que o gerenciamento de projetos de equipe se torna mais eficiente quando você agrupa os juntos e o atribui recursos. As operações como ramificação ou mesclar de código, faça backup e restaurar dados, e relatar informações sobre o projeto se tornam mais fácil porque eles são específicas para um banco de dados. Para obter mais informações sobre as coleções de projeto de equipe em Team Foundation Server 2010, consulte Organizing Your Server with Team Project Collections.

Neste tópico

Dica

Você pode estender Controle de versão do Team Foundation acessando e atualizar itens no repositório de controle de versão e em um espaço de trabalho no computador local para criar políticas de check-in para personalizados e aplicá-las a um projeto de equipe.Aproveitando herança, você substitui a funcionalidade existente com sua própria implementação de política que se aplica ao controle de versão.Para obter mais informações, consulte a seguinte página no site da Microsoft: Como: Criar políticas de check-in personalizados.

Exemplo: Acessando itens no repositório de Controle de versão

O exemplo a seguir usa o objeto de VersionControlServer para listar cada versão de cada arquivo .xaml no repositório de controle de versão.

Para usar este exemplo

  1. Crie um aplicativo de console, e adicione referências para os seguintes conjuntos de módulos (assemblies):

  2. Substitua o conteúdo de Module.vb (ou Module1.vb) com esse exemplo.

using System; 
using System.Text; 
using Microsoft.TeamFoundation.Client; 
using Microsoft.TeamFoundation.Framework; 
using Microsoft.TeamFoundation.VersionControl.Client; 

namespace VCSample
{
    class Program
    {
        static void Main(string[] args) 
        {
            // Connect to the team project collection and the server that hosts the version-control repository. 
            TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(
               new Uri("https://Server:8080/tfs/DefaultCollection"));
            VersionControlServer vcServer = tpc.GetService<VersionControlServer>(); 

            // List all of the .xaml files.
            ItemSet items = vcServer.GetItems("$/*.xaml", RecursionType.Full); 
            foreach(Item item in items.Items) 
            {
                Console.Write(item.ItemType.ToString());
                Console.Write(": ");
                Console.WriteLine(item.ServerItem.ToString());
            }
        }
    }
}
Imports System
Imports System.Text
Imports Microsoft.TeamFoundation.Client
Imports Microsoft.TeamFoundation.VersionControl.Client

Module Module1

    Sub Main()
        ' Connect to the team project collection and the server that hosts the version-control repository.
        Dim tfsUri As Uri
        tfsUri = New Uri("https://Server:8080/tfs/DefaultCollection")

        Dim tpc As New TfsTeamProjectCollection(tfsUri)

        Dim vcServer As VersionControlServer
        vcServer = tpc.GetService(Of VersionControlServer)()

        ' List all of the .xaml files.
        Dim items As ItemSet
        items = vcServer.GetItems("$/*.xaml", RecursionType.Full)
        Dim item As Item
        For Each item In items.Items
            System.Console.Write(item.ItemType.ToString())
            System.Console.Write(": ")
            System.Console.WriteLine(item.ServerItem.ToString())
        Next
    End Sub

End Module

Exemplo: Itens de atualização em um espaço de trabalho

Você pode trabalhar com arquivos em um espaço de trabalho executando operações como obtém, check-out, e fazer o check-in programaticamente. O exemplo a seguir obtém a versão mais recente dos arquivos em um espaço de trabalho.

Para usar este exemplo

  1. Em o exemplo anterior, localize a seção de código que lista os arquivos .xaml, e substitui-lo com o código a seguir.

  2. WorkspaceName substitua pelo nome do espaço de trabalho, que é normalmente o mesmo que o nome do computador que contém o espaço de trabalho.

  3. Substitua Nome do Usuário com o nome totalmente qualificado do usuário que possui o espaço de trabalho.

Para obter mais informações, consulte Workstation.GetLocalWorkspaceInfo e Criar e trabalhar com espaços de trabalho.

// Get the workspace that is mapped to c:\BuildProcessTemplate
WorkspaceInfo wsInfo = Workstation.Current.GetLocalWorkspaceInfo(
   vcServer, @"WorkspaceName", @"UserName");
Workspace ws = vcServer.GetWorkspace(wsInfo); 

// Update the workspace with most recent version of the files from the repository.
GetStatus status = ws.Get();
Console.Write("Conflicts: ");
Console.WriteLine(status.NumConflicts);
' Get the workspace that is mapped to c:\BuildProcessTemplate
Dim wsInfo As WorkspaceInfo
wsInfo = Workstation.Current.GetLocalWorkspaceInfo(vcServer, "WorkspaceName", "UserName")
Dim ws As Workspace
ws = vcServer.GetWorkspace(wsInfo)

' Update the workspace with the most recent version of the files from the repository.
Dim status As GetStatus
status = ws.Get
Console.Write("Conflicts: ")
Console.WriteLine(status.NumConflicts)

Você também pode obter um espaço de trabalho que é mapeado para uma pasta no computador local passando o caminho completo da pasta a Workstation.GetLocalWorkspaceInfo.

WorkspaceInfo wsInfo = Workstation.Current.GetLocalWorkspaceInfo(@"c:\MyWorkspace");
Dim wsInfo As WorkspaceInfo
wsInfo = Workstation.Current.GetLocalWorkspaceInfo("c:\MyWorkspace")

Exemplo: Adicionando itens ao repositório de Controle de versão

Você pode criar um arquivo e colocá-lo em controle de versão usando adicionar e registe métodos.

Aviso

O código lança uma exceção se você não tiver permissões no espaço de trabalho ler e fazer o check-in de arquivos.Essas permissões são as permissões de controle de origem para Ler e check-in em Gerenciador do Controle do Código-Fonte.

Em esse exemplo, você irá chamar os métodos a seguir:

  • Primeiro, você identifica coleções de projeto em Team Foundation Server chamando [M:Microsoft.TeamFoundation.Client.RegisteredTfsConnections.GetProjectCollection()] ou [M:Microsoft.TeamFoundation.Client.RegisteredTfsConnections.GetProjectCollections()].

  • Depois que você identifica as coleções de projeto, você então identifica cada coleção de projeto de equipe chamando [M:Microsoft.TeamFoundation.Client.TfsConfigurationServer.GetTeamProjectCollection()].

  • Dentro da coleção de projeto de equipe, você identifica projetos individuais de equipe chamando [M:Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer.GetAllTeamProjects()].

  • Para cada projeto de equipe, você obtém o espaço de trabalho associado chamando [M:Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer.GetWorkspace()] ou [M:Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer.CreateWorkspace()], e então você mapeia o espaço de trabalho a unidade local chamando [M:Microsoft.TeamFoundation.VersionControl.Client.Workspace.CreateMapping()].

  • Para copiar os arquivos em uma unidade local, você chama [M:Microsoft.TeamFoundation.VersionControl.Client.Workspace.Get()] para o espaço de trabalho.

Você pode adicionar um arquivo ao controle de versão se você tem as permissões apropriadas.

Para usar este exemplo

  1. Crie um aplicativo de console C#, e então adicione referências para os seguintes conjuntos de módulos (assemblies):

  2. Substitua o conteúdo de Module.vb com o código de exemplo.

  3. Altere o valor de Uris o nome do servidor de camada de aplicativo no seu ambiente.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

namespace VControl
{
    class Program
    {
        static void Main(string[] args)
        {
            List<RegisteredProjectCollection> projectCollections;

            if (args.Count() == 0)
            {
                // Try the default URI as the name of a registered project collection.
                projectCollections = new List<RegisteredProjectCollection> { RegisteredTfsConnections.GetProjectCollection(new Uri("https://Server:8080/tfs/DefaultCollection")) };   
            }
            else
            {
                // Get all registered project collections
                projectCollections = new List<RegisteredProjectCollection>(RegisteredTfsConnections.GetProjectCollections());
            }
            
            foreach (var registeredProjectCollection in projectCollections)
            {
                TfsTeamProjectCollection projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(registeredProjectCollection);
                
                Workspace workspace = null;
                Boolean createdWorkspace = false;
                String newFolder = String.Empty;
                try
                {
                    VersionControlServer versionControl = projectCollection.GetService<VersionControlServer>();
                    
                    var teamProjects = new List<TeamProject>(versionControl.GetAllTeamProjects(false));
                    
                    if (teamProjects.Count < 1)
                        continue;
                    String workspaceName = String.Format("{0}-{1}", Environment.MachineName, "Test");
                    try
                    {
                        workspace = versionControl.GetWorkspace(workspaceName, versionControl.AuthorizedUser);
                    }
                    catch (WorkspaceNotFoundException)
                    {
                        workspace = versionControl.CreateWorkspace(workspaceName, versionControl.AuthorizedUser);
                        createdWorkspace = true;
                    }
                    var serverFolder = String.Format("$/{0}", teamProjects[0].Name);
                    var localFolder = Path.Combine(Path.GetTempPath(), "Test");
                    var workingFolder = new WorkingFolder(serverFolder, localFolder);

                    // Create a workspace mapping.
                    workspace.CreateMapping(workingFolder);

                    if (!workspace.HasReadPermission)
                    {
                        throw new SecurityException(
                            String.Format("{0} does not have read permission for {1}", versionControl.AuthorizedUser, serverFolder));
                    }
                    
                    // Get the files from the repository.
                    workspace.Get();

                    // Create a file
                    newFolder = Path.Combine(workspace.Folders[0].LocalItem, "For Test Purposes");
                    Directory.CreateDirectory(newFolder);
                    String newFilename = Path.Combine(newFolder, "Safe To Delete.txt");

                    // Determine whether the user has check-in permissions.
                    if (!workspace.HasCheckInPermission)
                    {
                        throw new SecurityException(
                            String.Format("{0} does not have check-in permission for workspace {1}", workspace.VersionControlServer.AuthorizedUser,
                            workspace.DisplayName));
                    }

                    try
                    {
                        // Create the file.
                        using (var streamWriter = new StreamWriter(newFilename))
                        {
                            streamWriter.WriteLine("Revision 1");
                        }

                        workspace.PendAdd(Path.GetDirectoryName(newFilename), true);

                        //  Create a list of pending changes.
                        var pendingAdds = new List<PendingChange>(workspace.GetPendingChanges());
                        
                        //  Enumerate the pending changes
                        pendingAdds.ForEach(add => Console.WriteLine("\t{0}: {1}", add.LocalItem,
                            PendingChange.GetLocalizedStringForChangeType(add.ChangeType)));
                        
                        // Check in the items that you added.
                        int changesetForAdd = workspace.CheckIn(pendingAdds.ToArray(), "Initial revision");
                        Console.WriteLine("Checked in changeset {0}", changesetForAdd);
                    }
                    catch (IOException ex)
                    {
                        Console.Error.WriteLine("Error writing {1}: {0}", ex.Message, newFilename);
                        throw;
                    }
                    catch (VersionControlException ex)
                    {
                        Console.Error.WriteLine("Error adding file: {0}", ex.Message);
                        throw;
                    }
                }
                finally 
                {
                    if ((workspace != null) && createdWorkspace)
                    {
                        workspace.Delete();
                    }
                    if (!String.IsNullOrEmpty(newFolder) && Directory.Exists(newFolder))
                    {
                        Directory.Delete(newFolder);
                    }
                }
                break;
            }
            
        }
    }
}

Exemplo: Editando itens

Você pode alterar um arquivo existente sob controle de versão usando o código a seguir, que chama os métodos de PendEdit e de CheckIn . Este exemplo mostra como usar o modelo de objeto para editar e fazer o check-in de um arquivo existente. Você irá alterar o exemplo de código para criar um arquivo e substituirá em algumas linhas de código em esse exemplo com o código em este exemplo. Além de isso, este exemplo apresenta as especificações de item, que você usa para adicionar uma propriedade personalizada para um arquivo.

Para usar este exemplo

  • Abra o aplicativo de console C# que você criou no exemplo de Add a File to Version Control , e substitua o bloco interno tentativa com o seguinte código:
try
{
    // Check out and modify a file.
    workspace.PendEdit(newFilename);

    using (var streamWriter = new StreamWriter(newFilename))
    {
        streamWriter.WriteLine("Revision 2");
    }

    // Get the pending change, and check in the new revision.
    var pendingChanges = workspace.GetPendingChanges();
    int changesetForChange = workspace.CheckIn(pendingChanges, "Modified file contents");
    Console.WriteLine("Checked in changeset {0}", changesetForChange);
}

Você pode adicionar uma propriedade ao arquivo que você criou em este exemplo. Chamando o método de SetVersionedItemProperty , você pode definir uma propriedade de sua escolha no arquivo. Em o exemplo, você usará o parâmetro de itemSpec para especificar um caminho para os arquivos e pastas. Em esse caso, você especificará o caminho local, embora você também pode usar este parâmetro para especificar um caminho no armazenamento. Você também irá definir uma propriedade e um valor para ele.

Aviso

Você deve ser cuidadoso quando você usa um caminho local para uma especificação de item.Uma exceção será lançada se você especificar um mapeamento que também não existe no armazenamento.

//Add a custom property to this file.
versionControl.SetVersionedItemProperty( new ItemSpec(“$/proj/Safe To Delete.txt”),VersionSpec.Latest,
    DeletedState.Any, ItemType.File,”MyProperty”, 24);

Exemplo: Criar ramificações

Você pode ramificar um arquivo existente sob controle de versão usando o código a seguir, que chama os métodos de PendBranch e de CheckIn . Este exemplo cria no exemplo de Add a File to Version Control e demonstra como usar o modelo de objeto para criar uma ramificação e fazer o check-in de um arquivo existente. Você pode alterar o exemplo de código para criar um arquivo e substituir algumas linhas de código em esse exemplo com o código em este exemplo. Depois que você aplicar essas alterações, você pode criar uma ramificação de um arquivo em controle de versão.

Para usar este exemplo

  • Abra o aplicativo de console C# que você criou no tópico de Add a File to Version Control , e substitua o bloco interno tentativa com o seguinte código:
String branchedFilename = Path.Combine(Path.GetDirectoryName(newFilename),
    Path.GetFileNameWithoutExtension(newFilename)) + "-branch" + Path.GetExtension(newFilename);

workspace.PendBranch(newFilename, branchedFilename, VersionSpec.Latest, LockLevel.Checkin, true);

var pendingChanges = workspace.GetPendingChanges();
int changesetForBranch = workspace.CheckIn(pendingChanges, "Branched file");
Console.WriteLine("Branched {0} to {1} in changeset {2}", newFilename, branchedFilename, changesetForBranch);

Você pode adicionar uma especificação de versão quando você cria uma ramificação em vez de apenas usar a versão mais recente de um arquivo. Por exemplo, você pode especificar uma identificação do conjunto de alterações e um nome de usuário quando você chama PendBranch. Porque as várias classes são derivadas de VersionSpec, você pode usar uma especificação de versão como um parâmetro para obter todos os arquivos que correspondam uma identificação do conjunto de alterações ou que têm uma data específica ou um rótulo. Para obter mais informações, consulte ChangeSetVersionSpec, DateVersionSpec, ou LabelVersionSpec.

Em o exemplo a seguir, você especifica uma identificação do conjunto de alterações para associar o arquivo ramificado. Após confirmar as alterações, a identificação do conjunto de alterações de arquivo será transformada o valor que você especificou.

VersionSpec versionSpec = VersionSpec.ParseSingleSpec(changesetId, username);
String branchedFilename = Path.Combine(Path.GetDirectoryName(newFilename),
    Path.GetFileNameWithoutExtension(newFilename)) + "-branch" + Path.GetExtension(newFilename);
// Use the version spec in the method call.
workspace.PendBranch(newFilename, branchedFilename, versionSpec, LockLevel.Checkin, true);

Exemplo: excluindo pastas

Você pode excluir uma pasta de controle de versão usando o código a seguir, que chama os métodos de PendDelete e de CheckIn . Este exemplo cria no exemplo de Add a File to Version Control e demonstra como usar o modelo de objeto para excluir uma pasta para e então fazer o check-in da alteração. Você pode alterar o exemplo de código para criar um arquivo e substituir algumas linhas de código em esse exemplo com o exemplo a seguir. Depois que você aplicar essas alterações, você pode então excluir uma pasta de controle de versão.

Para usar este exemplo

  • Abra o aplicativo de console C# que você criou no tópico de Add a File to Version Control , e substitua o bloco interno tentativa no exemplo original com o seguinte código:
try
{
    // Delete the items
    workspace.PendDelete(workspace.GetServerItemForLocalItem(newFolder), RecursionType.Full);
    var pendingDeletes = workspace.GetPendingChanges();

    if (pendingDeletes.Length > 0)
    {
        workspace.CheckIn(pendingDeletes, "Clean up!");
    }
}
catch (VersionControlException ex)
{
    Console.Error.WriteLine("Error deleting file: {0}", ex.Message);
    throw;
}

Consulte também

Conceitos

Estendendo o Team Foundation

Outros recursos

Usar controle de versão