本文章是由機器翻譯。

ALM Ranger

TFS 用戶端物件模型中的版本控制

Jeff Bramwell

下載代碼示例

這篇文章是"使用團隊基礎伺服器用戶端物件模型,"寫的成員的 Visual Studio ALM 別動隊在 2012 年 8 月一期的後續行動 (msdn.microsoft.com/magazine/jj553516)。 到目前為止,我們已經介紹了團隊的基礎伺服器 (TFS) 用戶端物件模型,和現在我要介紹的版本控制 Api。

重述一遍,ALM 別動隊是一組由處理缺少的功能,促進的 Visual Studio 產品組、 Microsoft 服務和微軟最有價值專家 (MVP) 社會之間的協作,刪除通過受體阻滯劑和發佈最佳做法和指南基於現實世界的經驗的專家。

如果有人問你要解釋什麼是 TFS,很可能你會提到第一幾句內的版本控制。 雖然版本控制不會發揮重要的作用,TFS 內,您可以看到在圖 1 是有更多到 TFS。 與在 TFS 中的許多功能,如訪問通過 TFS 物件模型的版本控制子系統。 此協助工具為您提供了一個擴充性模型,您可以利用您自己的自訂工具和進程內。

Team Foundation Server Features
圖 1 團隊的基礎伺服器功能

程式集和命名空間

您可以訪問 TFS 物件模型中提供的功能之前,您必須首先瞭解所需的程式集和命名空間。 您也許還記得第一條使用 Microsoft.TeamFoundation.Client 的命名空間。 此命名空間包含的類和方法的必要連接到 TFS 佈建服務器和它的位於內具有相同名稱的程式集。 此命名空間是所有 TFS 物件模型有關發展的核心。

使用版本控制時,我們還必須利用 Microsoft.TeamFoundation.VersionControl.Client 的命名空間。 此命名空間包含用於與 TFS 版本控制系統進行交互所需的類。 利用此命名空間中的 Api 允許您訪問的檔和資料夾,暫止的變更、 合併、 分支,等等。 此命名空間內的 VersionControlServer 類是主要的類,它提供對 TFS 版本控制儲存庫的訪問。

一個簡單的例子開始

VersionControlServer 類公開許多屬性、 方法和事件與內 TFS 版本控制進行交互。 我先用一個簡單的例子:檢索最新的變更集 id。

與大多數的 TFS 物件模型所公開的 Api 進行交互所需的三個基本步驟如下:

  1. 連接到 TFS 佈建服務器。
  2. 獲取對您計畫利用的 TFS 服務的引用。
  3. 使使用的各種屬性、 方法和事件提供的服務。

採取略有不同的做法,而不是在 8 月文章中,介紹的示例連接到 TFS,我要連接到 TFS 使用 TeamProjectPicker 類。 TeamProjectPicker 類顯示一個用於連接到 TFS 伺服器的標準對話方塊。 此類不是只為功能完整的應用程式很有用,但也是非常方便簡單實用程式的位置,您可能需要在 TFS 的多個實例之間切換。

創建 TeamProjectPicker 的一個新實例,並顯示它使用 ShowDialog 方法:

private TfsTeamProjectCollection _tpc;
using (var picker = new 
  TeamProjectPicker(TeamProjectPickerMode.NoProject, false))
{
  if (picker.ShowDialog()== DialogResult.OK)
  {
    _tpc = picker.SelectedTeamProjectCollection;
  }
}

此代碼將顯示一個對話方塊,如中所示類似圖 2

The TeamProjectPicker Dialog
圖 2 TeamProjectPicker 對話方塊

按一下連接將返回實例的 TfsTeamProject­表示所選的團隊專案集合 (TPC) 的集合。 如果您更喜歡使用更程式化的方法 (即,沒有使用者交互) 連接到 TFS,請返回 8 月文章以供進一步的例子。

一旦你得到對 TfsTeamProjectCollection 的引用,它可以用於獲取 VersionControlServer 服務的實例:

var vcs = _tpc.GetService<VersionControlServer>();

一旦您擁有對該服務,您可以引用服務公開的方法的使用:

var latestId = vcs.GetLatestChangesetId();

