扩展版本控制

Visual Studio Team Foundation Server 2010 表示在 Team Foundation Server上体系结构的更改。 在阅读本主题中的代码示例,应了解 Team Foundation Server 体系结构至少在一个非常高级别,因此,以下信息可帮助您了解团队项目和团队项目集合的目的在项目集合中。 此组织更改允许您在团队项目集合的上下文中对相关项目的版本控制操作。

在 Team Foundation Server 2010 的主要组织结构是团队项目集合。 团队项目集合是组团队项目添加到中定义和管理项目的一组共享资源或基本代码的组织结构。 这种组织层次结构的优点是团队项目的管理变得更加高效,在组在一起并将资源分配它们。 ,因为它们是特定于数据库操作,如分支或合并代码,备份和还原数据和报告项目信息变得更加容易。 有关团队在 Team Foundation Server 2010的项目集合的更多信息,请参见 Organizing Your Server with Team Project Collections

主题内容

备注

您可以通过访问和更新项目进行版本管理储存库和在本地计算机上的非工作区创建自定义签入策略和应用它们的扩展 Team Foundation 版本控制 于团队项目。利用继承,用自己策略的实现替换现有功能,则适用于版本控制。有关更多信息,请参见Microsoft网站上的以下页面: 如何:创建自定义签入策略.

示例:在版本控制储存库访问项目

下面的示例使用 VersionControlServer 对象列表每.xaml文件的每个版本在版本控制储存库的。

使用此示例

  1. 创建一个控制台应用程序,并添加对以下程序集的引用:

  2. 用此示例替换Program.cs (或Module1.vb)内容。

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("http://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("http://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

示例:更新项目在工作区

可以处理文件在工作区中执行操作旁边如GET,检查并注册程序模型。 下面的示例在工作区获取文件的最新版本。

使用此示例

  1. 在前面的示例中,找到列表.xaml文件的代码部分,然后用以下代码替换它。

  2. 使用工作区的名称替换 WorkspaceName ,通常会与计算机的名称包含工作区。

  3. 用是工作区的所有者用户的完全限定名称替换 用户名 。

有关更多信息,请参见Workstation.GetLocalWorkspaceInfo创建和使用工作区

// 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)

您还可以获取映射到本地计算机上的文件夹通过该文件夹的完整路径来 Workstation.GetLocalWorkspaceInfo的工作区。

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

示例:将项目添加到版本控制储存库

可以创建文件,并将其放置在版本控制下使用添加和注册方法。

警告

,如果未在工作区有权写入和签出文件,代码将引发异常。这些权限是源代码管理权限 读取 以及 签入 在 源代码管理资源管理器的。

在该示例中,您将调用下列方法:

  • 首先,通过调用 [M:Microsoft.TeamFoundation.Client.RegisteredTfsConnections.GetProjectCollection()] 或 [M:Microsoft.TeamFoundation.Client.RegisteredTfsConnections.GetProjectCollections()]来找出 Team Foundation Server 的项目集合。

  • 在确认项目集合后,可以通过调用 [M:Microsoft.TeamFoundation.Client.TfsConfigurationServer.GetTeamProjectCollection()]然后标识每个团队项目集合。

  • 在团队项目集合中,通过调用 [M:Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer.GetAllTeamProjects()]标识单个团队项目。

  • 对于每个团队项目,您将得到关联的工作区通过调用 [M:Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer.GetWorkspace()] 或 [M:Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer.CreateWorkspace()],然后工作区映射到本地驱动器通过调用 [M:Microsoft.TeamFoundation.VersionControl.Client.Workspace.CreateMapping()]。

  • 若要将文件复制到本地驱动器的,则调用工作区的 [M:Microsoft.TeamFoundation.VersionControl.Client.Workspace.Get()] 。

,如果您具有适当的权限,然后可以将文件添加到版本控制。

使用此示例

  1. 创建一个C#控制台应用程序,然后添加对以下程序集的引用:

  2. 在示例代码替换Program.cs的内容。

  3. 更改 URI 的值到应用层服务器的名称在环境中。

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("http://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;
            }
            
        }
    }
}

示例:编辑项目

使用以下代码,可以修改现有文件在版本控制下,调用 PendEdit 和 CheckIn 方法。 此示例演示如何使用对象模型编辑器并注册现有文件。 您将修改创建的文件代码示例在此示例中的代码替换代码某些行在该示例中的。 此外,本示例介绍项规范,可以使用来添加自定义属性添加到文件。

使用此示例

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);
}

可以将特性添加到您在此示例中创建的文件。 通过调用 SetVersionedItemProperty 方法,可以将特性设置为您在中选择文件。 在此示例中,您将使用 itemSpec 参数指定文件的路径和文件夹。 在这种情况下,将指定本地路径,不过,在储存库中使用此参数指定路径。 您还将定义一个属性和一个值它。

警告

,也可以对项规范时,使用本地路径必须小心。将会引发异常,如果指定也不存在储存库的映射。

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

示例:创建分支

使用以下代码,您可以对现有文件在版本控制下,调用 PendBranch 和 CheckIn 方法。 在 Add a File to Version Control 的此示例生成示例并演示如何使用对象模型创建和注册现有文件的分支。 可以修改创建的文件代码示例和在此示例中的代码替换代码某些行该示例。 在应用这些更改之后,可以在版本控制随后可以创建文件的分支。

使用此示例

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);

使用文件时,,的最新版本,当您创建分支而不是可以添加版本规范。 例如,那么,当您调用 PendBranch时,可以指定变更集ID和用户名。 因为多个选件VersionSpec类从派生,可以使用版本规范作为参数来捕获与变更集ID或具有特定日期或标记的所有文件。 有关更多信息,请参见ChangeSetVersionSpecDateVersionSpecLabelVersionSpec

在下面的示例中,将指定变更集ID与分支文件。 在提交更改后,分支文件的变更集ID与您指定的值。

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);

示例:删除文件夹

使用以下代码,可以从版本控制删除文件夹,调用 PendDelete 和 CheckIn 方法。 在 Add a File to Version Control 的此示例生成示例并演示如何使用对象模型删除文件夹中注册该更改。 可以修改创建的文件代码示例和用下面的代码替换某些行该示例。 在应用这些更改之后,可以从版本控制然后删除文件夹。

使用此示例

  • 打开在 Add a File to Version Control 主题中创建的C#控制台应用程序,然后替换内部 尝试 在包含以下代码的原始示例中块:
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;
}

请参见

概念

扩展 Team Foundation

其他资源

使用版本控制