這是一個簡單的例子,但它不會表現出與在 TFS 中的版本控制系統進行交互的基本步驟。 然而,幾個應用程式都這麼簡單。

"獲取最新"

與版本控制有關的常見方案從庫中獲取的最新的原始程式碼 — — 就"獲取最新"Visual Studio 內工作時,您通常通過按右鍵檔或資料夾內源控制資源管理器 (SCE) 選擇獲取最新版本獲取最新的原始程式碼。 為此要正常工作,您還必須選擇映射的工作區。 當從伺服器下載最新的原始程式碼,選定工作區確定存儲位置。

請按照這些步驟以程式設計方式獲取最新的原始程式碼:

  1. 連接到 TFS 佈建服務器。
  2. 獲取對版本控制服務的引用。
  3. 利用現有的工作區,或創建一個新的臨時工作區。
  4. 將工作區映射到本地資料夾。
  5. 從工作區中下載所需的檔。

基於前面的示例中,添加所示的代碼圖 3

圖 3 獲取最新的版本控制

// Create a temporary workspace
var workspace = vcs.CreateWorkspace(Guid.NewGuid().ToString(),
  _tpc.AuthorizedIdentity.UniqueName,
  "Temporary workspace for file retrieval");
// For this workspace, map a server folder to a local folder
workspace.Map("$/Demo/TFS_VC_API", @"C:\Dev\Test");
// Create an ItemSpec to determine which files and folders are retrieved
// Retrieve everything under the server folder
var fileRequest = new GetRequest(
  new ItemSpec("$/Demo/TFS_VC_API", RecursionType.Full),
  VersionSpec.Latest);
// Get latest
var results = workspace.Get(fileRequest, 
  GetOptions.GetAll | GetOptions.Overwrite);

如果工作區中已存在,並且您想要使用它,替換行中的 1-4 圖 3 以下列:

// Get a reference to an existing workspace,
// in this case, "DEMO_Workspace"
var workspace = vcs.GetWorkspace("DEMO_Workspace",
  _tpc.AuthorizedIdentity.UniqueName);

請注意如果您不知道工作區的名稱,或不想指定它,您可以調用 GetWorkspace (見前面的代碼示例),在只有一個本地路徑中傳遞。 這將返回工作區映射到的本地路徑。

您不需要映射工作區以程式設計的方式,所以您也可以刪除行 5 和 6。

確定下載的檔和資料夾

正如您所料想的幾個 TFS 所提供的 Api 允許您查詢版本控制伺服器的特定專案,以及特定版本的專案。 在前面的示例中,當創建新實例的 GetRequest,我不得不提供規範的一個實例。 項規範,短的項規範,描述了一組檔或資料夾。 這些專案可以存在於您的本地電腦或在版本控制伺服器中。 在此特定示例中,我參與制造規範以返回"$ / 演示/TFS_VC_API"在伺服器資料夾內的所有檔。

這裡使用的項規範建構函式中的第二個參數指定 RecursionType,可以完全是無或 OneLevel。 此值確定多少個層次深 API 應該考慮查詢項時。 指定 OneLevel RecursionType 將查詢或從僅為最高級別 (相對於項規範) 返回的專案。 完全的值將查詢或返回的專案從最頂端的水準,以及 (再次,相對於項規範) 下面的所有級別。

而項規範確定哪些專案要考慮基於名稱和位置查詢版本控制系統時,版本規範,短的版本規範,提供了限制基於版本的項集的能力。 版本­Spec 是一個抽象類別,所以不能直接具現化。 TFS 提供了幾個版本的實現­查詢版本控制系統時,可以使的規範使用。 圖 4 列出了各種實現的 TFS 2012 提供開箱即用的版本規範。

圖 4 版本規範類型

版本規範 描述
ChangesetVersionSpec 指定基於變更集編號版本。
DateVersionSpec 指定基於日期/時間戳記的版本。
LabelVersionSpec 指定一個標籤所基於的版本。
LatestVersionSpec 表示存儲庫中的最新有效版本。
WorkspaceVersionSpec 指定工作區名稱/擁有者所基於的版本。

回到前面的示例創建 GetRequest,VersionSpec.Latest 列為我版本規範。 VersionSpec.Latest 是只需對 LatestVersionSpec 只是為方便提供單一實例的引用。 若要檢索基於一個特定的標籤代碼,例如,創建 LabelVersionSpec 的實例:

var fileRequest = new GetRequest(
  new ItemSpec("$/Demo/TFS_VC_API", RecursionType.Full),
  new LabelVersionSpec("MyLabel"));

簽出代碼

您已經知道了如何識別和從版本控制伺服器中檢索特定項,讓我們看看如何可以簽出原始程式碼。 在 TFS 術語中,要簽出項目是掛起的編輯在該專案上。 到掛起一個特定的工作區中的項的編輯,您調用 Workspace.PendEdit 方法。 PendEdit 方法具有九個重載,所有這些都需要一個路徑,以及幾個其他可選參數的陣列。 可選參數之一是 RecursionType,其中規範工程完全如前文所述。

例如,要簽出的所有 C# (.cs) 檔,使此調用:

// This example assumes we have obtained a reference
// to an existing workspace by following the previous examples
var results = workspace.PendEdit("$/Demo/TFS_VC_API/*.cs", 
  RecursionType.Full);

在此示例中,我要求 TFS 掛起編輯所有 C# 檔 (通過 *.cs 萬用字元) 下方的伺服器資料夾"$ / 演示/TFS_VC_API"。因為我指定 RecursionType 為充分,我就會簽出指定的路徑下的所有資料夾中的 C# 檔。 在此示例中使用的特定方法簽名將還簽出檔下載到的本地路徑作為由指定的工作區映射。 您可以使用此方法接受一個參數的類型 PendChangesOptions 參數的重載版本之一,並指定 PendChangesOption.Silent 壓制時的掛起編輯的檔的下載。 在結果中返回的值包含下載由於對 PendEdit 的調用的項的計數。

編輯不會你可以在版本控制系統內的掛起的唯一行動。 也有掛起的方法:

  • 添加通過 PendAdd
  • 通過 PendBranch 的分支機搆
  • 通過 PendDelete 刪除
  • 通過 PendPropertyName 屬性
  • PendRename 通過重命名
  • 通過 PendUndelete 的撤銷刪除

例如,以下代碼等待一個新的分支,命名為 Dev,從主要的資料夾:

// This example assumes we have obtained a reference
// to an existing workspace by following the previous examples
var results = workspace.PendBranch("$/Demo/TFS_VC_API/Main",  
   "$/Demo/TFS_VC_API/Dev", VersionSpec.Latest);

我們將介紹分支和合併在以後的文章中詳細使用的 Api。

簽入變更

一旦向一個或多個簽出的檔進行了更改,您可以檢查他們回通過 Workspace.CheckIn 方法。 您呼叫的簽入方法之前,然而,您必須首先獲取暫止的變更的工作區的清單通過調用 Workspace.GetPendingChanges。 如果您不指定任何參數的 GetPendingChanges 方法,你再回來所有暫止的變更工作區。 否則,您可以使用的其他 11 重載之一和篩選器暫止的變更到 TFS 調用所返回的清單。

下面的示例將檢查在工作區中所有暫止的變更:

// This example assumes we have obtained a reference
// to an existing workspace by following the previous examples
var pendingChanges = workspace.GetPendingChanges();
var results = workspace.CheckIn(pendingChanges, "My check in.");

代碼的第一行,在工作區得到所有暫止的變更的清單。 在第二行中,檢查一切回到指定注釋與變更集相關聯的版本控制伺服器中。 在結果中返回的值包含簽入的項的計數。 如果有一個或多個暫止的變更,並且結果回來為零,然後在伺服器和用戶端之間的掛起項中發現沒有差異。

掛起的編輯不是唯一的更改簽入到版本控制系統中。 您還檢查:

  • 增補
  • 分支機搆
  • 撤銷刪除/刪除
  • 內容
  • 重命名

您還可以撤銷暫止的變更通過調用工作­空間。撤銷方法。 使用簽入方法,您還必須指定的暫止的變更要撤銷。 下面的示例將撤銷所有暫止的變更的工作區:

var pendingChanges = workspace.GetPendingChanges();
var results = workspace.Undo(pendingChanges);

檢索歷史

在Team 總管內的共同任務查看一個或多個檔或資料夾的歷史記錄。 您可能會發現需要以程式設計方式也這樣做。 正如你所料想的但有一個 API 用於查詢歷史記錄。 事實上,我要討論的方法是從 VersionControlServer 實例 (為代表的在前面的示例中的變數 vcs) 可用。 該方法是 VersionControlServer.QueryHistory,並且它有八個重載。 此方法提供了許多不同的方式,根據的類型和值傳遞給方法調用的參數查詢版本控制伺服器的功能。

圖 5 顯示 Form1.cs 檔的歷史記錄視圖可能是什麼樣子在常設專家委員會內。

History for Form1.cs
圖 5 Form1.cs 的歷史記錄

您可以複製此功能以程式設計方式使用中所示的代碼圖 6

圖 6 檢索項歷史記錄

 

var vcs = _tpc.GetService<VersionControlServer>();
var results = vcs.QueryHistory(
"$/Demo/TFS_VC_API/Form1.cs", // The item (file) to query history for
VersionSpec.Latest,           // We want to query the latest version
0,                            // We're not interested in the Deletion ID
RecursionType.Full,           // Recurse all folders
null,                         // Specify null to query for all users
new ChangesetVersionSpec(1),  // Starting version is the 1st changeset        
                              // in TFS
VersionSpec.Latest,           // Ending version is the latest version
                              // in TFS
int.MaxValue,                 // Maximum number of entries to return
true,                         // Include changes
false);                     // Slot mode
if (results != null)
{
  foreach (var changeset in (IEnumerable<Changeset>)results)
  {
    if (changeset.Changes.Length > 0)
    {
      foreach (var change in changeset.Changes)
      {
        ResultsTextBox.Text +=
          string.Format("  {0}\t{1}\t{2}\t{3}\t{4}\t{5}\r\n",
          change.Item.ChangesetId,
          change.ChangeType,
          changeset.CommitterDisplayName,
          change.Item.CheckinDate,
          change.Item.ServerItem,
          changeset.Comment);
      }
    }
  }
}

在 13 號線上特別注意參數圖 6。 我指定參數 includeChanges 為 true 值。 如果你指定了 false,然後具體變化的版本歷程記錄不會包含在返回的結果和圖 6 示例不會顯示詳細資訊。 您仍可以顯示基本變更集歷史記錄而無需返回更改,但有些細節將不可用。

運行圖 6 示例生成中所示的結果圖 7

History from API
圖 7 歷史從 API

還有很多其他的調用 QueryHistory API 的變化。 思考如何為您可以使用此方法,只是玩弄在 SCE 中的歷史記錄功能。 您也可以查詢更多歷史。 例如,有其他與查詢相關的方法,如由 VersionControlServer 提供:

  • QueryBranchObjectOwnership
  • QueryBranchObjects
  • QueryLabels
  • QueryMergeRelationships
  • QueryMerges
  • QueryMergesExtended
  • QueryMergesWithDetails
  • QueryPendingSets
  • QueryRootBranchObjects
  • QueryShelvedChanges
  • QueryShelvesets
  • QueryWorkspaces

有很多的資訊可從版本控制伺服器,和各種查詢方法為您提供一個視窗到該資訊。

下一個步驟

別動隊只已開始觸摸上由 TFS 物件模型公開的版本控制功能。 在本文中所涵蓋的功能可以有用且功能強大,但無數的功能公開的 TFS 版本控制伺服器,我們還沒有涉及。 這些功能的一些示例包括分支和合併,擱置集、 標籤和版本控制事件。 這個系列的文章中,我們希望公開許多這些 Api,並為您提供您需要更好地利用了 TFS 物件模型的知識。 更多敬請。

Jeff Bramwell 是美國農場信貸服務的企業體系結構的主任。他擁有超過 20 年的軟體發展經驗,並始終致力於遵循最推崇的開始簡單的和你的工作方式從那裡。在他的博客是 devmatter.blogspot.com。您可以按照他在 Twitter 上 twitter.com/jbramwell

感謝以下技術專家對本文的審閱:布賴恩 · 布萊克曼、 邁克 Fourie 和威利-彼得 · 肖布